总的来说这次的re都还好。这里分享一下。
easyZ
一个不太常见架构S/390的程序,ida后发现不能反汇编,报错。。
然后在linux下使用qemu来模拟了程序的运行,确定关键字符串:Please input your string:
在所给的hex.txt搜索该字符串定位关键字符串的地址,再到dis.txt文件中搜索该地址定位到关键汇编指令地址处。其实可以接着利用qemu开一个gdb端口进行调试分析,其他架构的程序也可如此。这里我我直接结合z Architecture汇编手册来手撸汇编代码。
最后整理关键加密函数。
1000910: eb bf f0 58 00 24 stmg %r11,%r15,88(%r15) //第一个关键函数
1000916: e3 f0 ff 50 ff 71 lay %r15,-176(%r15) //lea
100091c: b9 04 00 bf lgr %r11,%r15
1000920: e3 20 b0 a0 00 24 stg %r2,160(%r11) //r2 = r11+160 input
1000926: e3 20 b0 a0 00 04 lg %r2,160(%r11)
100092c: c0 e5 ff ff ff 02 brasl %r14,0x1000730
1000932: b9 04 00 12 lgr %r1,%r2 //mov
1000936: a7 1f 00 20 cghi %r1,32 //cmp len(input), 32
100093a: a7 84 00 06 je 0x1000946
100093e: a7 18 00 00 lhi %r1,0
1000942: a7 f4 00 56 j 0x10009ee
1000946: e5 4c b0 ac 00 00 mvhi 172(%r11),0
100094c: a7 f4 00 49 j 0x10009de
1000950: e3 10 b0 ac 00 14 lgf %r1,172(%r11)
1000956: e3 10 b0 a0 00 08 ag %r1,160(%r11)
100095c: 43 10 10 00 ic %r1,0(%r1)
1000960: b9 94 00 11 llcr %r1,%r1
1000964: c2 1f 00 00 00 2f clfi %r1,47
100096a: a7 c4 00 11 jle 0x100098c
100096e: e3 10 b0 ac 00 14 lgf %r1,172(%r11)
1000974: e3 10 b0 a0 00 08 ag %r1,160(%r11)
100097a: 43 10 10 00 ic %r1,0(%r1)
100097e: b9 94 00 11 llcr %r1,%r1
1000982: c2 1f 00 00 00 39 clfi %r1,57
1000988: a7 c4 00 24 jle 0x10009d0
100098c: e3 10 b0 ac 00 14 lgf %r1,172(%r11)
1000992: e3 10 b0 a0 00 08 ag %r1,160(%r11)
1000998: 43 10 10 00 ic %r1,0(%r1)
100099c: b9 94 00 11 llcr %r1,%r1
10009a0: c2 1f 00 00 00 60 clfi %r1,96
10009a6: a7 c4 00 11 jle 0x10009c8
10009aa: e3 10 b0 ac 00 14 lgf %r1,172(%r11)
10009b0: e3 10 b0 a0 00 08 ag %r1,160(%r11)
10009b6: 43 10 10 00 ic %r1,0(%r1)
10009ba: b9 94 00 11 llcr %r1,%r1
10009be: c2 1f 00 00 00 66 clfi %r1,102
10009c4: a7 c4 00 09 jle 0x10009d6
10009c8: a7 18 00 00 lhi %r1,0
10009cc: a7 f4 00 11 j 0x10009ee
10009d0: 18 00 lr %r0,%r0
10009d2: a7 f4 00 03 j 0x10009d8
10009d6: 18 00 lr %r0,%r0
10009d8: eb 01 b0 ac 00 6a asi 172(%r11),1
10009de: 58 10 b0 ac l %r1,172(%r11)
10009e2: a7 1e 00 1f chi %r1,31
10009e6: a7 c4 ff b5 jle 0x1000950
10009ea: a7 18 00 01 lhi %r1,1
10009ee: b9 14 00 11 lgfr %r1,%r1
10009f2: b9 04 00 21 lgr %r2,%r1
10009f6: e3 40 b1 20 00 04 lg %r4,288(%r11)
10009fc: eb bf b1 08 00 04 lmg %r11,%r15,264(%r11)
1000a02: 07 f4 br %r4
1000a04: 07 07 nopr %r7
1000a06: 07 07 nopr %r7
1000a08: b3 c1 00 2b ldgr %f2,%r11 //加密判断函数
1000a0c: b3 c1 00 0f ldgr %f0,%r15
1000a10: e3 f0 ff 48 ff 71 lay %r15,-184(%r15)
1000a16: b9 04 00 bf lgr %r11,%r15
1000a1a: e3 20 b0 a0 00 24 stg %r2,160(%r11) //input
1000a20: e5 4c b0 a8 00 00 mvhi 168(%r11),0 //mov 立即数
1000a26: a7 f4 00 4b j 0x1000abc
1000a2a: e3 10 b0 a8 00 14 lgf %r1,168(%r11) //循环
1000a30: e3 10 b0 a0 00 08 ag %r1,160(%r11) //r1 = input[i]
1000a36: 43 10 10 00 ic %r1,0(%r1)
1000a3a: b9 94 00 11 llcr %r1,%r1
1000a3e: 50 10 b0 b4 st %r1,180(%r11) //r11[180] = r1
1000a42: 58 30 b0 b4 l %r3,180(%r11) //r3 = r1
1000a46: 71 30 b0 b4 ms %r3,180(%r11) //r3*r3
1000a4a: c0 10 00 04 d3 ef larl %r1,0x109b228 //
1000a50: e3 20 b0 a8 00 14 lgf %r2,168(%r11) //i
1000a56: eb 22 00 02 00 0d sllg %r2,%r2,2 // << 2 (*4)
1000a5c: 58 12 10 00 l %r1,0(%r2,%r1) // 0x109b228[i<<2]
1000a60: b2 52 00 31 msr %r3,%r1 //input[i]*input[i]*0x109b228[i<<2]
1000a64: c0 10 00 04 d3 e2 larl %r1,0x109b228
1000a6a: e3 20 b0 a8 00 14 lgf %r2,168(%r11) //i
1000a70: a7 2b 00 20 aghi %r2,32 //add + 32
1000a74: eb 22 00 02 00 0d sllg %r2,%r2,2 // << 2
1000a7a: 58 12 10 00 l %r1,0(%r2,%r1) //0x109b228[(i+32)<<2]
1000a7e: 71 10 b0 b4 ms %r1,180(%r11) //0x109b228[(i+32)<<2]*input[i]
1000a82: 1a 31 ar %r3,%r1 //input[i]*input[i]*0x109b228[i<<2] + 0x109b228[(i+32)<<2]*input[i]
1000a84: c0 10 00 04 d3 d2 larl %r1,0x109b228
1000a8a: e3 20 b0 a8 00 14 lgf %r2,168(%r11) //i
1000a90: a7 2b 00 40 aghi %r2,64 //i+64
1000a94: eb 22 00 02 00 0d sllg %r2,%r2,2 //(i+64) << 2
1000a9a: 58 12 10 00 l %r1,0(%r2,%r1) //r1 = 0x109b228[(i+64) << 2]
1000a9e: 1a 31 ar %r3,%r1 //add r3 + 0x109b228[(i+64) << 2]
1000aa0: c4 18 00 04 d3 68 lgrl %r1,0x109b170
1000aa6: e3 20 b0 a8 00 14 lgf %r2,168(%r11) //i
1000aac: eb 22 00 02 00 0d sllg %r2,%r2,2 // i << 2
1000ab2: 50 32 10 00 st %r3,0(%r2,%r1) r1[r2] = r3, 0x109dd08
1000ab6: eb 01 b0 a8 00 6a asi 168(%r11),1 //i++;
1000abc: 58 10 b0 a8 l %r1,168(%r11) //mov eax, i(168(%r11));
1000ac0: a7 1e 00 1f chi %r1,31
1000ac4: a7 c4 ff b3 jle 0x1000a2a //cmp
1000ac8: e5 4c b0 ac 00 01 mvhi 172(%r11),1 //j = 1
1000ace: e5 4c b0 b0 00 00 mvhi 176(%r11),0 //i = 0
1000ad4: a7 f4 00 21 j 0x1000b16
1000ad8: c4 18 00 04 d3 4c lgrl %r1,0x109b170 //判断循环 加密后的数据
1000ade: e3 20 b0 b0 00 14 lgf %r2,176(%r11) //i
1000ae4: eb 22 00 02 00 0d sllg %r2,%r2,2 //i << 2
1000aea: 58 32 10 00 l %r3,0(%r2,%r1) //enc[i<<2]
1000aee: c0 10 00 04 d3 5d larl %r1,0x109b1a8
1000af4: e3 20 b0 b0 00 14 lgf %r2,176(%r11) //i
1000afa: eb 22 00 02 00 0d sllg %r2,%r2,2 // i << 2
1000b00: 58 12 10 00 l %r1,0(%r2,%r1) //d[i<<2]
1000b04: 19 31 cr %r3,%r1
1000b06: a7 84 00 05 je 0x1000b10
1000b0a: e5 4c b0 ac 00 00 mvhi 172(%r11),0
1000b10: eb 01 b0 b0 00 6a asi 176(%r11),1 //add
1000b16: 58 10 b0 b0 l %r1,176(%r11) //i
1000b1a: a7 1e 00 1f chi %r1,31 //cmp
1000b1e: a7 c4 ff dd jle 0x1000ad8
1000b22: 58 10 b0 ac l %r1,172(%r11)
1000b26: b9 14 00 11 lgfr %r1,%r1
1000b2a: b9 04 00 21 lgr %r2,%r1
1000b2e: b3 cd 00 b2 lgdr %r11,%f2
1000b32: b3 cd 00 f0 lgdr %r15,%f0
1000b36: 07 fe br %r14
1000b38: eb bf f0 58 00 24 stmg %r11,%r15,88(%r15) //main函数
1000b3e: e3 f0 ff 20 ff 71 lay %r15,-224(%r15)
1000b44: b9 04 00 bf lgr %r11,%r15
1000b48: b2 4f 00 10 ear %r1,%a0
1000b4c: eb 11 00 20 00 0d sllg %r1,%r1,32
1000b52: b2 4f 00 11 ear %r1,%a1
1000b56: d2 07 b0 d8 10 28 mvc 216(8,%r11),40(%r1)
1000b5c: c0 20 00 03 82 84 larl %r2,0x1071064 //please input ...
1000b62: c0 e5 00 00 40 43 brasl %r14,0x1008be8 //printf
1000b68: ec 1b 00 a6 00 d9 aghik %r1,%r11,166
1000b6e: b9 04 00 31 lgr %r3,%r1
1000b72: c0 20 00 03 82 87 larl %r2,0x1071080 // %s
1000b78: c0 e5 00 00 3a 5c brasl %r14,0x1008030 // scanf(" ");
1000b7e: ec 1b 00 a6 00 d9 aghik %r1,%r11,166 //add
1000b84: b9 04 00 21 lgr %r2,%r1 %r1 : input
1000b88: c0 e5 ff ff fe c4 brasl %r14,0x1000910 //关键加密函数。
1000b8e: b9 04 00 12 lgr %r1,%r2 //mov
1000b92: 12 11 ltr %r1,%r1 //cmp test
1000b94: a7 84 00 17 je 0x1000bc2
1000b98: ec 1b 00 a6 00 d9 aghik %r1,%r11,166
1000b9e: b9 04 00 21 lgr %r2,%r1
1000ba2: c0 e5 ff ff ff 33 brasl %r14,0x1000a08
1000ba8: b9 04 00 12 lgr %r1,%r2
1000bac: 12 11 ltr %r1,%r1
1000bae: a7 84 00 0a je 0x1000bc2
1000bb2: c0 20 00 03 82 69 larl %r2,0x1071084 // lea "you win"
1000bb8: c0 e5 00 00 40 18 brasl %r14,0x1008be8
1000bbe: a7 f4 00 08 j 0x1000bce
1000bc2: c0 20 00 03 82 66 larl %r2,0x107108e //lea "you lose!"
1000bc8: c0 e5 00 00 40 10 brasl %r14,0x1008be8
提取处数据,在gdb中使用x/100xw查看的数据然后提取出(直接找到地址在hex.txt文件找也可以)。
然后解密:
#include <stdio.h>
unsigned int data[] = { 0x0000b2b0, 0x00006e72, 0x00006061, 0x0000565d,
0x0000942d, 0x0000ac79, 0x0000391c, 0x0000643d,
0x0000ec3f, 0x0000bd10, 0x0000c43e, 0x00007a65,
0x0000184b, 0x0000ef5b, 0x00005a06, 0x0000a8c0,
0x0000f64b, 0x0000c774, 0x000002ff, 0x00008e57,
0x0000aed9, 0x0000d8a9, 0x0000230c, 0x000074e8,
0x0000c2a6, 0x000088b3, 0x0000af2a, 0x00009ea7,
0x0000ce8a, 0x00005924, 0x0000d276, 0x000056d4,
0x000077d7, 0x0000990e, 0x0000b585, 0x00004bcd,
0x00005277, 0x00001afc, 0x00008c8a, 0x0000cdb5,
0x00006e26, 0x00004c22, 0x0000673f, 0x0000daff,
0x00000fac, 0x000086c7, 0x0000e048, 0x0000c483,
0x000085d3, 0x00002204, 0x0000c2ee, 0x0000e07f,
0x00000caf, 0x0000bf76, 0x000063fe, 0x0000bffb,
0x00004b09, 0x0000e5b3, 0x00008bda, 0x000096df,
0x0000866d, 0x00001719, 0x00006bcf, 0x0000adcc,
0x00000f2b, 0x000051ce, 0x00001549, 0x000020c1,
0x00003a8d, 0x000005f5, 0x00005403, 0x00001125,
0x00009161, 0x0000e2a5, 0x00005196, 0x0000d8d2,
0x0000d644, 0x0000ee86, 0x00003896, 0x00002e71,
0x0000a6f1, 0x0000dfcf, 0x00003ece, 0x00007d49,
0x0000c24d, 0x0000237e, 0x00009352, 0x00007a97,
0x00007bfa, 0x0000cbaa, 0x000010dc, 0x00003bd9,
0x00007d7b, 0x00003b88, 0x0000b0d0, 0x0000e8bc };
unsigned int result[] = { 0x08a73233, 0x116db0f6, 0x0e654937, 0x03c374a7,
0x16bc8ed9, 0x0846b755, 0x08949f47, 0x04a13c27,
0x0976cf0a, 0x07461189, 0x1e1a5c12, 0x11e64d96,
0x03cf09b3, 0x093cb610, 0x0d41ea64, 0x07648050,
0x092039bf, 0x08e7f1f7, 0x004d871f, 0x1680f823,
0x06f3c3eb, 0x2205134d, 0x015c6a7c, 0x11c67ed0,
0x0817b32e, 0x06bd9b92, 0x08806b0c, 0x06aaa515,
0x205b9f76, 0x0de963e9, 0x2194e8e2, 0x047593bc };
int main()
{
unsigned int a = 0;
for (int i = 0; i < 32; i++)
{
for (int input = 0x20; input < 0x7e; input++)
{
a = input*input*data[i]+ data[i + 32] * input+ data[i + 64];
if (a == result[i])
{
printf("%c", input);
break;
}
}
}
getchar();
}
//8eb5d8b632dae2a5167e3e1c4884eef9
easyre
直接拖入ida分析完main函数后没有发现加密判断函数,直接动调跟流程,读汇编代码,也很简单,只是一些移位的操作。整理了下加密与最后比较数据的笔记:
a = input[0] << 3
b = input[1] >> 5
a = a|b
a = a ^ i;
input[i] = (input[i] << 3) | (input[(i+1)%24] & 0xE0) >> 5
unsigned char ida_chars[] =
{
43, 8, 169, 200, 151, 47, 255, 140, 146, 240,
163, 137, 247, 38, 7, 164, 218, 234, 179, 145,
239, 220, 149, 171
};
sar:算术右移指令。右移时保留操作数的符号,即用符号位来补足。
shr:逻辑右移指令。右移时总是用0来补足。
解密:
#include <stdio.h>
unsigned char ida_chars[] =
{
43, 8, 169, 200, 151, 47, 255, 140, 146, 240,
163, 137, 247, 38, 7, 164, 218, 234, 179, 145,
239, 220, 149, 171
};
int main(void)
{
int i = 0;
unsigned char ch1 = 0;
ch1 = (ida_chars[0] >> 3) | (ida_chars[23] << 5);
putchar(ch1);
for(i = 1; i < 23; i++)
{
ch1 = (((ida_chars[i]^i) >> 3) | ((ida_chars[i-1]^(i-1)) << 5))&0xff;
putchar(ch1);
}
ch1 = (ida_chars[23] >> 3 ) | ((ida_chars[22]^22) << 5);
putchar(ch1);
//ea5yre_1s_50_ea5y_t0_y0u
}
easy_c++
很简单,ida打开后简单分析以下,只是对输入进行了一个异或,然后与指定编码字符串进行比较。。
直接在ida-python解决:
s = '7d21e<e3<:3;9;ji t r#w\"$*{*+*$|,'
flag = ''
for i in range(32):
flag += chr(ord(s[i])^i)
print(flag)
#7e02a9c4439056df0e2a7b432b0069b3
ReMe
首先从程序图标可以想到python,然后ida载入查看字符串,发现很多PY相关的字符且程序不寻常。这时候基本可以确定是python打包成的exe程序了。
然后使用python pyinstxtractor.py ReMe.exe解包,从得到的包里可以pyc文件看到ReMe,但是缺少文件头的,找到包里的另一个stuct文件,对ReMe的文件头进行补齐。
接着使用uncompyle6 -o re.py ReMe.pyc转化为py文件。
py代码很简单,把原来的代码稍微修改以下可以直接爆破出flag:
import sys, hashlib
check = [
'e5438e78ec1de10a2693f9cffb930d23',
'08e8e8855af8ea652df54845d21b9d67',
'a905095f0d801abd5865d649a646b397',
'bac8510b0902185146c838cdf8ead8e0',
'f26f009a6dc171e0ca7a4a770fecd326',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'4cb467175ab6763a9867b9ed694a2780',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'cffd0b9d37e7187483dc8dd19f4a8fa8',
'fd311e9877c3db59027597352999e91f',
'49733de19d912d4ad559736b1ae418a7',
'7fb523b42413495cc4e610456d1f1c84',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'acb465dc618e6754de2193bf0410aafe',
'bc52c927138231e29e0b05419e741902',
'515b7eceeb8f22b53575afec4123e878',
'451660d67c64da6de6fadc66079e1d8a',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'fe86104ce1853cb140b7ec0412d93837',
'acb465dc618e6754de2193bf0410aafe',
'c2bab7ea31577b955e2c2cac680fb2f4',
'8e50684ac9ef90dfdc6b2e75f2e23741',
'f077b3a47c09b44d7077877a5aff3699',
'620741f57e7fafe43216d6aa51666f1d',
'9e3b206e50925792c3234036de6a25ab',
'49733de19d912d4ad559736b1ae418a7',
'874992ac91866ce1430687aa9f7121fc']
def func(num):
result = []
while num != 1:
num = num * 3 + 1 if num % 2 else num // 2
result.append(num)
return result
if __name__ == '__main__':
flag = ''
for i in range(27):
for ch in range(32, 127):
ret_list = func(ch)
s = ''
for idx in range(len(ret_list)):
s += str(ret_list[idx])
s += str(ret_list[(len(ret_list) - idx - 1)])
md5 = hashlib.md5()
md5.update(s.encode('utf-8'))
if md5.hexdigest() == check[i]:
flag += chr(ch)
break
md5 = hashlib.md5()
md5.update(flag.encode('utf-8'))
print('flag{' + md5.hexdigest() + '}')
#flag{0584cfa2ce502951ef5606f6b99fc921}