Automne's Shadow.

XMAS CTF 2018 ChristmasGame WriteUp

2018/12/23 Share

Misc

automne

连上之后可以发现首先需要我们过md5校验,校验完成后给出一个游戏,通过搜索下图标记的关键词发现这是博弈论里的一个Nim Game

automne

该游戏其实是有必胜策略的

automne

因此只需要关注所有堆里面的当前石子个数的异或是否为0,当异或值为0时,留下的局面为必胜。

使用pwntools进行连接,最终的python脚本为:

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

from pwn import *

import hashlib
import random
import string
import sys

CHARS = string.letters + string.digits

def Verifymd5(substr, str_len, start=0, size=20):
global CHARS
flag = 1
while flag == 1:
rnds = ''.join(random.choice(CHARS) for _ in range(size))
md5 = hashlib.md5(rnds)
if md5.hexdigest()[start: start+str_len] == substr:
flag = 0
return rnds

def xxor(l):
r = 0
for i in l:
r ^= i
return r


if __name__ == '__main__':
p = remote('199.247.6.180',14002)
s1 = p.recvline_contains('md5')
substr = s1[-6:-1]
str_len = len(substr)
s2 = Verifymd5(substr, str_len, 0, 20)
print s2
p.sendline(s2)

for i in xrange(100):
while 1:
try:
print p.recvline()
p.recvuntil('the game: ') #handle the exception using try except
r = p.recvline()
print r
r = r.lstrip('[')
r = r[0:-2]
r = map(int, r.strip().split(', '))
#print r
xor = 0
for j in xrange(15):
#print r[j]
xor ^= r[j]
print "The XOR of the piles: %d" % xor
if (xor == 0):
break
else:
for mx in xrange(15):
for d in xrange(r[mx] + 1):
l = list(r)
l[mx] -= d
if (xxor(l) == 0):
q = [d, mx]
break
print "I choose Pile: %d" % q[1]
print "I choose Quantity: %d" % q[0]
p.sendline("%d" % q[1])
#p.interactive()
p.sendline("%d" % q[0])
r[q[1]] -= q[0]
except:
print p.recvall()
break
else:
break

运行脚本即可得到flag

automne

CATALOG