ムクソカクナケフçタハマロZ6ホ日モヒ4
クレルçアZエシネスフ74ーヨノ5ラ9ウ
ロモキナチヤカウ9ミハ・ノ日ユシマ7ク:
ア0ツコロリ3ヨルソンヘトネçク9ーレサ
4フツハヘワケ8ヤ01ホタエオ:ウメリク
1Zリナミアユワツトキタヤテçネノ8ケセ
ホイ7コセヒケ8日ラエリヲトタヤワ3テウ
.フナヌカニクキヒソーコ09セ1ホサヘワ
クカルムミヨニラテ・ネ8ヌオユハナ日9ア
ワコチキーヨクスムルツヘン.フ9タセアヲ
.7カウレ9ツ2テ1サノンモムクスローヌ
テZ6ヌキカソルウ.シ8日ハ59ツ2ニサ
ヨナシマロリヒ5ウヌアミエムン日3ス.ホ
セエホ3ユルZヘーオヲレニクカヤヒ:リソ
カチソ.ヲコ4クノケフオ5クス61タツレ
チムツZシイレ日3タ5クモリス6ユニソワ
ケ.ハオ0ナ65ヒクルソヨZレ32日モç
ユノ日ミチヨヘナ5タル4キ9ハイテヲマ0
Z97.レシウアクチロツフ35ーワケネラ
ンー5ケロラ:29モチスニクçワリ・コ0
ユ5ネセエヌールタラ・ケ.ヤヲナテホノウ
カモヌム4ク7ロウー.チメニヘヨ8ノルト
:ーヘ6ミ9日ホキロムコテヤサルヌイçラ
イセヘヤç8ケヒユモサーZマミンリアエホ
ç6エノホニシーヘムイメマヤセヒンヲ2Z
ナクスローモエフ1リサ4カ日テコヒ・ツニ
タキムチç日0ウワ6メコヘセユナツア4オ
カツレソ2ー7.ヒ8シçニタオトヌ4フネ
ホサヒソネ・タ0シロミコワー23トテスキ
ケ2ムレイラZユミツメヤ8・ニヨソロアナ
トミ29ワヌ4サクリラタカ86マZウルユ
ルフçニマチ.6タヘム8ヲレナテキノZイ
カルフンユリタヤ8ヒ:モヘコテオクエツワ
メ日42キアヲçZハシニナ1ムウコセネヨ
ト8セZ3オイークカ・ラタシニ0ノ2ツメ
カク8ヲ:テシト9キツ日6タエコムヘサ・
5ツソマオ・.フ279ロçホネメタ:ヌ4
ルスライZミソヒワ2ク3ト7ヨシ1ネ・日
ワ.シZユクー60ンタア・ツ3オクマ9チ
ネミ5Zムフ:ヨ2リウ7タ94キイマーシ
ナメユオヲ・サン7ホチレ04:9ヌç日ハ
.ムナタヒリオツニ48イ日エ0サウソ5テ
ノメワ5・モアスカ:ラムçキト日ク2ニケ
2ユ5çヤカヌコ9ロヨウシト0ノタリメオ
7タツヒ.エハ:ナワメーオリヨセ301・
シロ9タナニネワテホキヒクカ8ーセクハ.
:ラク8ノホテイ2.クモヤウシニールマヘ
イ日スルツキフヲ94ア3ワナネヘセクユ2
ラルワ8ヲセシ6ケチホムヒ・ミオサフエア
ソモヤーホタカ日・ンリミ.ネノメ:çマロ
ヌキイルニ84モコ7リク日ノ1ンメクレト
0クロçナ1ムモ9シエサ日ヲラコヌZハヤ
ヘチタンテキ1ロ4ユサツ0セクーカソホヤ
9オロチヒ0ネ6・:4çメハヲユニミワツ
キリ8ト:ヒルスオウカヌホ5ソニネラサナ
ナフマ7ーサシ・ユンワテミリラツヌZ02
モア4リ20ータム.Zヒラコスクヌソキツ
エ3ヒキ6タヨムミ1ーçスホメヌア2モソ
ノハキ8ウツサイ・ーチスオ4ロ7ルムラヒ
ンホスZハ9レーカケキトコヌル0.ウラヤ
日フ.05トテアシハナロニルワス29ヌレ
キム3ホケハクミリス9テユラートçレ7チ
6タツ.ヲキリヌセ04Zホチヤ:シイロン
5ー3レクユ:ロチホヲ8ソテマ1ヌシ2ヤ
タツアコ4サミモソオケ0ネカ.57ナムロ

