Tags: crypto 

Rating:

**This writeup proposes a method to craft payload in one request and get fmac. **

Please pay attention that,

1, The length of the cmd matters because padding string can be \t \r \x0b \x0c etc. Command with length of 16 is OK.

2, This writeup can be considered as a supplement to existing writeups.

We build 257 16-bytes blocks in total. The 2nd and 3rd blocks are padding of the whole blocks. The 1st block can be xored with the 257th block. The 4th - 128th blocks can be xored with 132th - 256th blocks. So we have 129th - 131th blocks left, which corresponds to keys used for 1st - 3rd blocks. Thus we can break the system and get the flag.

Code:
```
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('macsh.chal.pwning.xxx',64791))

block = 'a' * 16
print s.recv(1024)
while True:
cmd = raw_input()
cmd_padding = cmd + '\x00' * 15 + chr(len(cmd))
cmd_padding += chr(16 - len(cmd_padding) % 16) * (16 - len(cmd_padding) % 16)
block_padding = '\x00' * 14 + '\x10\x10'
block_padding += '\x10' * 16
data = 'tag ' + block + block_padding
for i in range(125):
data = data + block
data += cmd_padding
for i in range(126):
data = data + block
s.send('aa<|>'+data+'\n')
mac = s.recv(1024)[:32]
print mac
s.send(mac + '<|>'+ cmd +'\n')
print s.recv(4096)
```

Execution result:
```
|$|>
ls ././././././.
d3d002d1b2b915c0eaeb5131f47b0cba
__pycache__
flag.txt
fmac.py
macsh.py
.bashrc
.bash_logout
.profile
|$|>
cat ././flag.txt
55a751e406db7dc7f22916cbaccc19a4
PCTF{fmac_is_busted_use_PMAC_instead}
|$|>
```