Hack.lu 2017 writeup

TO BE CONTINUE
这两天做了hacklu2017,随便写写,有空再补了。其实比较倒霉,6点比赛结束,6点02算出了LostKey的flag……手速还是不行啊,得多练……

Pwn

bit

40072b:4 - > loop
overwrite main ret instruction to long jump to start of main function input logic and reflip 40072b:4. Then write the shellcode to 0400741, and finally reflip 40072b:4 to get shellcode execute.

Rev

The Maya Society

13.0.0.0 on the home page is not a ip address, it’s 2012.12.21 in Maya calendar, just set the time to 2012.12.11 and run the program to get the flag.

Rusted from the Rain

Reverse and write script to solve.

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
import z3

ans_len = 28
y = z3.BitVecs(' '.join("a_%d"%i for i in xrange(ans_len)), 8)
x = [0]*ans_len
for i in range(ans_len):
x[i] = z3.ZeroExt(8,y[i])

s = z3.Solver()
s.add(x[13]==x[14])
s.add(x[18]==x[19])
s.add(x[5]==x[26])
s.add(x[23]==x[7])
s.add(x[9]==x[16])
s.add(x[9]==x[21])
s.add(x[8]==x[22])

s.add(x[27]-x[4]==2)
s.add(x[0] ==63+7)
s.add(x[1] ==63+0xd)
s.add(x[2] ==63+2)
s.add(x[3] ==63+8)

s.add(x[21] <= 0x60)
s.add(x[14] + x[18] == 0xD1)
s.add(x[14] - x[18] == 7)
s.add(x[10] == x[15])
s.add((~x[24])&0xff & x[17]== 0)
s.add(x[17] == 115)
s.add((~(x[10] ^ 0x73)) & 0xFF == 0xFF)
s.add(((2 * x[25])&0xff) % x[24] == 2)

v12 = (x[23] + x[25])&0xff
s.add((v12 - 99 * ((83 * v12 & 0x6000) >> 13))== 35)
s.add(3 * x[11] + 2 * x[12] + x[20] == 640)
s.add( x[6] - 35 * ((235 * x[6] & 0xE000) >> 13) == 6)
s.add(x[8] != 0)
s.add((((2 * x[6])&0xff) % x[8]) & 0xFF == x[14] )
res = [0x7fed,0xfb11,0xeabe,0x2631]

for i in range(4):
v17 = 0
v20 = 0
for j in range(7):
v20 = (v20 + x[i*7+j]) % 0xFF
v17 = (v20 + v17) % 0xFF
s.add(res[i] == (v17 | (v20 << 8)))

if s.check() == z3.sat:
m = s.model()
print m
flag = map(lambda sym: m[sym], y)
flag = map(lambda val: chr(int(str(val))), flag) # wtf
print len(flag)
print ''.join(flag)

LostKey

4 processes created by clone, shared memory. When the program init, some rops will be filled in each process’s stack, and the rops are the thing that check your flag.

anti-debug will be used in perior 3 processes, and generate the key to decode the input in thread 4.

So just track the right rops to get the algorithm. And write some scripts to calculate the flag.

Web,Rev

Triangle

Use chrome to decode the ARM binary code, we got two function, encode and test. Write a script to solve the problem.

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
import z3

x = [z3.BitVec(i, 8) for i in range(32)]
y = [0] * 32
s = z3.Solver()

a = "XYzaSAAX_PBssisodjsal_sSUVWZYYYb"
b = map(ord, a)

flag = 0
for i in range(32):
ch = x[i]
ch = z3.If(flag == 1, ch + (i & 3), ch)
temp = ch + 6
flag = temp & 1
y[i] = temp

for i in range(32):
ch = y[i] + 5
if i & 1:
ch = y[i] + 2
s.add(ch == b[i])

if s.check() == z3.sat:
m = s.model()
print m
flag = map(lambda sym: m[sym], x)
flag = map(lambda val: chr(int(str(val))), flag) # wtf
print ''.join(flag)

Misc, Web

DnSoSecure

source audit, download the source.zip
git log and checkout last branch

get private and public key for setting up DNSSEC server.

ref:https://www.digitalocean.com/community/tutorials/how-to-setup-dnssec-on-an-authoritative-bind-dns-server--2

named.conf.default-zone

1
2
3
4
5
zone "otherside.earth.flux"{
type master;
file "/etc/bind/master/otherside.earth.flux.db.signed";
allow-update { none; };
};

otherside.earth.flux.db

1
2
3
4
5
6
7
8
9
10
11
12
13
$TTL    3600
@ IN SOA ns1.otherside.earth.flux. root.otherside.earth.flux. (
2014072202; Serial
3600 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
;
@ IN A 127.0.0.1
@ IN NS ns1.earth.flux.
ns1 IN A 127.0.0.1
$INCLUDE Kotherside.earth.flux.+007+11537.key
$INCLUDE Kotherside.earth.flux.+007+26883.key

use this command to sign and gen RRSIG

1
dnssec-signzone -A -3 $(head -c 1000 /dev/random | sha1sum | cut -b 1-16) -N INCREMENT -o otherside.earth.flux. -t otherside.earth.flux.db

use rndc reload to reload bind9 config

CAUTION: The file name must be like this

1
2
Kotherside.earth.flux.+007+11537.key      Kotherside.earth.flux.+007+26883.key      dsset-otherside.earth.flux.  otherside.earth.flux.db.signed
Kotherside.earth.flux.+007+11537.private Kotherside.earth.flux.+007+26883.private otherside.earth.flux.db

same as zone name. It’s important.

sudo apt install rng-tools to speed up sign progress