Writeup MBE 1B

Writeup MBE 1B

七月 3, 2019 阅读 251 字数 13117 评论 0 喜欢 2

lab1B

lab1B@warzone:/levels/lab01$ file lab1B
lab1B: setuid ELF 32-bit LSB  executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=c9f07b581bd8d97cdc7c0ff1a288e20aea2df0f5, stripped

继续R2 analyze all (aaa)

lab1B@warzone:/levels/lab01$ r2 lab1B
 -- command not found: calc.exe
[0x08048850]  aaa

list all functions (afl)

[0x08048850] afl
0x08048850  34  1  entry0
0x08048820  6  1  sym.imp.__libc_start_main
0x08048826  10  2  fcn.08048826
0x08048760  12  1  section..plt
0x0804876c  10  1  sub.strcmp_12_76c
0x08048776  10  1  fcn.08048776
0x08048780  6  1  sym.imp.printf
0x08048786  10  1  fcn.08048786
0x08048790  6  1  sym.imp.fflush
0x08048796  10  1  fcn.08048796
0x080487a0  6  1  sym.imp.getchar
0x080487a6  10  1  fcn.080487a6
0x080487b0  6  1  sym.imp.time
0x080487b6  10  1  fcn.080487b6
0x080487c0  6  1  sym.imp.__stack_chk_fail
0x080487c6  10  1  fcn.080487c6
0x080487d0  6  1  sym.imp.puts
0x08048830  6  1  sym.imp.rand
0x08048836  10  1  fcn.08048836
0x08048840  6  1  sym.imp.__isoc99_scanf
0x08048846  10  1  fcn.08048846
0x08048880  4  1  fcn.08048880
0x08048890  42  4  fcn.08048890
0x080488ba  61  4  fcn.080488ba
0x080488f7  39  3  fcn.080488f7
0x08048920  45  8  fcn.08048920
0x0804894d  34  5  sym.clear_stdin
0x0804896f  55  1  sym.get_unum
0x080489a6  17  1  sym.prog_timeout
0x080489b7  189  11  sym.decrypt
0x08048a74  368  3  sym.test
0x08048be4  133  3  sym.main
0x08048800  6  1  sym.imp.srand
0x08048806  10  1  fcn.08048806
0x08048810  6  1  sym.imp.strlen
0x08048816  10  1  fcn.08048816
0x08048c70  97  4  sym.__libc_csu_init
0x08048cd1  17  2  fcn.08048cd1
0x08048ce2  22  1  section_end..text
0x08048738  35  3  section..init
0x080487f0  6  1  sym.imp.__gmon_start__
0x080487f6  10  1  fcn.080487f6
0x0804875b  17  1  section_end..init
0x080487e0  6  1  sym.imp.system
0x080487e6  10  1  fcn.080487e6

main 函数里面
密码输入提示在 前两行代码里面,str.npassword, call sym.imp.printf;
后面scanf 提示用户输入密码,获取到的两个参数,一个是 [esp+0x1c] 一个是 0x8048dee。

 |           0x08048c2e    c70424e28d04.  mov dword [esp], str._nPassword:  ; [0x8048de2:4]=0x7361500a  ; str._nPassword:
│          0x08048c35    e846fbffff     call sym.imp.printf ;sym.imp.printf()
│          0x08048c3a    8d44241c       lea eax, [esp + 0x1c]           ; 0x1c
│          0x08048c3e    89442404       mov dword [esp + 4], eax        ; [0x4:4]=0x10101
│          0x08048c42    c70424ee8d04.  mov dword [esp], 0x8048dee      ; [0x8048dee:4]=0x6425
│          0x08048c49    e8f2fbffff     call sym.imp.__isoc99_scanf ;sym.imp.__isoc99_scanf()

