• 欢迎光临~

# 题面

``````from src.common import *
from src.pow import NcPowser
from src.part1 import part1_, part1
from src.part2 import part2_, part2
from src.part3 import part3_, part3

def main():
part1_()
input("Press enter to continue...")
for i in range(2, 18):
part1(i)
part2_()
input("Press enter to continue...")
for i in range(2, 6):
part2(6)
part3_()
input("Press enter to continue...")
part3()

if __name__ == '__main__':
if (SHOULD_USE_POW):
nc = NcPowser()
if nc.pow():
main()
else:
exit(0)
else:
main()

``````
``````from time import time
import itertools
import random
from Crypto.Util.number import bytes_to_long
from progress.bar import ChargingBar
from time import *
import os

SHOULD_USE_POW = True
SHOULD_USE_ANNOYING_ANIMATIONS = True

intro_dictionary = "AB"
mid_dictionary = "ABCD"

def brrr_the_strings(strings):
print('PRINTING...')
for i in range(len(strings)):
print(strings[i])
print('DONE PRINTING')
``````
``````from src.common import *

def part1_():
print("Hi, this is my game :)")
print("I will give you some sTrInGs, and you will have to tell me, which one is missing, seems easy, right? :D")
print("Let's try it out!")

def part1(l):
if (SHOULD_USE_ANNOYING_ANIMATIONS):
sleep(0.1)
strings = ["".join(x)
for x in itertools.product(intro_dictionary, repeat=l)]
indexToRemove = bytes_to_long(os.urandom(32)) % len(strings)
removedString = strings[indexToRemove]
strings.remove(removedString)
random.shuffle(strings)
brrr_the_strings(strings)
print("Which one is missing?")
guess = input("> ")
if guess == removedString:
print("Correct!")
else:
print("Wrong!!!!! Cmon, you can do it!")
exit(0)
``````
``````from src.common import *

def part2_():
print("You are doing great! Now, let's try something harder!")
print("I will give you AGAIN some StRiNgS, and you will have to tell me, which one is missing, seems still doable, right? :D")
print("But I need you to hurry this time, so you will have to guess the missing string in 5 seconds.")
print("Let's try it out!")

def part2(l):
if (SHOULD_USE_ANNOYING_ANIMATIONS):
sleep(0.1)
strings = ["".join(x) for x in itertools.product(mid_dictionary, repeat=l)]
indexToRemove = bytes_to_long(os.urandom(32)) % len(strings)
removedString = strings[indexToRemove]
strings.remove(removedString)
random.shuffle(strings)
brrr_the_strings(strings)
print("Which one is missing?")
guess = input("> ")
if guess == removedString:
print("Correct!")
else:
print("Wrong!!!!! Cmon, you can do it!")
exit(0)
``````
``````from src.common import *
from flag import flag

assert(len(flag) == 2**(2**2))

def part3_():
print("Ok. This is kinda spooky. This time I will show you that I know everything, and you will have to prove me wrong in order to get the flag.")

def part3():
real_flag = flag[5:][:-1]
if (SHOULD_USE_ANNOYING_ANIMATIONS):
sleep(0.1)
flags = ["".join(x) for x in itertools.permutations(real_flag)]
flags.remove(real_flag)
random.shuffle(flags)
brrr_the_strings(flags)
print("If you are so smart, then you should be able to give the flag in 15 seconds!")
start = time()
guess = input("> ")
end = time()
if guess == flag and end - start <= 15:
print("Correct! Here is your flag: " + flag)
else:
print("Well, at least I can rest. GL")
exit(0)

``````
``````import hashlib
import secrets

class NcPowser:
def __init__(self, difficulty=20, prefix_length=17):
self.difficulty = difficulty
self.prefix_length = prefix_length

def get_challenge(self):
prefix = secrets.token_hex(self.prefix_length)
rest = secrets.token_hex(self.difficulty - self.prefix_length)
return prefix, rest

def pow(self):
prefix, rest = self.get_challenge()
print(
f"sha256("{prefix} + {'?'*(len(rest))}") == "{hashlib.sha256((prefix + rest).encode()).hexdigest()}"")
if hashlib.sha256((prefix + answer).encode()).hexdigest() == hashlib.sha256((prefix + rest).encode()).hexdigest():
return True
else:
return False

def solve_pow(self, prefix, result, unknown_count):
from itertools import product
possibilities = product("0123456789abcdef", repeat=unknown_count)
for ans in possibilities:
if hashlib.sha256((prefix + answer).encode()).hexdigest() == result:

if __name__ == '__main__':
print("Solving PoW...")
nc = NcPowser()
# sha256("dd32ded3ce6a9c864b5b2a0c364003b409 + ??????") == "e46f470c74eff9629dd828c0bfada1ff87bbeede19cdcd3fbcac8684a07b1384"
prefix = "dd32ded3ce6a9c864b5b2a0c364003b409"
unknown_count = 6
solution = nc.solve_pow(prefix, result, unknown_count)
print(f"Solution: {solution}")
exit(0)

``````

# 审计代码：

## main.py

``````def main():
part1_()
input("Press enter to continue...")
for i in range(2, 18):
part1(i)
part2_()
input("Press enter to continue...")
for i in range(2, 6):
part2(6)
part3_()
input("Press enter to continue...")
part3()
``````

## common.py

``````intro_dictionary = "AB"
mid_dictionary = "ABCD"
``````

