Write operation allows us to write to the temporary file created and read operation prints out the content of the file as md5/sha1 hashed or aes256 encrypted using the sha256 hash of the flag as the key.

There is a secret operation which is not included in the menu. It simply copies the flag to our temporary file.

The write operation uses xxd to convert hexadecimal string to bytes. However, this operation overwrites the file from the start of it instead of overwriting the whole file.

1

2

3

4

$printf'414243444546'|xxd-r-ps-test&&cat test

ABCDEF

$printf'6162'|xxd-r-ps-test&&cat test

abCDEF

We can use this to brute force the flag one character at a time. In order to find the length of the flag, we will copy the flag into the file first, Then, we will overwrite its characters one by one until, the hash of the file matches the hash of the same number of characters.

After finding the length of the flag, we will simply overwrite all characters of it except the last one and read its hash. Then, we will just brute force that character and move on to the next character from the end of the string. We will repeat this until we get all the characters.

Here is the script to solve this challenge:

solve.py

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

#!/usr/bin/env python2

#-*- coding: utf-8 -*-

fromhashlibimportsha1

frompwn import*

fromstringimportprintable

context.log_level='error'

HOST='13.113.205.160'

PORT=21700

defchoose(r,option):

r.recvuntil('quit\n')

r.sendline(str(option))

defwrite(r,data):

choose(r,1)

r.recvline()

r.sendline(data.encode('hex'))

defread(r):

choose(r,2)

returnr.recvline().rstrip()

defsecret(r):

choose(r,1337)

deffind_length():

forlength inxrange(1,100):

s='A'*length

withremote(HOST,PORT)asr:

secret(r)

write(r,s)

ifread(r)==sha1(s).hexdigest():

returnlength

raiseException('Could not find the length!')

deffind_char(flag,i):

withremote(HOST,PORT)asr:

secret(r)

write(r,'A'*(i-1))

sha1_hash=read(r)

forcinprintable:

s='A'*(i-1)+c+flag

ifsha1_hash==sha1(s).hexdigest():

returnc

raiseException('Could not find char #{}!'.format(i))

defmain():

length=find_length()

print'Length: {}'.format(length)

flag=''

foriinxrange(length,0,-1):

flag=find_char(flag,i)+flag

print'Flag: {}'.format(flag)

if__name__=='__main__':

main()

Let’s run the script and get the flag.

1

2

3

$./solve.py

Length:32

Flag:hitcon{xxd?XDD!ed45dc4df7d0b79}

The flag is hitcon{xxd?XDD!ed45dc4df7d0b79}.

Umut Barış Öztunç

Security researcher who participates in Capture The Flag events, also the founder of BreakPoint CTF team.