This page looks best with JavaScript enabled

Flare-On 8 2021 Challenge 4 Solution - 04_myaquaticlife

Hosted by FireEye's FLARE team from 10 September - 22 October

 ·  ☕ 4 min read  ·  🌚 drome

Thanks drome for sharing his knowledge and skills! He completed all 10 challenges and this series of writeups is done by him :)

Details Links
Official Challenge Site https://flare-on.com/
Official Challenge Announcement https://www.fireeye.com/blog/threat-research/2021/08/announcing-the-eighth-annual-flare-on-challenge.html
Official Solutions https://www.mandiant.com/resources/flare-on-8-challenge-solutions
Official Challenge Binaries http://flare-on.com/files/Flare-On8_Challenges.zip

04_myaquaticlife

What would Flare-On do without a healthy amount of nostalgia for the abraisive simplicity of 1990’s UI design? Probably do more actual work and less writing fun challenges like this.
7-zip password: flare

The 7z gives an executable file myaquaticlife.exe with the following properties:

arch     x86
baddr    0x400000
binsz    2389687
bintype  pe
bits     32
canary   false
retguard false
class    PE32
cmp.csum 0x00253d02
compiled Wed Nov 14 08:27:56 2007
crypto   false
endian   little
havecode true
hdr.csum 0x00000000
laddr    0x0
lang     c
linenum  true
lsyms    true
machine  i386
nx       false
os       windows
overlay  true
cc       cdecl
pic      false
relocs   true
signed   false
sanitize false
static   false
stripped false
subsys   Windows GUI
va       true

The file seems to be UPX packed, so we save a copy of the original executable and run:

upx -d myaquaticlife.exe

Looking at some of the strings inside like http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.c and Flash Player installation, it seems that it is a Shockwave Flash program packaged into an executable. However, we couldn’t find any tools that could extract the original script, so we just have to look at the executable.

The game looks like this when run:

Aquatic animals on a blue background with 'What's your favourite aquatic animal?' in text

Every time we click on a fish, the following message appears on the IDA output

702C0000: loaded C:\Windows\SysWOW64\policymanager.dll
70250000: loaded C:\Windows\SysWOW64\msvcp110_win.dll
Unloaded C:\Windows\SysWOW64\msvcp110_win.dll
Unloaded C:\Windows\SysWOW64\policymanager.dll

The executable file is huge with many functions and has many C++ artifacts like virtual function tables that make it hard to analyze statically, so we debugged it in API Monitor to find any interesting API calls.

Debugging with API Monitor shows GetProcAddress calls

We find that every time we click a fish, the program would call GetProcAddress to get the address of SetFile and a (non-existent) function that looks something like flotsam:DFWEyEW or lagan:BAJkR, from the module at %temp%\MMBPlayer\fathom.dll.

We go to that folder at %temp%\MMBPlayer\, and find that other than that DLL, the program also drops the GIF files, and two HTML files that serve as the background.

Dropped DLL, GIF, and HTML files in temp folder

The index.html file renders the first page with all the fishes we see, and has the following code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="main">
    <img class="img1" src="bg.gif" width=1190 height=100>
    <a href="script:Script17"><p class="txt1">What's your favorite aquatic animal?</p></a>
    <a href="script:Script1"><img class="img2" src="1.gif" width=200></a>
    <a href="script:Script2"><img class="img3" src="2.gif" width=200></a>
    <a href="script:Script3"><img class="img4" src="3.gif" width=200></a>
    <a href="script:Script4"><img class="img5" src="4.gif" width=200></a>
    <a href="script:Script5"><img class="img6" src="5.gif" width=200></a>
    <a href="script:Script6"><img class="img7" src="6.gif" width=200></a>
    <a href="script:Script7"><img class="img8" src="7.gif" width=200></a>
    <a href="script:Script8"><img class="img9" src="8.gif" width=200></a>
    <a href="script:Script9"><img class="img10" src="9.gif" width=140></a>
    <a href="script:Script10"><img class="img11" src="10.gif" width=200></a>
    <a href="script:Script11"><img class="img12" src="11.gif" width=100></a>
    <a href="script:Script12"><img class="img13" src="12.gif" width=60></a>
    <a href="script:Script13"><img class="img14" src="13.gif" width=120></a>
    <a href="script:Script14"><img class="img15" src="14.gif" width=200></a>
    <a href="script:Script15"><img class="img16" src="15.gif" width=200></a>
    <a href="script:Script16"><img class="img17" src="16.gif" width=300></a>
    <img class="img18" src="banner.gif"><img class="img19" src="banner.gif">
    <img class="img20" src="bubbles.gif"><img class="img21" src="bubbles.gif">
</div>

The index2.html file renders the background page we get after clicking the center yellow text.

The text that gets sent for each fish clicked is as follows

1. derelict:MZZWP
2. lagan:BAJkR
3. flotsam:DFWEyEW
4. flotsam:PXopvM
5. derelict:LDNCVYU
6. derelict:yXQsGB
7. jetsam:newaui
8. lagan:QICMX
9. lagan:rOPFG
10.jetsam:HwdwAZ
11.jetsam:SLdkv
12.derelict:LSZvYSFHW
13.flotsam:BGgsuhn
14.derelict:LSZvYSFHW
15.derelict:RTYXAc
16.lagan:GTXI

We analyze the DLL and find that clicking on the center yellow text calls the PluginFunc19 export, and inside there is this code segment that looks suspicious

1
2
3
4
5
for ( i = 0; i < 31; ++i )
{
  v16[i] ^= v1[i % strlen(v1)];
  v16[i] -= v13[0][i % 0x11u];
}

Here, v1 is a string that contains all the flotsam texts after the colons concatenated together, so for example pressing fish 3 then fish 4 would result in it being DFWEyEWPXopvM, while v13[0] is the same thing but for the jetsam fish. v16 is some encrypted text.

After that it calculates the MD5 hash of the processed text then compares it against 6c5215b12a10e936f8de1e42083ba184, so we write a script to try the different permutations of the concatenated strings that form v1 and v13.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import hashlib
import itertools

enc_text = b'\x96%\xa4\xa9\xa3\x96\x9a\x90\x9f\xaf\xe58\xf9\x81\x9e\x16\xf9\xcb\xe4\xa4\x87\x8f\x8f\xba\xd2\x9d\xa7\xd1\xfc\xa3\xa8\x00'
flotsams = [b'DFWEyEW', b'PXopvM', b'BGgsuhn']
jetsams = [b'newaui', b'HwdwAZ', b'SLdkv']

def process(flotsam_key, jetsam_key):
    ans = []
    for i, b in enumerate(enc_text):
        ans.append(((b ^ flotsam_key[i % len(flotsam_key)]) - jetsam_key[i % 0x11]) % 0x100)
    return bytes(ans)[:31]

for flotsam_perm in itertools.permutations(flotsams):
    for jetsam_perm in itertools.permutations(jetsams):
        flotsam = b''.join(flotsam_perm)
        jetsam = b''.join(jetsam_perm)
        weird_bytes = process(flotsam, jetsam)
        if hashlib.md5(weird_bytes).hexdigest() == '6c5215b12a10e936f8de1e42083ba184':
            print(flotsam, jetsam)

This outputs b'PXopvMDFWEyEWBGgsuhn' b'SLdkvnewauiHwdwAZ'. This corresponds to fishes 4, 3, then 13 for flotsam, and fishes 11, 7, then 10 for jetsam.

We click the fishes in that order, and get the following screen:

Flag shown after fishes clicked in correct order

Flag

s1gn_my_gu357_b00k@flare-on.com
Share on