## pow.py

``````sha256("dd32ded3ce6a9c864b5b2a0c364003b409 + ??????") =="e46f470c74eff9629dd828c0bfada1ff87bbeede19cdcd3fbcac8684a07b1384"
prefix = "dd32ded3ce6a9c864b5b2a0c364003b409"
``````

### EXP

``````p = remote("guess_what.ctf.knping.pl",20000)
str=p.recvuntil(b'> ')
key=str[8:-84].decode()
h=str[58:-4].decode()
print(key)
print(h)
for i in range(16777216):
tmp = key + hex(i).zfill(6)[2:8]
if hashlib.sha256(tmp.encode('utf-8')).hexdigest() == h:
print(tmp)
break
print(tmp[-6:])
p.sendline(tmp[-6:])
p.recvuntil(b'Press enter to continue...')
p.sendline()
``````

## part1.py

``````strings = ["".join(x) for x in itertools.product(intro_dictionary, repeat=l)]
``````

``````removedString = strings[indexToRemove]
strings.remove(removedString)
random.shuffle(strings)
``````

### EXP

EXP在分析完题目后就非常好写了，只需要讲排列组合列出来对生成的字符串进行比对然后 (sendline) 即可。

``````for l in range(2,18):
p.recvuntil(b'PRINTING...n')
keyword=p.recvuntil(b'DONE PRINTINGn',drop=True)
keyword=keyword[:-1].decode()
keywordlist=keyword.split("n")
#print(keyword)
#print(keywordlist)
for e in itertools.product('AB', repeat=len(keywordlist[0])):
s = ''.join(e)
if s not in keywordlist:
p.sendline(s)
p.recvuntil(b'Press enter to continue...')
p.sendline()
``````

## part2.py

``````strings = ["".join(x) for x in itertools.product(mid_dictionary, repeat=l)]
``````

### EXP

``````for l in range(2,6):
p.recvuntil(b'PRINTING...n')
keyword=p.recvuntil(b'DONE PRINTINGn',drop=True)
keyword=keyword[:-1].decode()
keywordlist=keyword.split("n")
#print(keyword)
#print(keywordlist)
for e in itertools.product('ABCD', repeat=len(keywordlist[0])):
s = ''.join(e)
if s not in keywordlist:
p.sendline(s)
p.recvuntil(b'Press enter to continue...')
p.sendline()
``````

## part3.py

``````assert(len(flag) == 2**(2**2))

real_flag = flag[5:][:-1]

flags = ["".join(x) for x in itertools.permutations(real_flag)]

flags.remove(real_flag)
random.shuffle(flags)
brrr_the_strings(flags)

if guess == flag and end- start <= 15:
``````

### EXP

``````p.recvuntil(b'PRINTING...n')
keyword=p.recvuntil(b'DONE PRINTINGn',drop=True)
keyword=keyword[:-1].decode()
keywordlist=keyword.split("n")
flags = ["".join(x) for x in itertools.permutations('i8a9eF2d4n')]
keywordlist.sort()
flags.sort()
p.recvuntil(b'> n')
for i in range(0,10**10):
if keywordlist[i] != flags[i]:
p.sendline("ping{"+flags[i]+"}")
break
p.interactive()
``````

# 完整EXP

``````import itertools
from pwn import *
import hashlib
context.log_level='debug'
p = remote("guess_what.ctf.knping.pl",20000)
str=p.recvuntil(b'> ')
key=str[8:-84].decode()
h=str[58:-4].decode()
print(key)
print(h)
for i in range(16777216):
tmp = key + hex(i).zfill(6)[2:8]
if hashlib.sha256(tmp.encode('utf-8')).hexdigest() == h:
print(tmp)
break
print(tmp[-6:])
p.sendline(tmp[-6:])
p.recvuntil(b'Press enter to continue...')
p.sendline()
#part1
for l in range(2,18):
p.recvuntil(b'PRINTING...n')
keyword=p.recvuntil(b'DONE PRINTINGn',drop=True)
keyword=keyword[:-1].decode()
keywordlist=keyword.split("n")
#print(keyword)
#print(keywordlist)
for e in itertools.product('AB', repeat=len(keywordlist[0])):
s = ''.join(e)
if s not in keywordlist:
p.sendline(s)
p.recvuntil(b'Press enter to continue...')
p.sendline()
#part2
for l in range(2,6):
p.recvuntil(b'PRINTING...n')
keyword=p.recvuntil(b'DONE PRINTINGn',drop=True)
keyword=keyword[:-1].decode()
keywordlist=keyword.split("n")
#print(keyword)
#print(keywordlist)
for e in itertools.product('ABCD', repeat=len(keywordlist[0])):
s = ''.join(e)
if s not in keywordlist:
p.sendline(s)
p.recvuntil(b'Press enter to continue...')
p.sendline()
#getflag
p.recvuntil(b'PRINTING...n')
keyword=p.recvuntil(b'DONE PRINTINGn',drop=True)
keyword=keyword[:-1].decode()
keywordlist=keyword.split("n")
flags = ["".join(x) for x in itertools.permutations('i8a9eF2d4n')]
keywordlist.sort()
flags.sort()
p.recvuntil(b'> n')
for i in range(0,10**10):
if keywordlist[i] != flags[i]:
p.sendline("ping{"+flags[i]+"}")
break
p.interactive()
``````