打印0x8048dee ps(print string)

[0x08048850]  ps @ 0x8048dee
%d

输入之后跟着的代码是 把用户输入的密码 和 0x1337d00d 一起传入了 自定义函数 test;

 |           0x08048c4e    8b44241c       mov eax, dword [esp + 0x1c]     ; [0x1c:4]=52
│          0x08048c52    c74424040dd0.  mov dword [esp + 4], 0x1337d00d  ; [0x1337d00d:4]=-1
│          0x08048c5a    890424         mov dword [esp], eax
│          0x08048c5d    e812feffff     call sym.test ;sym.test()

反推出来的C代码应该是这样色的

int userinput;
printf("password:  \n");
scanf("%d", &userinput);
test(userinput, 0x1337d00d);

接着看 test 函数

[0x08048850]  pdf @ sym.test
╒ (fcn) sym.test 368
│           ; arg int arg_2        @ ebp+0x8
│           ; arg int arg_3        @ ebp+0xc
│           ; arg int arg_5_1      @ ebp+0x15
│           ; var int local_3      @ ebp-0xc
│           ; CALL XREF from 0x08048c5d (sym.main)
│           ;-- sym.test:
│           0x08048a74    55             push ebp
│           0x08048a75    89e5           mov ebp, esp
│           0x08048a77    83ec28         sub esp, 0x28

首先,我们先找到传入进来的2个 参数, arg2 arg3 ,此时栈的状态是

ebp + 0x0 [ saved ebp ] <— push ebp
ebp + 0x4 [ return address ] <—return address pushed by call-instrunction
ebp + 0x8 [integer userinput] <— 1st argument
ebp + 0xc [constant 0x1337d00d] <— 2nd argument

go on

│           0x08048a74    55             push ebp
│           0x08048a75    89e5           mov ebp, esp
│           0x08048a77    83ec28         sub esp, 0x28
│           0x08048a7a    8b4508         mov eax, dword [ebp + 8]       ; [0x8:4]=0
│           0x08048a7d    8b550c         mov edx, dword [ebp + 0xc]     ; [0xc:4]=0
│           0x08048a80    29c2           sub edx, eax
│           0x08048a82    89d0           mov eax, edx
│           0x08048a84    8945f4         mov dword [ebp-local_3], eax
│           0x08048a87    837df415       cmp dword [ebp-local_3], 0x15  ; [0x15:4]=0x50000000
│       ┌─< 0x08048a8b    0f8744010000   ja 0x8048bd5

eax(userinput) edx(constant) 然后 edx – eax 最后把 值 再赋给eax
然后把eax的值 传给 dword[ebp-local_3] , 再与0x15 compare;
反推出来的C代码是这样几的;

void test(int userinput, int constant)
{
	int result;
	result = constant - userinput;
	if(result <= 0x15){
	}else{
		0x8048bd5;
	}
	return;
}

如果没有大于 0x15 ,那就不会 jmp 到 0x8048bd5, 所以就说明 constant(0x1337d00d) 与userinput 的差 小于0x15;
那么继续跟踪代码如下:

│       │   0x08048a91    8b45f4         mov eax, dword [ebp-local_3]
│       │   0x08048a94    c1e002         shl eax, 2
│       │   0x08048a97    05308d0408     add eax, 0x8048d30
│       │   0x08048a9c    8b00           mov eax, dword [eax]
│       │   0x08048a9e    ffe0           jmp eax
│       │   0x08048aa0    8b45f4         mov eax, dword [ebp-local_3]
│       │   0x08048aa3    890424         mov dword [esp], eax
│       │   0x08048aa6    e80cffffff     call sym.decrypt ;sym.decrypt()

把 [ebp-local_3] 给 eax(两者的差),然后算数左移 2位 之后再加上 0x8048d30,再把 [eax] 的值给eax,然后 jmp eax;
把 差传递给 eax,把 差 入栈;调用函数 sym.decrypt;
这段汇编 反推出来的C 代码应该是this:

