Frida入门练习(二) - KGB Message

题目附件:tlamb96/kgb_messenger: An Android CTF practice challenge (github.com)


MainActivity

这里我们需要跟踪一下R.string.User,直接点击,可以知道对应的资源id为:

1
public static final int User = 0x7f0d0000;

根据这个资源id在resources.arsc中可以搜索到对应的string标签名称为”User”:

1
<public type="string" name="User" id="0x7f0d0000" />

根据标签名称直接搜索资源文件(xml文件):

解码Base64就得到了第一个flag:FLAG{57ERL1NG_4RCH3R}。

要想进入下一关,我们就需要hook系统方法System.getProperty()System.getenv(),使其直接返回正确的字符串,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function MainActivity(){

Java.perform(
function(){
var SystemClass = Java.use("java.lang.System");
SystemClass.getProperty.overload("java.lang.String").implementation = function(key){
var tmp = this.getProperty(key);
return "Russia";
}
SystemClass.getenv.overload("java.lang.String").implementation = function(name){
var tmp = this.getenv(name);
return "RkxBR3s1N0VSTDFOR180UkNIM1J9Cg==";
}
}
)

}

setImmediate(MainActivity)

LoginActivity

是一个登录界面,所对应的代码逻辑如下:

如果我们只是简单的进入下一关,当然可以直接hook j()方法,使其直接返回true。但是我们还需要得到flag,flag的生成需要依靠账号和密码(详细见i()方法)。

其中 j()、i()如下:

所以说我们不应hook j()方法使其返回true,而是要逆md5码获取密码明文,推荐网站md5 hash decoder and calculator (md5hashing.net)

得到密码明文为:guest。

为了更为方便点,我们还可以hook Toast.makeText()方法,在控制台输出flag,毕竟toast弹窗显示时间比较短而且还不能复制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function LoginActivity(){

Java.perform(
function(){
var ToastClass = Java.use("android.widget.Toast");
ToastClass.makeText.overload("android.content.Context", "java.lang.CharSequence", "int").implementation = function(context, text, duration){
console.log("flag = " + text);
return this.makeText(context,text,duration);
}
}
)

}

setImmediate(LoginActivity)

得到第二个flag:FLAG{G00G13_PR0}

MessengerActivity

是一个聊天界面。发送消息的代码逻辑如下:

来看a()b()这两个方法:

就是两个简单的加密方法,要说有点挑战的也就是移位异或了,不过这个拿个例子在草稿上推演一遍就知道怎么做了。

解密脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
p = list("V@]EAASB\u0012WZF\u0012e,a$7(&am2(3.\u0003")

for i in range(len(p) // 2):
c = chr(ord(p[-1-i]) ^ ord('A'))
p[-1 - i] = chr(ord(p[i]) ^ ord('2'))
p[i] = c
print(''.join(_ for _ in p))


r = list("\u0000dslp}oQ\u0000 dks$|M\u0000h +AYQg\u0000P*!M$gQ\u0000")
for i in range(len(r) // 2):
r[i], r[-1-i] = r[-1-i], r[i]
for i in range(len(r)):
shiftBit = i % 8
if shiftBit == 0:# >> 0 的还原不了
continue
# 重复循环就可以得到原来的
while shiftBit < 8:
r[i] = chr((ord(r[i]) >> shiftBit) ^ ord(r[i]))
shiftBit *= 2
print(''.join(_ for _ in r))

得到的明文如下图所示:

由于存在移位为0bit的情况,这种情况最后是相同明文进行异或得到0,是无法还原出来的,所以需要我们自己手动还原。

最终flag如下图所示:


Frida入门练习(二) - KGB Message
http://example.com/2023/12/21/Android安全/Frida入门练习(二) - KGB Messager/
作者
gla2xy
发布于
2023年12月21日
许可协议