开坑,此处更新reversing.kr 的re题的wp。希望我能坚持下去。
reversing.kr是棒子的一个逆向网站,题目质量不错(学长推荐的),欢迎各位学bin的来摩擦。
Easy Crack 直接拖到ida,shift+f12查看字符串,定位关键函数:
直接拼出flag:Ea5yR3versing
Easy Keygen
Find the Name when the Serial is 5B134977135E7D13
直接拖到ida,关键代码在main函数里。
应该不用我解释了,上python:
1 2 3 4 5 6 7 serial = '5B134977135E7D13' .decode('hex' ) key=[0x10 ,0x20 ,0x30 ] name='' for i in range (len (serial)): name+=chr (ord (serial[i])^key[i%3 ]) print name
flag:K3yg3nm3
Easy Unpack
Find the OEP ex) 00401000
脱个简单的压缩壳而已,脱壳环境xp sp3。
用esp定律轻松来到壳的段尾:
f8到oep
lordpe转储,importREC修复,脱壳成功。
所以flag:00401150
Music Player
This MP3 Player is limited to 1 minutes. You have to play more than one minute.
There are exist several 1-minute-check-routine. After bypassing every check routine, you will see the perfect flag.
先让他放到一分钟,有一个弹窗提示,
由于是vb,下断点BP rtcMsgBox,重新运行
向上翻,可以发现有一个jl可以跳过这段代码,而比较的值为0xEA60,即60000,就是一分钟,那我们把jl改成jmp。
到一分钟以后跳出了:
下断点 bp RaiseException 重载
再次跳出窗口时成功断下,打开堆栈调用的窗口:
来到
把jge改成jmp,保存以后重载
成功得到flag:LIstenCare
Replace 意图很明显,你输入正确的key,下面就是提示正确。这题有趣就有趣在你随便输一个数,这个程序一般是会炸的
那我们就分析一下。
根据字符串来到这里:
发现上面有个jmp不科学。更上面的一个jmp跳到了一个更奇怪的地方:
我也卡不出这些代码是些什么,估计是汇编手写的,那就动态跟踪一下看看。
上面有个GetBlgItemInt,是用来获取用户输入的,先在那里下断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 0040104C > \56 push esi ; Case 3EB of switch 0040103A 0040104D . 8B75 08 mov esi,dword ptr ss:[ebp+0x8] 00401050 . 6A 00 push 0x0 ; /IsSigned = FALSE 00401052 . 6A 00 push 0x0 ; |pSuccess = NULL 00401054 . 68 EA030000 push 0x3EA ; |ControlID = 3EA (1002.) 00401059 . 56 push esi ; |hWnd = 000E07D8 ('Replace',class='#32770') 0040105A . FF15 9C504000 call dword ptr ds:[<&USER32.GetDlgItemIn>; \GetDlgItemInt 00401060 . A3 D0844000 mov dword ptr ds:[0x4084D0],eax ; int to 0x4084d0 00401065 > E8 05360000 call Replace.0040466F 0040106A . 33C0 xor eax,eax 0040106C . E9 1F360000 jmp Replace.00404690 00401071 . EB 11 jmp short Replace.00401084 00401073 . 68 34 60 40 0>ascii "h4`@",0 ; Correct! 00401078 . 68 E9030000 push 0x3E9 ; |ControlID = 3E9 (1001.) 0040107D . 56 push esi ; |hWnd = 000E07D8 ('Replace',class='#32770') 0040107E . FF15 A0504000 call dword ptr ds:[<&USER32.SetDlgItemTe>; \SetDlgItemTextA 00401084 > B8 01000000 mov eax,0x1 00401089 . 90 nop 0040108A . 90 nop
call Replace.0040466F那里跟过去
可见应该是作者把call当jmp用,而且那两句mov的地址引起了我的注意,可见这是一段SMC的代码。
跟了一下,操作大致如下,把输入的值转换为整型放到eax,然后把eax的值存到0x4084D0,并+1、+1、+0x601605C7、+1、+1,然后把0x4084D0的值存到eax,把eax的值及其+1对应的地址的机器码修改为0x90。为了达成目的,我们需要让0x401071、0x401072是nop,才会显示correct!
因此只要我们输入值+1+1+0x601605C7+1+1=0x401071,由此需要溢出,用0x100401071-1-1-0x601605C7-1-1
flag:2687109798
ImagePrc 看样子应该是在程序上画画,然后对图片进行判断。
根据字符串“wrong”找到核心代码:
用reshacker把资源dump出来以后写个脚本解密即可
1 2 3 4 5 6 7 8 9 10 11 from PIL import Imagewidth = 200 height = 150 image_file = open ('Data_1.bin' , 'rb' ) data = image_file.read() image = Image.frombuffer('RGB' , (width, height), data, 'raw' , 'RGB' ) image = image.transpose(Image.FLIP_TOP_BOTTOM) image.show() image_file.close()
flag:GOT
Easy ELF 这题我不能用ida的f5键,那就看汇编分析吧。 (已经部分重命名) 首先到main函数:
可见主体在calc函数里面:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 .text:08048451 calc proc near ; CODE XREF: main+2Ap .text:08048451 push ebp .text:08048452 mov ebp, esp .text:08048454 movzx eax, ds:input+1 .text:0804845B cmp al, '1' ; input[1]='1' .text:0804845D jz short loc_8048469 .text:0804845F mov eax, 0 .text:08048464 jmp loc_80484F5 .text:08048469 ; --------------------------------------------------------------------------- .text:08048469 .text:08048469 loc_8048469: ; CODE XREF: calc+Cj .text:08048469 movzx eax, ds:input .text:08048470 xor eax, 34h ; xor [0],0X34 .text:08048473 mov ds:input, al .text:08048478 movzx eax, ds:input+2 ; xor [2],0X32 .text:0804847F xor eax, 32h .text:08048482 mov ds:input+2, al .text:08048487 movzx eax, ds:input+3 ; xor [3],0x88 .text:0804848E xor eax, 0FFFFFF88h .text:08048491 mov ds:input+3, al .text:08048496 movzx eax, ds:input+4 ; [4] = 'X' .text:0804849D cmp al, 'X' .text:0804849F jz short loc_80484A8 ; [5] = 0 .text:080484A1 mov eax, 0 .text:080484A6 jmp short loc_80484F5 .text:080484A8 ; --------------------------------------------------------------------------- .text:080484A8 .text:080484A8 loc_80484A8: ; CODE XREF: calc+4Ej .text:080484A8 movzx eax, ds:input+5 ; [5] = 0 .text:080484AF test al, al .text:080484B1 jz short loc_80484BA ; cmp [2],0x7C .text:080484B3 mov eax, 0 .text:080484B8 jmp short loc_80484F5 .text:080484BA ; --------------------------------------------------------------------------- .text:080484BA .text:080484BA loc_80484BA: ; CODE XREF: calc+60j .text:080484BA movzx eax, ds:input+2 ; cmp [2],0x7C .text:080484C1 cmp al, 7Ch .text:080484C3 jz short loc_80484CC ; CMP [0],0X78 .text:080484C5 mov eax, 0 .text:080484CA jmp short loc_80484F5 .text:080484CC ; --------------------------------------------------------------------------- .text:080484CC .text:080484CC loc_80484CC: ; CODE XREF: calc+72j .text:080484CC movzx eax, ds:input ; CMP [0],0X78 .text:080484D3 cmp al, 78h .text:080484D5 jz short loc_80484DE .text:080484D7 mov eax, 0 .text:080484DC jmp short loc_80484F5 .text:080484DE ; ---------------------- ----------------------------------------------------- .text:080484DE .text:080484DE loc_80484DE: ; CODE XREF: calc+84j .text:080484DE movzx eax, ds:input+3 .text:080484E5 cmp al, 0DDh ; CMP [3],0XDD .text:080484E7 jz short loc_80484F0 .text:080484E9 mov eax, 0 .text:080484EE jmp short loc_80484F5 .text:080484F0 ; --------------------------------------------------------------------------- .text:080484F0 .text:080484F0 loc_80484F0: ; CODE XREF: calc+96j .text:080484F0 mov eax, 1 .text:080484F5 .text:080484F5 loc_80484F5: ; CODE XREF: calc+13j .text:080484F5 ; calc+55j ... .text:080484F5 pop ebp .text:080484F6 retn .text:080484F6 calc endp .text:080484F6
直接跑脚本:
1 2 3 4 5 6 7 flag='' flag+=chr (0x78 ^0x34 ) flag+='1' flag+=chr (0x7c ^0x32 ) flag+=chr (0xdd ^0x88 ) flag+='X' print flag
flag:L1NUX
ransomware 首先readme告诉我们,被加密的文件原来是一个exe文件。
运行程序发现乱码,因为是韩国人的网站,猜测上面应该是韩文,这不是重点,我们仍然可以分析。
首先程序加了upx壳,简单脱掉不解释了。
想载入ida,但发现分析异常缓慢,OD看了一下,发现加了花式nop指令:
那就写个脚本去掉:
1 2 3 data = open ('run.exe' ,'rb' ).read() data = data.replace('\x60\x61\x90\x50\x58\x53\x5b' ,'\x90\x90\x90\x90\x90\x90\x90' ) open ('run_dejunk.exe' ,'wb' ).write(data)
再丢到ida里就能分析了:
这里我们根据pe文件中一点:
就是这句话在固定的位置上(虽然这句话能改,而且不影响程序运行,但一般我们是不会去修改的,所以可以利用)
1 2 3 4 5 6 7 8 9 10 11 enc='C7F2E2FFAFE3ECE9FBE5FBE1ACF0FBE5E2E0E7BEE4F9B7E8F9E2B3F3E5ACCBDCCDA6F1F8FEE9'.decode('hex') dec='This program cannot be run in DOS mode' key='' enc = list(enc) dec = list(dec) for i in range(len(enc)): enc[i] = (~ord(enc[i]))&255 key += chr(ord(dec[i])^enc[i]) print key
得到key = “letsplaychess”
解密文件:
1 2 3 4 5 6 7 8 data_c = open('file','rb').read() data_d='' key='letsplaychess' key_len = len(key) for i in range(len(data_c)): data_d += chr(ord(key[i%key_len])^(~ord(data_c[i]))&255) open('file.exe','wb').write(data_d)
运行file.exe得到flag:Colle System
CSHOP 这题很迷,我同时放上我的解题过程和网上的过程。
我打开窗口,发现只有一个空白的窗口,我习惯性的点了点鼠标,敲了敲键盘,结果按到空格的时候出现了这个:
提交发现就是flag。。。。
接着放网上的方法:
这题是一个C#的题,打开是一个空白的对话框,用dnSpy反编译,看到new了一个按钮,但大小却是0
可以修改IL指令把size改大点,然后按钮就显示出来了,其实不改也行,由于按钮的TabIndex是0,当焦点在按钮上时,按空格键相当于点击按钮,所以打开程序后按下空格flag就出来了
flag:P4W6RP6SES
Direct3D_FPS 这题很迷,我电脑上打开这个程序是白屏的,又只能靠字符串来猜测程序了。23333
在Game_clear的函数中,发现messagebox的text参数很可疑,我猜是flag,交叉引用发现有异或加密:
byte_409184这个地方看起来很重要,但是靠ida静态分析我没能得出这里面的数据是什么。
大致上逻辑是:
i = sub_403440(); flag[i] ^= byte_409184[528*i];
那我们用OD动态分析试试看:
发现 byte_409184[528*i] = 4*i。 所以flag[i] ^= 4i;
写个python脚本解密一下即可:
1 2 3 4 5 6 flag_c='436B666B62756C694C455C455F5A461C07252529701734390116494C20150B0FF7EBFAE8B0FDEBBCF4CCDA9FF5F0E8CEF0A9' .decode('hex' ) flag_d='' for i in range (len (flag_c)): flag_d += chr (ord (flag_c[i])^4 *i) print flag_d
flag:Thr3EDPr0m
HateIntel mac上的程序,但我们有万能的ida。
主函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int sub_2224() { char key; // [sp+4h] [bp-5Ch]@1 int int_4; // [sp+54h] [bp-Ch]@1 signed __int32 key_len; // [sp+58h] [bp-8h]@1 signed __int32 i; // [sp+5Ch] [bp-4h]@1 char vars0; // [sp+60h] [bp+0h]@2 int_4 = 4; printf("Input key : "); scanf("%s", &key); key_len = strlen(&key); enc((signed __int32)&key, int_4); for ( i = 0; i < key_len; ++i ) { if ( (unsigned __int8)*(&vars0 + i - 0x5C) != byte_3004[i] )// key cmp { puts("Wrong Key! "); return 0; } } puts("Correct Key! "); return 0; }
enc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 signed __int32 __fastcall enc(signed __int32 len_key, int int_4) { int _4; // [sp+0h] [bp-14h]@1 char *key; // [sp+4h] [bp-10h]@1 int i; // [sp+8h] [bp-Ch]@1 signed __int32 j; // [sp+Ch] [bp-8h]@2 key = (char *)len_key; _4 = int_4; for ( i = 0; i < _4; ++i ) // 加密4次 { for ( j = 0; ; ++j ) { len_key = strlen(key); if ( len_key <= j ) break; key[j] = calc(key[j], 1); } } return len_key; }
calc:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 int __fastcall calc(unsigned __int8 key_char, int _1) { int ch; // [sp+8h] [bp-8h]@1 int i; // [sp+Ch] [bp-4h]@1 ch = key_char; for ( i = 0; i < _1; ++i ) { ch *= 2; if ( ch & 256 ) ch |= 1u; } return (unsigned __int8)ch; }
直接写脚本爆破:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def calc (result ): for i in range (32 ,128 ): k = i for j in range (4 ): tmp = k*2 if tmp & 0x100 : tmp |= 1 k = tmp & 255 if k == result: return chr (i) f_c = '44F6F557F5C696B656F51425D4F596E63747275736479603E6F3A392' .decode('hex' ) f_d = '' for ch in f_c: f_d+=calc(ord (ch)) print f_d
flag:Do_u_like_ARM_instructi0n?:)
Flash Encrypt 这题只要工具好就能做
网上下载ffdec。
用ffdec反编译swf,在设置中选上自动反混淆
来到帧1:
提示是按钮2 (4),查看脚本:
需要输入1456,然后到帧3,
如此下来,依次输入: 1456,25,44,8,88,20546即可。
flag:16876
Position 题目描述:
Find the Name when the Serial is 76876-77776 This problem has several answers. Password is ***p
ida载入,根据字符串来到这里:
到calc函数内部:
分析得逻辑如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 v7=name[0] v8 = (v7 & 1) + 5 v59 = ((v7 >> 4) & 1) + 5 v53 = ((v7 >> 1) & 1) + 5 v55 = ((v7 >> 2) & 1) + 5 v57 = ((v7 >> 3) & 1) + 5 v9=name[1] v45 = (v9 & 1) + 1 v51 = ((v9 >> 4) & 1) + 1 v47 = ((v9 >> 1) & 1) + 1 v10 = ((v9 >> 2) & 1) + 1 v49 = ((v9 >> 3) & 1) + 1 v8+v10=serial[0] v57+v49==serial[1] v53+v51==serial[2] v55+v45==serial[3] v59+v47==serial[4] ===================== v26=name[2] v27 = (v26 & 1) + 5 v60 = ((v26 >> 4) & 1) + 5 v54 = ((v26 >> 1) & 1) + 5 v56 = ((v26 >> 2) & 1) + 5 v58 = ((v26 >> 3) & 1) + 5 v28=name[3] v46 = (v28 & 1) + 1 v52 = ((v28 >> 4) & 1) + 1 v48 = ((v28 >> 1) & 1) + 1 v29 = ((v28 >> 2) & 1) + 1 v50 = ((v28 >> 3) & 1) + 1 v27+v29==serial[5] v58+v50==serial[6] v54+v52==serial[7] v56+v46==serial[8] v60+v48==serial[9]
脚本爆破:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 serial='7687677776' for i in range (ord ('a' ),ord ('z' )+1 ): for j in range (ord ('a' ),ord ('z' )+1 ): v7=i v9=j v8 = (v7 & 1 ) + 5 v59 = ((v7 >> 4 ) & 1 ) + 5 v53 = ((v7 >> 1 ) & 1 ) + 5 v55 = ((v7 >> 2 ) & 1 ) + 5 v57 = ((v7 >> 3 ) & 1 ) + 5 v45 = (v9 & 1 ) + 1 v51 = ((v9 >> 4 ) & 1 ) + 1 v47 = ((v9 >> 1 ) & 1 ) + 1 v10 = ((v9 >> 2 ) & 1 ) + 1 v49 = ((v9 >> 3 ) & 1 ) + 1 if v8+v10==int (serial[0 ]) and v57+v49==int (serial[1 ]) and v53+v51==int (serial[2 ]) and v55+v45==int (serial[3 ]) and v59+v47==int (serial[4 ]): print chr (i),chr (j) print '===============' for i in range (ord ('a' ),ord ('z' )+1 ): for j in range (ord ('a' ),ord ('z' )+1 ): v26=i v28=j v27 = (v26 & 1 ) + 5 v60 = ((v26 >> 4 ) & 1 ) + 5 v54 = ((v26 >> 1 ) & 1 ) + 5 v56 = ((v26 >> 2 ) & 1 ) + 5 v58 = ((v26 >> 3 ) & 1 ) + 5 v46 = (v28 & 1 ) + 1 v52 = ((v28 >> 4 ) & 1 ) + 1 v48 = ((v28 >> 1 ) & 1 ) + 1 v29 = ((v28 >> 2 ) & 1 ) + 1 v50 = ((v28 >> 3 ) & 1 ) + 1 if v27+v29==int (serial[5 ]) and v58+v50==int (serial[6 ]) and v54+v52==int (serial[7 ]) and v56+v46==int (serial[8 ]) and v60+v48==int (serial[9 ]): print chr (i),chr (j)
输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 b u c q f t g p =============== a y b m c i e x f l g h h u i q j e k a l t m p n d
由于name第四位为’p’,所以可能的name为:
提交bump
时成功,flag:bump