if(result <= 0x15){
	void *ptr = (void*)(result << 2);
	ptr += 0x8048d30;
	goto *ptr;
}

现在让我们看一下 result<= 15 存在可能继续的地址;

result result << 2 ptr += 0x8048d30
0x15 0x54 0x8048d84
0x14 0x50 0x8048d80
0x13 0x4c 0x8048d7c
0x12 0x48 0x8048d78
···
0x01 0x04 0x8048d34
0x00 0x00 0x8048d30

范围从 0x8048d30(0x00) 到 0x8048d84(0x15)

[0x08048850]> pxw 88 @ 0x8048d30
0x08048d30  0x08048bd5 0x08048aa0 0x08048ab0 0x08048ac0  ................
0x08048d40  0x08048ad0 0x08048ae0 0x08048af0 0x08048b00  ................
0x08048d50  0x08048b10 0x08048b20 0x08048b30 0x08048b40  .... ...0...@...
0x08048d60  0x08048b50 0x08048b60 0x08048b6d 0x08048b7a  P...`...m...z...
0x08048d70  0x08048b87 0x08048b94 0x08048ba1 0x08048bae  ................
0x08048d80  0x08048bbb 0x08048bc8                      ........

88bytes(= 0x15= 22dwords)

现在拿到了 jmp eax 的值; 也就是 goto *ptr 的值, 现在我们看看这些地址的汇编代码是怎么样的
例如:0x8048d30(result=0x00)

pd(print disassmeble)

[0x08048850]  > pd 5 @ [0x8048d30]
           ; JMP XREF from 0x08048a8b (sym.test)
│          0x08048bd5    e856fcffff     call sym.imp.rand ;sym.imp.rand()
│          0x08048bda    890424         mov dword [esp], eax
│          0x08048bdd    e8d5fdffff     call sym.decrypt ;sym.decrypt()
│          0x08048be2    c9             leave
╘          0x08048be3    c3             ret

call imp.rand() 调用随机数,然后传给eax, 再 call decrypt();

其他结果:
|result=0x01, 0x02, 0x03 look like this;

[0x08048850]> pd 4 @ [0x8048d34]
│          0x08048aa0    8b45f4         mov eax, dword [ebp-local_3]
│          0x08048aa3    890424         mov dword [esp], eax
│          0x08048aa6    e80cffffff     call sym.decrypt ;sym.decrypt()
│          0x08048aab    e932010000     jmp 0x8048be2
[0x08048850]> pd 4 @ [0x8048d38]
│          0x08048ab0    8b45f4         mov eax, dword [ebp-local_3]
│          0x08048ab3    890424         mov dword [esp], eax
│          0x08048ab6    e8fcfeffff     call sym.decrypt ;sym.decrypt()
│          0x08048abb    e922010000     jmp 0x8048be2
[0x08048850]> pd 4 @ [0x8048d3c]
│          0x08048ac0    8b45f4         mov eax, dword [ebp-local_3]
│          0x08048ac3    890424         mov dword [esp], eax
│          0x08048ac6    e8ecfeffff     call sym.decrypt ;sym.decrypt()
│          0x08048acb    e912010000     jmp 0x8048be2

调用4条重复的汇编指令,将 [ebp-local_3] (constant-userinput的差)作为参数,call decrypt() functions;ret 后 jmp 0x8048be2 sym.test functions的末尾;

so let’s have a look at the function sys.decrypt

[0x08048850]> pdf @ sym.decrypt
╒ (fcn) sym.decrypt 189
│          ; arg int arg_2        @ ebp+0x8
│          ; arg int arg_215506719_1 @ ebp+0x33617c7d
│          ; arg int arg_433691864 @ ebp+0x67667360
│          ; arg int arg_492773204_1 @ ebp+0x757c7d51
│          ; arg int arg_517577951_2 @ ebp+0x7b66737e
│          ; var int local_3      @ ebp-0xc
│          ; var int local_3_1    @ ebp-0xd
│          ; var int local_7_1    @ ebp-0x1d
│          ; var int local_9      @ ebp-0x24
│          ; var int local_10     @ ebp-0x28
│          ; CALL XREF from 0x08048bdd (sym.test)
│          ;-- sym.decrypt:
│          0x080489b7    55             push ebp
│          0x080489b8    89e5           mov ebp, esp
│          0x080489ba    83ec38         sub esp, 0x38
│          0x080489bd    65a114000000   mov eax, dword gs:[0x14]        ; [0x14:4]=1
│          0x080489c3    8945f4         mov dword [ebp-local_3], eax
│          0x080489c6    31c0           xor eax, eax
│          0x080489c8    c745e3517d7c.  mov dword [ebp-local_7_1], 0x757c7d51  ; [0x757c7d51:4]=-1
│          0x080489cf    c745e7607366.  mov dword [ebp - 0x19], 0x67667360  ; [0x67667360:4]=-1
│          0x080489d6    c745eb7e7366.  mov dword [ebp - 0x15], 0x7b66737e  ; [0x7b66737e:4]=-1
│          0x080489dd    c745ef7d7c61.  mov dword [ebp - 0x11], 0x33617c7d  ; [0x33617c7d:4]=-1
│          0x080489e4    c645f300       mov byte [ebp-local_3_1], 0
│          0x080489e8    50             push eax
│          0x080489e9    31c0           xor eax, eax
│      ┌─< 0x080489eb    7403           je 0x80489f0
│      │   0x080489ed    83c404         add esp, 4
│      └   ; JMP XREF from 0x080489eb (sym.decrypt)
│      └─> 0x080489f0    58             pop eax
│          0x080489f1    8d45e3         lea eax, [ebp-local_7_1]
│          0x080489f4    890424         mov dword [esp], eax
│          0x080489f7    e814feffff     call sym.imp.strlen ;sym.imp.strlen()
│          0x080489fc    8945dc         mov dword [ebp-local_9], eax
│          0x080489ff    c745d8000000.  mov dword [ebp-local_10], 0
│     ┌──< 0x08048a06    eb20           jmp 0x8048a28
│    ┌     ; JMP XREF from 0x08048a2e (sym.decrypt)
│    ┌───> 0x08048a08    8d55e3         lea edx, [ebp-local_7_1]
│    ││    0x08048a0b    8b45d8         mov eax, dword [ebp-local_10]
│    ││    0x08048a0e    01d0           add eax, edx
│    ││    0x08048a10    0fb600         movzx eax, byte [eax]
│    ││    0x08048a13    89c2           mov edx, eax
│    ││    0x08048a15    8b4508         mov eax, dword [ebp + 8]        ; [0x8:4]=0
│    ││    0x08048a18    31d0           xor eax, edx
│    ││    0x08048a1a    8d4de3         lea ecx, [ebp-local_7_1]
│    ││    0x08048a1d    8b55d8         mov edx, dword [ebp-local_10]
│    ││    0x08048a20    01ca           add edx, ecx
│    ││    0x08048a22    8802           mov byte [edx], al
│    ││    0x08048a24    8345d801       add dword [ebp-local_10], 1
│    │└    ; JMP XREF from 0x08048a06 (sym.decrypt)
│    │└──> 0x08048a28    8b45d8         mov eax, dword [ebp-local_10]
│    │     0x08048a2b    3b45dc         cmp eax, dword [ebp-local_9]
│    └───< 0x08048a2e    72d8           jb 0x8048a08
│          0x08048a30    c7442404038d.  mov dword [esp + 4], str.Congratulations_  ; [0x8048d03:4]=0x676e6f43  ; "Congratulations!" @ 0x8048d03
│          0x08048a38    8d45e3         lea eax, [ebp-local_7_1]
│          0x08048a3b    890424         mov dword [esp], eax
│          0x08048a3e    e82dfdffff     call sym.imp.strcmp             ; sub.strcmp_12_76c+0x4 ;sub.strcmp_12_76c() ; sym.imp.strcmp
│          0x08048a43    85c0           test eax, eax
│   ┌────< 0x08048a45    750e           jne 0x8048a55
│   │      0x08048a47    c70424148d04.  mov dword [esp], str._bin_sh    ; [0x8048d14:4]=0x6e69622f  ; "/bin/sh" @ 0x8048d14
│   │      0x08048a4e    e88dfdffff     call sym.imp.system ;sym.imp.system()
│  ┌─────< 0x08048a53    eb0c           jmp 0x8048a61
│  │└      ; JMP XREF from 0x08048a45 (sym.decrypt)
│  │└────> 0x08048a55    c704241c8d04.  mov dword [esp], str._nInvalid_Password_  ; [0x8048d1c:4]=0x766e490a  ; str._nInvalid_Password_
│  │       0x08048a5c    e86ffdffff     call sym.imp.puts ;sym.imp.puts()
│  └       ; JMP XREF from 0x08048a53 (sym.decrypt)
│  └─────> 0x08048a61    8b45f4         mov eax, dword [ebp-local_3]
│          0x08048a64    653305140000.  xor eax, dword gs:[0x14]
│          0x08048a6b    7405           je 0x8048a72
│          0x08048a6d    e84efdffff     call sym.imp.__stack_chk_fail ;sym.imp.__stack_chk_fail()
│          ; JMP XREF from 0x08048a6b (sym.decrypt)
│          0x08048a72    c9             leave
╘          0x08048a73    c3             ret

如我们所见, this funcstions takes one arguments witch can be accessed with ebp+0x8 ( ; arg int arg_2 @ ebp+0x8) (传进来的差)
在第21-24行 有4个dword 和 1 个 byte 在 栈上 ,look like this

│          0x080489c8    c745e3517d7c.  mov dword [ebp-local_7_1], 0x757c7d51  ; [0x757c7d51:4]=-1
│          0x080489cf    c745e7607366.  mov dword [ebp - 0x19], 0x67667360  ; [0x67667360:4]=-1
│          0x080489d6    c745eb7e7366.  mov dword [ebp - 0x15], 0x7b66737e  ; [0x7b66737e:4]=-1
│          0x080489dd    c745ef7d7c61.  mov dword [ebp - 0x11], 0x33617c7d  ; [0x33617c7d:4]=-1
│          0x080489e4    c645f300       mov byte [ebp-local_3_1], 0

这些指令被执行后,栈中的存放的值如下:
ebp-0x1d( ; var int local_7_1 @ ebp-0x1d) :517d7c75607366677e73667b7d7c613300
结合后面指令的strlen来看, 这段值看起来像是个字符串;

[0x08048850]> !python -c 'print("517d7c75607366677e73667b7d7c613300".decode("hex"))'
Q}|u`sfg~sf{}|a3

