吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5113|回复: 12
收起左侧

[Android CTF] 攻防世界题解1-easyjni

[复制链接]
丶诺熙 发表于 2020-1-11 00:02

easyjni

根据题目,可以猜测肯定需要分析so文件。
上来先通过JEB反编译一下安卓代码。首先需要看MainActivity,这个是程序的入口,可以看到这里对我们输入的内容做做了判断。

进而继续跟,可以看到这里进行了两次处理,首先传入a这个类中,处理过一次,然后传到ncheck。分析可以发现ncheck是我们so文件中的函数。而a这个类是java代码。

继续对a类反编译,并分析。

首先可以看到,这个应该是一个加密,看到上面存在密码表。根据其字符可以猜测为变种base64。提取出其密码表,尝试拿python重写一个。(网上有现成的)

然后和java代码执行结果相比对,可以发现猜测正确。
对123加密,结果如下:

此时java层代码分析完毕。接下来看so文件内代码。
直接解压apk,从lib目录中提取出so文件。拖入ida。根据我们的关键字ncheck。可以找到这个函数,进而F5,可以看到伪代码。

这里看着就迷很多了。在参考iyzyi师傅的wp后,以及询问apeng师傅后,逐渐理清了很多。

首先,我们可以猜测到v6为传入的字符串。

然后我们来看第一个循环,看一下第一次执行结果,可以看到。

 do
    {
      // 首先v8保存了s1字符串的起始位地址,即s1[0]
      v8 = &s1[v7];
      // 然后将v6的v7+16位赋值给s1的v7位,即s1[0]=v6[16]
      s1[v7] = v6[v7 + 16];
      // v9保存了v6[v7]的值,然后v7+1 (后++),即v9=v6[0],v7=1
      v9 = v6[v7++];
      // 将v9 赋值给 s1[起始位+16],即s1[0+16]=v6[0]
      v8[16] = v9;
    }
    while ( v7 != 16 );

可以看出,该逻辑是将前16位与后16位对调。
然后继续分析下一个循环。

 do
    {
      v12 = __OFSUB__(v10, 30);
      v11 = v10 - 30 < 0;

      // v16 = s1[0]
      v16 = s1[v10];

      // s1[0]=s1[1]
      s1[v10] = s1[v10 + 1];
      // s1[1] = v16
      s1[v10 + 1] = v16;
      v10 += 2;
    }
 while ( v11 ^ v12 );

分析代码,可以发现,是两位两位,进行位置对调。

然后进而分析循环结束条件:
查阅资料。__OFSUB__ 表示x-y是否溢出,溢出返回1,没有溢出返回0。在此情况下,应该不存在溢出,则返回均为0,即v12=0,当v10>30时,v11=0。此时异或得0,循环结束。

此时已经将整个程序分析完毕,接下来写poc解题。

base64_charset = "i5jLW7S0GX6uf1cv3ny4q8es2Q+bdkYgKOIT/tAxUrFlVPzhmow9BHCMDpEaJRZN"

# 百度嫖的base64解码
def decode(base64_str):
    base64_bytes = ['{:0>6}'.format(str(bin(base64_charset.index(s))).replace('0b', '')) for s in base64_str if
                    s != '=']
    resp = bytearray()
    nums = len(base64_bytes) // 4
    remain = len(base64_bytes) % 4
    integral_part = base64_bytes[0:4 * nums]

    while integral_part:
        tmp_unit = ''.join(integral_part[0:4])
        tmp_unit = [int(tmp_unit[x: x + 8], 2) for x in [0, 8, 16]]
        for i in tmp_unit:
            resp.append(i)
        integral_part = integral_part[4:]

    if remain:
        remain_part = ''.join(base64_bytes[nums * 4:])
        tmp_unit = [int(remain_part[i * 8:(i + 1) * 8], 2) for i in range(remain - 1)]
        for i in tmp_unit:
            resp.append(i)

    return resp

# MbT3sQgX039i3g==AQOoMQFPskB1Bsc7
flag_enc = "AQOoMQFPskB1Bsc7MbT3sQgX039i3g=="
tmp=""
for i in range(len(flag_enc)//2):
    tmp += flag_enc[i*2+1] + flag_enc[i*2]
print(tmp)
print(decode(tmp))

免费评分

参与人数 7威望 +2 吾爱币 +18 热心值 +7 收起 理由
troyli + 1 + 1 谢谢@Thanks!
qtfreet00 + 2 + 12 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
dreamlivemeng + 1 + 1 谢谢@Thanks!
三木零 + 1 + 1 热心回复!
monsterbaby521 + 1 + 1 热心回复!
Deuez + 1 + 1 我很赞同!
ArnoD + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 丶诺熙 发表于 2020-1-11 11:55

攻防世界的练习题、
https://adworld.xctf.org.cn/
 楼主| 丶诺熙 发表于 2020-1-11 00:04
附件地址:https://adworld.xctf.org.cn/media/task/attachments/633a06ba88a142bc9527e9b00bbb55ce.apk
judgecx 发表于 2020-1-11 03:20
zhngypng 发表于 2020-1-11 08:45
好奇点进来,一脸懵走出去。没看懂
frankB4 发表于 2020-1-11 09:18
虽然看不懂但还是感谢分享
昨夜星辰恰似你 发表于 2020-1-11 09:46
本帖最后由 昨夜星辰恰似你 于 2020-1-11 09:48 编辑

这是哪个哪个ctf呢
人小鬼大666 发表于 2020-1-11 16:58
一脸的懵逼。
冰封天堂 发表于 2020-1-11 21:55
这这这,上来就是这种难度的吗,完全懵逼状态
拖地僧 发表于 2020-1-12 16:13
虽然看不懂,但是还是想看!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 19:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表