BUGKU逆向reverse 1-8题
练习IDA两年半
打开尘封已久的bugku,从题目中练习使用,现在都已经是新版本了 orz
入门逆向
运行baby.exe
将解压后的baby.exe拖到IDA里面
主函数中找到mov指令 可以看到这里就是flag
flag{Re_1s_S0_C0OL}
signin
下载附件
解压之后是sign_in.apk ,Android逆向我不会啊orz
丢到AndroidKiller 里面去
可以看到这里有一个checkpassword方法
不过我不知道怎么把这个直接跳过 估计是需要登录的时候直接绕过这个方法然后重打包
看到评论里面有的人用的是GDK https://github.com/charles2gan/GDA-android-reversing-Tool
GDA,一款用C++实现的强大的Dalvik字节码反编译器,具有分析速度快、内存磁盘消耗低等优点,对apk、dex、odex、oat、jar、class、aar文件的反编译能力更强。
GDK打开之后 牛逼啊
登录验证逻辑如下
private String getFlag(){
return this.getBaseContext().getString(0x7f0b0020);
}
private void showMsgToast(String p0){
Toast.makeText(this, p0, 1).show();
}
public void checkPassword(String p0){
if (p0.equals(new String(Base64.decode(this.getFlag().reverse(), 0)))) {
this.showMsgToast("Congratulations !");
}else {
this.showMsgToast("Try again.");
}
return;
}
接下来去找这个0x7f0b0020对应的值是多少
转换成十进制为
去找2131427360 这玩意,不过我直接搜索这个值找不到
手动查toString 看到在这里
所以这个值对应的是toString
GDK用起来卡卡的
toString 的值为 991YiZWOz81ZhFjZfJXdwk3X1k2XzIXZIt3ZhxmZ
按照规则 把字符串逆序 ZmxhZ3tIZXIzX2k1X3kwdXJfZjFhZ18zOWZiY199
然后base64解密,得到flag
flag{Her3_i5_y0ur_f1ag_39fbc_}
Easy_Re
额要是我知道我还运行干啥
我理解这里应该是会有一个比较操作 逆向的时候在比较操作的时候看flag值
IDA打开之后F5查看伪代码
输入的内容存储到v7变量中 然后跟v5进行对比,对比结果存储到v3中
scanf("%s", v7);
v3 = strcmp(v5.m128i_i8, v7);
所以真实的flag就在v5中,赋值操作在
v5 = _mm_loadu_si128((const __m128i *)&xmmword_413E34);
真实值在 xmmword_413E34,点击跟进
按 a 转译
获取flag
游戏过关
运行exe,看起来这个游戏好难
n是灯的序列号,m是灯的状态
如果第N个灯的m为1,则它点亮,否则它熄灭
起初所有的灯都关上了
现在你可以输入n来改变它的状态
但你应该注意一件事,如果你改变第N个灯的状态,第(N-1)个和第(N+1)个的状态也会改变
当所有灯亮起时,flag将出现
现在,输入n
乱输一通
获得flag zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
丢到IDA里面检查一下,这次的文件比较多 搜索flag字符串 alt+t
看到输出flag的界面
汇编代码如下
F5转换为C代码,去除掉一些干扰代码
int sub_45E940()
{
int i; // [esp+D0h] [ebp-94h]
char v2[22]; // [esp+DCh] [ebp-88h] BYREF
char v3[32]; // [esp+F2h] [ebp-72h] BYREF
char v4[4]; // [esp+112h] [ebp-52h] BYREF
char v5[64]; // [esp+120h] [ebp-44h]
sub_45A7BE("done!!! the flag is ");
v5[0] = 18;
v5[1] = 64;
v5[2] = 98;
v5[3] = 5;
v5[4] = 2;
v5[5] = 4;
v5[6] = 6;
v5[7] = 3;
v5[8] = 6;
v5[9] = 48;
v5[10] = 49;
v5[11] = 65;
v5[12] = 32;
v5[13] = 12;
v5[14] = 48;
v5[15] = 65;
v5[16] = 31;
v5[17] = 78;
v5[18] = 62;
v5[19] = 32;
v5[20] = 49;
v5[21] = 32;
v5[22] = 1;
v5[23] = 57;
v5[24] = 96;
v5[25] = 3;
v5[26] = 21;
v5[27] = 9;
v5[28] = 4;
v5[29] = 62;
v5[30] = 3;
v5[31] = 5;
v5[32] = 4;
v5[33] = 1;
v5[34] = 2;
v5[35] = 3;
v5[36] = 44;
v5[37] = 65;
v5[38] = 78;
v5[39] = 32;
v5[40] = 16;
v5[41] = 97;
v5[42] = 54;
v5[43] = 16;
v5[44] = 44;
v5[45] = 52;
v5[46] = 32;
v5[47] = 64;
v5[48] = 89;
v5[49] = 45;
v5[50] = 32;
v5[51] = 65;
v5[52] = 15;
v5[53] = 34;
v5[54] = 18;
v5[55] = 16;
v5[56] = 0;
qmemcpy(v2, "{ ", 2);
v2[2] = 18;
v2[3] = 98;
v2[4] = 119;
v2[5] = 108;
v2[6] = 65;
v2[7] = 41;
v2[8] = 124;
v2[9] = 80;
v2[10] = 125;
v2[11] = 38;
v2[12] = 124;
v2[13] = 111;
v2[14] = 74;
v2[15] = 49;
v2[16] = 83;
v2[17] = 108;
v2[18] = 94;
v2[19] = 108;
v2[20] = 84;
v2[21] = 6;
for ( i = 0; i < 56; ++i )
{
v2[i] ^= v5[i];
v2[i] ^= 0x13u;
}
return sub_45A7BE("%s\n");
}
这里有个问题啊,就是v2和v5的长度不一致
v2的长度就是22,这样的话最后得到的结果是
少了一部分的flag,但是v3和v4的长度加起来是 32+2=34,再加上前面的22就是56,所以我们应该把v2 v3 v4组在一起 为啥这里看不出来 我感觉这里的C语言代码是有点问题
更新python脚本
v2=[123,32,18,98,119,108,65,41,124,80,125,38,124,111,74,49,83,108,94,108,84,6,96,83,44,121,104,110,32,95,117,101,99,123,127,119,96,48,107,71,92,29,81,107,90,85,64,12,43,76,86,13,114,1,117,126,0]
v5=[18,64,98,5,2,4,6,3,6,48,49,65,32,12,48,65,31,78,62,32,49,32,1,57,96,3,21,9,4,62,3,5,4,1,2,3,44,65,78,32,16,97,54,16,44,52,32,64,89,45,32,65,15,34,18,16,0]
flag=""
for i in range(len(v2)):
flag+=chr(v2[i]^v5[i]^0x13)
print(flag)
结果如下
换一个方式 使用动态调试 也就是掏出OllyDbg
使用中文搜索引擎
选择智能搜索 然后就可以看到
双击进入
这部分的入栈位置在这里
上转至 006A7AB4
上转调用位置为 006AF66C
这里的几个汇编指令我觉得需要解释一下
可以看到每一个jnz前面都有cmp,也就是比较失败就跳转到 006AF671
如果所有的比较都成功则调用call 方法,调用006A7AB4地址的方法
这里的逻辑很显然就是这里判断灯亮灯灭的判断(IDA中看见
所以我们将这里的jmp地址修改为call地址 不管输入 1-8 的哪个数字都能拿到flag了
右键复制到可执行文件 选择
保存为 ConsoleApplication7.exe,然后运行一下,输入 1,获取flag
Easy_vb
运行之后随便点点 好像没啥用
OD打开智能搜索
树林的小秘密
下载之后我的OD载入不了64位的程序 只能IDA了
shift + F12 搜索flag
看起来是pyinstaller打包的
用对应的工具去恢复源码,工具在这,点进去就是下载
https://nchc.dl.sourceforge.net/project/pyinstallerextractor/dist/pyinstxtractor.py
把工具和待反编译的exe放到一个目录下,然后运行
python pyinstxtractor.py easy_reverse.exe
生成了 easy_reverse.exe_extracted 文件,可以看到反编译的结果为
这里这个没有后缀的就是之前打包的python文件对应的pyc文件
这个时候打开123已经可以拿到flag了,base64解密
Timer(阿里CTF)
又是一个APK
GDA打开 搜索flag
跳转查看,如下
JNI编程?这么上流
这个位置load 了 so文件
所以其实flag在这个里面
但是so文件逆向我更不会了,只能看代码逻辑
初始化onCreate方法
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
Handler handler = new Handler();
Runnable runnable = new MainActivity$1(this, this.findViewById(0x7f0c0051), this.findViewById(0x7f0c0050), handler);
handler.postDelayed(runnable, 0);
}
运行了这个方法
public void run(){
MainActivity$1 tthis$0;
this.this$0.t = System.currentTimeMillis();
this.this$0.now = (int)(this.this$0.t / 1000);
this.this$0.t = 1500 - (this.this$0.t % 1000);
this.val$tv2.setText("AliCTF");
if (((this.this$0.beg - this.this$0.now)) <= 0) {
this.val$tv1.setText("The flag is:");
this.val$tv2.setText("alictf{"+this.this$0.stringFromJNI2(this.this$0.k)+"}");
}
if (MainActivity.is2((this.this$0.beg - this.this$0.now))) {
tthis$0 = this.this$0;
tthis$0.k = tthis$0.k + 100;
}else {
tthis$0 = this.this$0;
tthis$0.k = tthis$0.k - 1;
}
this.val$tv1.setText("Time Remaining\(s\):"+(this.this$0.beg - this.this$0.now));
this.val$handler.postDelayed(this, this.this$0.t);
return;
}
OK 虽然看起来有点费劲
现在有四个参数
- t
- now
- beg
- k
now是当前时间戳
beg是启动APK的时候的时间,在
当然加了20万秒 所以如果破解不了的话就等着吧,虽然CTF比赛很快就要结束力
t 是一个取余时间值
k是计算的时间种子,最后会传到JNI方法里面去,所以我们如果直接改if语句是没用的,因为时间种子没有修改正确
所以这里我们有两个地方需要修改,一个是计算出正确的时间种子,一个是进入if语句,先从简单的进入if语句开始
把beg改成0就OK
不过好像GDK没有这个修改重打包的功能,使用AndroidKiller
把if-gtz修改为 if-lez,从判断大于零改为判断小于或等于零
接下来需要计算正确的K,抽离其中的关键因素
使用GDA反编译之后的代码看起来费劲,换成jd-gui
先使用dex2jar 把 classes.dex转换成 jd-gui可识别的jar包
然后使用jd-gui打开jar包,现在看起来就好多了
编写python脚本如下
now=0
beg=0+200000
k=0
def is2(n):
if n<=3:
if n > 1:
return True
return False
elif n%2==0 or n%3==0:
return False
else:
i=5
while i*i <= n:
if 0 == n%i or n%(i+2) == 0:
return False
i=i+6
return True
while beg - now > 0:
if is2(beg-now):
k+=100
else:
k-=1
beg -= 1
print(k)
运行得到K值
k值为 1616384
修改代码 在这里直接把K强行赋值
回编译得到修改后的APK
连一下自己手机
adb install之后运行 就可以看到flag了
拿到flag
逆向入门
运行admin.exe???16位的应用程序
IDA打开感觉奇奇怪怪的,介素?
看起来类似010editer里面的格式,丢到wxmedit里面
一眼照片,这是逆向?服了
字符串丢到浏览器上 浏览器自动解码
扫码获取flag
OK现在逆向的前八题就做完了 再接再厉
END
建了一个微信的安全交流群,欢迎添加我微信备注进群
,一起来聊天吹水哇,以及一个会发布安全相关内容的公众号,欢迎关注 😃
加我拉你入群 | 黑糖安全公众号 |
---|---|