continue reversing the function decrypt,The function strlen is called, The pass argument is a reference the string we just found [ebp-0x1d] (Q}|u`sfg~sf{}|a3)

│          0x080489f1    8d45e3         lea eax, [ebp-local_7_1]
│          0x080489f4    890424         mov dword [esp], eax
│          0x080489f7    e814feffff     call sym.imp.strlen ;sym.imp.strlen()

the return length of the string stored in eax is move to local variable [ebp-local_9], another local variable [ebp-local_10] is initialized with 0;

│          0x080489fc    8945dc         mov dword [ebp-local_9], eax
│          0x080489ff    c745d8000000.  mov dword [ebp-local_10], 0

continue , The disassemble look like is a loop-condition

│    ┌───> 0x08048a08    8d55e3         lea edx, [ebp-local_7_1]
│    ││    0x08048a0b    8b45d8         mov eax, dword [ebp-local_10]
│    ││    0x08048a0e    01d0           add eax, edx
│    ││    0x08048a10    0fb600         movzx eax, byte [eax]
│    ││    0x08048a13    89c2           mov edx, eax
│    ││    0x08048a15    8b4508         mov eax, dword [ebp + 8]        ; [0x8:4]=0
│    ││    0x08048a18    31d0           xor eax, edx
│    ││    0x08048a1a    8d4de3         lea ecx, [ebp-local_7_1]
│    ││    0x08048a1d    8b55d8         mov edx, dword [ebp-local_10]
│    ││    0x08048a20    01ca           add edx, ecx
│    ││    0x08048a22    8802           mov byte [edx], al
│    ││    0x08048a24    8345d801       add dword [ebp-local_10], 1
│    │└    ; JMP XREF from 0x08048a06 (sym.decrypt)
│    │└──> 0x08048a28    8b45d8         mov eax, dword [ebp-local_10]
│    │     0x08048a2b    3b45dc         cmp eax, dword [ebp-local_9]
│    └───< 0x08048a2e    72d8           jb 0x8048a08

The loop-body load the baseaddress of the string(line 40) and adds the loop-counter(line 41)。
after the execution of the 44 line, edx stored a single chr through a loop-counter; The chr is xor with value stored at [ebp + 8](line 46)
The XORed chr is writte back to the string ,At last the loop-counter is increment;

The decrypt function look like this :

void decrypt(int v){
	char str[] = "Q}|u`sfg~sf{}|a3";
	int len = strlen(str);
	for(i=0; i < len; i++){
		str[i] = str[i] ^ v;
	}
}

