发布于 

攻防世界Mobile - 人民的名义-抓捕赵德汉1-200、ill-intentions

第五题(人民的名义-抓捕赵德汉1-200)

题目安全大赛题目,但是难度系数不高,开搞

下载下来是一个jar包169e139f152e45d5ae634223fe53e6be.jar
使用 jadx-gui或者jd-gui确定java层代码,确定之后的代码逻辑

这题是Jar包的形式,不要使用Jar2Dex工具,会丢失部分数据,找到入口函数,中间有一个读入对比判断,跟入判断,这个判断函数将输入的数据做MD5计算,将这个MD5字符串拿去解密,最后验证一下检查当前密码确定MD5信息,字节数组转换为16进制

使用解密工具解密

最后得到结果 flag{monkey99}

第六题(ill-intentions)

得到了一个APK文件,有以下消息:

Do you have have ill intentions?

用jadx反编译了应用程序,看到如果我们可以选择应用程序活动并接收应用程序发送的广播消息,我们将得到解决方案。我没有为第一个挑战安装Android IDE,只有一个旧的Android SDK和apktool。

为了能够启动活动,我将它们设置为导出并使用活动Launcer。注意:我还更改了MainActivity,因为它什么也不做。

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.hellojni" platformBuildVersionCode="22" platformBuildVersionName="5.1.1-1819727">
    <permission android:description="@string/android.permission._msg" android:name="ctf.permission._MSG" android:protectionLevel="signature"/>
    <permission android:description="@string/android.permission._msg" android:name="ctf.permission._SEND"/>
    <application android:icon="@mipmap/ic_launcher" android:label="CTF Application">
        <activity android:label="Main Activity" android:name="com.example.application.MainActivity" android:exported="true">
       </activity>
        <activity android:label="Activity: Is This The Real One" android:name="com.example.application.IsThisTheRealOne">
  <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <activity android:label="This Is The Real One" android:name="com.example.application.ThisIsTheRealOne" android:exported="true" />
        <activity android:label="Definitely Not This One" android:name="com.example.application.DefinitelyNotThisOne" android:exported="true" />
        <receiver android:exported="true" android:name="com.example.application.Send_to_Activity"/>
    </application>
</manifest>

打开查看MainActivity,仅仅注册了一个广播接收者

而这个广播接收者也没什么代码,仅仅是接受到不同的信息跳转到不同的Acitivity

三个Activity各有一个native函数



三个类逻辑差不多相同,只是调用的native方法不同,关系如下

DefinitelyNotThisOne:definitelyNotThis
sThisTheRealOne:perhapsThis
ThisIsTheRealOne:orThat

安装apk打开,只有MainAcitvity一个TextView,没有什么其他的东西,AndroidManifest.xml中,三个类均是未导出的状态

由于没有让用户输入,所以flag应该是某个阶段生成的,关键应该就在那三个native函数上,且根据名字只有一个是真的。

于是可以在java层hook intent.putExtra()方法来获得结果 和三个native方法得到参数
为了练习一下native hook,我hook了native层

function main() {
    function getjstring(jstr) {
        return Java.vm.getEnv().getStringUtfChars(jstr, null).readCString();
    }
    Java.perform(function () {
        var so_addr = Module.findBaseAddress("libhello-jni.so");
        var perhapsThis_addr = Module.findExportByName("libhello-jni.so", "Java_com_example_application_IsThisTheRealOne_perhapsThis");
        console.log("perhapsThis_addr", perhapsThis_addr);
        Interceptor.attach(perhapsThis_addr, {
            onEnter: function (args) {
                console.log("perhapsThis_args:[1]", getjstring(args[2]), "\n    [2]", getjstring(args[3]), "\n    [3]", getjstring(args[4]), "\n");
            },
            onLeave: function (retval) {
                console.log("perhapsThis_result:", getjstring(retval));
            },
        });

        Interceptor.attach(Module.findExportByName("libhello-jni.so", "Java_com_example_application_ThisIsTheRealOne_orThat"), {
            onEnter: function (args) {
                console.log("orThat_args:[1]", getjstring(args[2]), "\n    [2]", getjstring(args[3]), "\n    [3]", getjstring(args[4]), "\n");
            },
            onLeave: function (retval) {
                console.log("orThat_result:", getjstring(retval));
            },
        });

        Interceptor.attach(Module.findExportByName("libhello-jni.so", "Java_com_example_application_DefinitelyNotThisOne_definitelyNotThis"), {
            onEnter: function (args) {
                console.log("definitelyNotThis_args:[1]", getjstring(args[2]), "\n    [2]", getjstring(args[3]), "\n");
            },
            onLeave: function (retval) {
                console.log("definitelyNotThis_result:", getjstring(retval));
            },
        });
    });
}
setImmediate(main);

由于我没有修改apk文件,所以比较麻烦。需要开两个终端,先用objection android intent跳转到相应的activity,然后frida附加进程,在点击相应按钮获得hook输出。
或者采用重打包apk,给activity添加exported属性然后使用am命令来跳转到相应的Activity,修改入口也可以。

最终我们得到输出

orThat_args:[1] IIjsWa}iyYSmks
[2] ODBkNTNhZjRmMGZmMWYtMzhhMDIzMmMwYjcwNzlhMTUwMDczOWNlYjhjMhUWYWYeMzYiZDFkMTY?
[3] MhMhMGJhMTUhOGYWZThlZDQaYWJkYzkWZTktMTQhMjYhOTgiOTZkODgaNWRkZmFiZTciOGNlNDI?
orThat_result: KeepTryingThisIsNotTheActivityYouAreLookingForButHereHaveSomeInternetPoints!

perhapsThis_args:[1] TRytfrgooq|F{i-JovFBungFk\VlphgQbwvjHuDgaeTzuSt.@Lex^
[2] ZGFkNGIwYzIWYjEzMTUWNjVjNTVlNjZhOGJkNhYtODIyOGEaMTMWNmQaOTVjZjkhMzRjYmUzZGE?
[3] MzQxZTZmZjAxMmIiMWUzNjUxMmRiYjIxNDUwYTUxMWItZGQzNWUtMzkyOWYyMmQeYjZmMzEaNDQ?
perhapsThis_result: Congratulation!YouFoundTheRightActivityHereYouGo-CTF{IDontHaveABadjokeSorry}

definitelyNotThis_args:[1] YjYwYWZjMjRkMhVhZTQhZDIwZGFkNWJhMGZmZGYiYmQaMmFkMjBiMTEhNDAtMzMzMjdlZmEWNzU?
[2] MzYwNjMeNjgxNWZkNGQeOTFhOTIhNDkiMDVhNDBkYTAyNWQtYhYxNWYwOTUxMzZiMTlmMzciMjM?
definitelyNotThis_result: Told you so!

得到最终的flag为CTF{IDontHaveABadjokeSorry}

另外一种方式:

没有编写接收广播的应用程序,而是修补smalli文件,添加如下代码的日志:

.method private static strlog(Ljava/lang/String;)V
    .registers 6

    const-string v0, "DefinitelyNotThisOne"

    invoke-static {v0, p0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I

    return-void
.end method


#to log, insert this

    invoke-static {v5}, Lcom/example/application/DefinitelyNotThisOne$1;->strlog(Ljava/lang/String;)V

我们在日志中找到了这个:

Congratulation!YouFoundTheRightActivityHereYouGo-CTF{IDontHaveABadjokeSorry}