pwnable.tw新手向write up(一)
图片出处:http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html
更细致的内容可以参考链接的内容,这里只简单概括一下._start函数才是程序的入口点,他会调用libc_start_main函数,这里可以先看一下libc_start_main函数的原型:
根据64位程序程序通过寄存器来保存前六个参数的特性,我们可以得出以下结论:
也就是说,我们可以在_start函数中得到上述三个函数的地址.
刚刚我们知道了__libc_csu_fini函数在main函数返回之后执行,现在看看具体代码:
在.text:0000000000402988这个地方有一个call指令,结合前面的代码可以知道rbp保存的是fini_array的值,所以这里会调用fini_array中的函数.所以只要修改了fini_array的数值,我们就可以劫持eip.看一下fini_array的代码:
这里保存了两个函数指针,分别是fini_array[0]和fini_array[1],观察libc_csu_fini中的汇编代码我们可以得知这俩函数指针是反向执行的,先执行fini_array[1],再执行fini_array[0].如果我们将fini_array[0]覆盖为libc_csu_fini的地址,再将fini_array[1]覆盖为任意一个地址A,那么程序就会循环执行A地址的代码,直到fini_array[0]覆盖为其他值.
其次,在.text:0000000000402968可以修改rbp为fini_array的首地址,配合leave;ret可以把栈迁移到fini_array
因为没有符号,所以最开始连main函数都找不到,我们先进到start函数,根据最开始讲的内容,我们可以很轻松地得到以下内容:
__libc_csu_fini地址后边会用到,我们先跳转到main函数
改了几个函数的名字,加强了一点可读性,逻辑很简单,输入地址和内容,就可以对目标地址进行更改,是软件给予我们的任意地址写,但是长度只有0x18个字节,并不足以进行利用,这个时候就用到了前置知识的第二点,我们可以劫持fini_array来进行多次的任意地址写,从而getshell.
利用方法
劫持fini_array[1]为main函数地址,fini_array[0]为__libc_csu_fini,将长度为18的任意地址写升级为长度无限制的任意地址写
在0x4b40f0+0x10地址处构造ROP chain
构造完ROP chain之后,将fini_array[0]改为'leave;ret',将fini_array[1]改为'ret'.这样,在执行完main函数(即fini_array[1])之后,程序去执行位于fini_array[0]的'leave;ret',执行完之后,rip=fini_array[1],rsp=0x4b40f0+0x10.此时,fini_array[1]存放着我们放入的ret,这样,eip的值就被修改为了0x4b40f0+0x10.这也就是上一步我们将ROP链放在这个地址的原因.
至此,程序就会一步一步执行我们的ROP链,ROP链就很简单了,大致如下:
exp
博客有我的联系方式,欢迎大家来玩,地址:https://www.0x2l.cn
//libc_start_main函数原型
__libc_start_main(main,argc,argv&env,init,fini,rtld_fini)
rdi <- main
rcx <- __libc_csu_init //在main函数前执行
r8 <- __libc_csu_fini //在main函数后执行
.text:0000000000402960 __libc_csu_fini proc near ; DATA XREF: start+Fo
.text:0000000000402960 ; __unwind {
.text:0000000000402960 push rbp
.text:0000000000402961 lea rax, unk_4B4100
.text:0000000000402968 lea rbp, _fini_array_0
.text:000000000040296F push rbx
.text:0000000000402970 sub rax, rbp
.text:0000000000402973 sub rsp, 8
.text:0000000000402977 sar rax, 3
.text:000000000040297B jz short loc_402996
.text:000000000040297D lea rbx, [rax-1]
.text:0000000000402981 nop dword ptr [rax+00000000h]
.text:0000000000402988
.text:0000000000402988 loc_402988: ; CODE XREF: __libc_csu_fini+34j
.text:0000000000402988 call qword ptr [rbp+rbx*8+0]
.text:000000000040298C sub rbx, 1
.text:0000000000402990 cmp rbx, 0FFFFFFFFFFFFFFFFh
.text:0000000000402994 jnz short loc_402988
.text:0000000000402996
.text:0000000000402996 loc_402996: ; CODE XREF: __libc_csu_fini+1Bj
.text:0000000000402996 add rsp, 8
.text:000000000040299A pop rbx
.text:000000000040299B pop rbp
.text:000000000040299C jmp sub_48E32C
.text:000000000040299C ; } // starts at 402960
.text:000000000040299C __libc_csu_fini endp
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2020-8-12 20:23
被0x2l编辑
,原因: 修改