After the loop there is call the strcmp function

 
│          0x08048a30    c7442404038d.  mov dword [esp + 4], str.Congratulations_  ; [0x8048d03:4]=0x676e6f43  ; "Congratulations!" @ 0x8048d03
│          0x08048a38    8d45e3         lea eax, [ebp-local_7_1]
│          0x08048a3b    890424         mov dword [esp], eax
│          0x08048a3e    e82dfdffff     call sym.imp.strcmp             ; sub.strcmp_12_76c+0x4 ;sub.strcmp_12_76c() ; sym.imp.strcmp

The first string being compared is “Congratulations!”, The second string stored at [ebp-local_7_1] is the string has just been Xored in the loop;

│          0x08048a43    85c0           test eax, eax
│   ┌────< 0x08048a45    750e           jne 0x8048a55
│   │      0x08048a47    c70424148d04.  mov dword [esp], str._bin_sh    ; [0x8048d14:4]=0x6e69622f  ; "/bin/sh" @ 0x8048d14
│   │      0x08048a4e    e88dfdffff     call sym.imp.system ;sym.imp.system()
│  ┌─────< 0x08048a53    eb0c           jmp 0x8048a61
│  │└      ; JMP XREF from 0x08048a45 (sym.decrypt)
│  │└────> 0x08048a55    c704241c8d04.  mov dword [esp], str._nInvalid_Password_  ; [0x8048d1c:4]=0x766e490a  ; str._nInvalid_Password_

