Introduction
It is not me that solve the challenge during the competition. Just take it as a warm-up for coming CTF.
Analysis
For those who are not familiar with GO binary, please read this post [1] first.
The binary will take a buffer[32] as its input. It only accepts 0-9a-fA-F in buffer. Then the 32-byte buffer will be translated into str[16] through combining every two bytes into one hexadecimal value.
For example, buffer[2] = “31” will be translated into str[1] = “\x31”.
Then we come to the verification process in the binary as below:
After some effort, we can get the verification logic as below:
str[1] ^ 3 = 0xae; str[0] & 0xfe = 0x10; str[3] | 3 = 0x1b; str[2] ^ 0xde = 0xae; str[5] ^ 0xaf = 0xfe; str[7] ^ 0x92 = 0xbe; str[4] | 0x3a = 0xfa; str[6] & 0x19 = 0x10; (str[8] | 0x3) ^ 0xde = 0x21; str[9] ^ 0x7f = 0xad; (str[10] ^ 0x32) | 0x8a = 0xdb; str[11] ^ str[10] ^ 0x13 = 0xba; str[12] ^ 0x30 = 0xdf; str[13] ^ 0x3a = 0xef; str[14] ^ str[13] = 0x32; str[15] ^ str[1] ^ str[2] = 0x25;
Exploit
from pwn import * DEBUG = int(sys.argv[1]); if(DEBUG == 0): r = remote("1.2.3.4", 2333); elif(DEBUG == 1): r = process("./crackme.go"); elif(DEBUG == 2): r = process("./crackme.go"); gdb.attach(r, '''source script'''); def halt(): while(True): log.info(r.recvline()); def exploit(): r.recvuntil(":"); payload = ""; payload += "10AD7018"; payload += "f051102c"; payload += "ffd263ca"; payload += "efd5e7f8"; log.info(len(payload)); r.sendline(payload); halt(); exploit();
Reference
[1] https://rednaga.io/2016/09/21/reversing_go_binaries_like_a_pro/