If the result not equal, Is printed ‘ Invalid Password!’ and the functions returns; If euqal call the /bin/sh; We can complete the decrypt function:

void decrypt(int v){
// str contains "Q}|u`sfg~sf{}|a3" XORed with v

if(strcmp("Congratulations!", str) == 0){
	system("/bin/sh");
}
else{
	puts("Invalid Password!");
}
}

总结下来,我们必须找到一个值 可以将 “Q}|u`sfg~sf{}|a3” 转换成 “Congratulations!”, 直接将两个值进行异或,就可以拿到结果了;

[0x08048856]> !python
Python 2.7.6 (default, Mar 22 2014, 22:59:38)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
  s1 = "Q}|u`sfg~sf{}|a3"
  s2 = "Congratulations!"
  [ord(a) ^ ord(b) for a,b in zip(s1, s2)]
[18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18]

结果就是 18 = 0x12 ;
正如文章一开头讲的那样,传进 decrypt 来的值 是 userinput 和 constant(0x1337d00d) 的差;

0x1337d00d – 0x12 = 0x1337cffb = 322424827

lab1B@warzone:/levels/lab01$ ./lab1B
.---------------------------.
|-- RPISEC - CrackMe v2.0 --|
'---------------------------'

Password: 322424827
$ whoami
lab1A

发表评论

电子邮件地址不会被公开。 必填项已用*标注