Content
About
Executing shellcode is commonly achieved through APIs like VirtualAlloc, WriteProcessMemory, CreateProcess, and WinExec. Jeff White has compiled a list of APIs that seem to be capable of accepting a memory address for code execution, potentially making them susceptible to abuse.
One method from the list involves the abuse of UuidFromStringA and EnumSystemLocalesA, which, at least for me, is unheard of :).
This technique begins by allocating memory through HeapAlloc. It then utilizes UuidFromStringA to convert UUID strings into their binary format and employs EnumSystemLocalesA to execute the shellcode.
HeapAlloc UuidFromStringA EnumSystemLocalesA
UuidFromStringA
The UuidFromString function converts a string to a UUID.
1
2
3
4
RPC_STATUS UuidFromStringA(
RPC_CSTR StringUuid, // Pointer to a string representation of a UUID.
UUID *Uuid // Returns a pointer to a UUID in binary form.
);
EnumSystemLocalesA
Enumerates the locales that are either installed on or supported by an operating system.
1
2
3
4
BOOL EnumSystemLocalesA(
LOCALE_ENUMPROCA lpLocaleEnumProc, // Pointer to an application-defined callback function.
DWORD dwFlags // Flags specifying the locale identifiers to enumerate.
);
Let’s attempt the Malwy challenge from D-CTF, which involves the utilization of this technique.
Challenge
Challenge link
Author : T3jv1l
Description
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
Hello friends. We are a well-known group of hackers who have created a dangerous malware. We ask that you send us the BTC to the Twitter address displayed on the screen.
Malicious activity: "e983c933-e8ad-ffff-ffff-c05e81760efe"
"83f58225-fcee-f4e2-27ce-192c8a0176c4"
"c4f5972c-4137-8409-ceae-f4f975539e7e"
"8b092db8-aede-cdb4-b13d-f706a724530a"
"9909451f-01da-b009-c2ae-d6dd8624687e"
"af093db4-24de-1669-ca6c-09c175246cc4"
"09421401-a152-8142-f9e4-4df8ffe26901"
"dda659c5-c48b-af09-da24-69937529c97e"
"1e8339a4-2175-f409-16ac-c6d1e2444147"
"7c560cf6-ac1b-9d40-706b-8c19accd1d0a"
"b00bda01-9efa-2dfc-1c56-05e9da776a7b"
"7c7dda01-2dbb-99ea-9205-c39dcd17ac91"
"90f15096-158c-7d59-a201-887c18737da0"
"a540acfa-8d45-b820-42a2-9ed1accddd0a"
"adeada01-05de-9da2-ba66-d6b3cffe0aa9"
"160b21da-5896-d5da-de4d-b4c4c71ceac1"
"9db612cd-479c-c3e4-961d-b7c6cb4de796"
"c2ea44cc-119f-9db5-9c1c-b1919640e0cd"
"c7e04d9a-1dc9-c6ea-c743-b29d9c40e6c6"
"90b64796-4dc6-cdba-cd16-eacc9841ba9d"
"cdbb12c9-1496-c4b2-9c4d-c1a1b85eb33c"
"b0a66976-c477-27b3-ac76-d3a701f5b335"
"fdd7daae-0000-0000-0000-000000000000"
Flag format: CTF{sha256}
Walkthrough
When opening this executable in DiE, it reveals that it is a PE32 file containing numerous UUIDs within its strings. Upon analyzing it in IDA, we can observe that it employs the technique mentioned earlier.
I attempted to run the file, and it produced a MessageBox along with printing some hexadecimal data.
The hexadecimal data printed is nothing but the shellcode generated by the UUIDs present in the binary.
To verify this, I used a Python script to generate the shellcode from the UUIDs, allowing us to analyze it using scdbg.
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
from uuid import UUID
a = ["1fbad5db-74d7-d9b5-7424-f45f33c9b14c",
"31fcef83-1557-5703-15fd-22ad5e9a143a",
"11976885-e777-5ce9-1c8c-7b6f56e47704",
"5c03141e-afd7-416d-6c99-a9ce6a903a89",
"cb428b8b-a0ec-28d1-c93d-6c0d9a154715",
"af1c7f9d-f485-1079-b7e1-9d64fe7e550e",
"efa76e01-ae33-a334-b0ee-b1bb792134c5",
"feb356be-8c3c-7414-5c47-3e529fbcd911",
"7cad0993-8cb0-0b5a-cc05-9de4445dbae8",
"18709e37-f491-fcfc-6836-967024b88bdf",
"1fac5b51-ea5e-e416-1a92-40062fed6de3",
"14031982-26dd-ae95-2ab0-ca5c0b017bae",
"b81faf79-dc08-4aba-c3f9-cdf707f744e1",
"ea02f81e-c417-49fd-8f6a-b01157766f38",
"4390d9b0-8dbf-9c36-606d-af9823396910",
"7629497f-c07b-1e31-dbf2-95ffb384e493",
"38470062-ba56-e02f-ec55-90882ceb840b",
"e241b845-56f1-9eef-d786-872c51b623b9",
"5aa25381-faaa-f41a-5994-7a62ff101333",
"f291ad90-c5a7-d11a-1b5c-4328b60cd71a",
"ad074f64-ff48-9b57-4000-000000000000"]
file = open("encrypt.bin", "wb")
for i in a:
file.write(UUID(i).bytes_le)
file.close()
The script wrote the shellcode into an “encrypt.bin” file. Now, when launching the shellcode using scdbg, it reveals the same MessageBox call with the identical arguments that were generated when running the original binary.
To decrypt the data, we have been given UUIDs in the description of the challenge. Using these UUIDs, we can generate a shellcode.
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
from uuid import UUID
a = ["e983c933-e8ad-ffff-ffff-c05e81760efe",
"83f58225-fcee-f4e2-27ce-192c8a0176c4",
"c4f5972c-4137-8409-ceae-f4f975539e7e",
"8b092db8-aede-cdb4-b13d-f706a724530a",
"9909451f-01da-b009-c2ae-d6dd8624687e",
"af093db4-24de-1669-ca6c-09c175246cc4",
"09421401-a152-8142-f9e4-4df8ffe26901",
"dda659c5-c48b-af09-da24-69937529c97e",
"1e8339a4-2175-f409-16ac-c6d1e2444147",
"7c560cf6-ac1b-9d40-706b-8c19accd1d0a",
"b00bda01-9efa-2dfc-1c56-05e9da776a7b",
"7c7dda01-2dbb-99ea-9205-c39dcd17ac91",
"90f15096-158c-7d59-a201-887c18737da0",
"a540acfa-8d45-b820-42a2-9ed1accddd0a",
"adeada01-05de-9da2-ba66-d6b3cffe0aa9",
"160b21da-5896-d5da-de4d-b4c4c71ceac1",
"9db612cd-479c-c3e4-961d-b7c6cb4de796",
"c2ea44cc-119f-9db5-9c1c-b1919640e0cd",
"c7e04d9a-1dc9-c6ea-c743-b29d9c40e6c6",
"90b64796-4dc6-cdba-cd16-eacc9841ba9d",
"cdbb12c9-1496-c4b2-9c4d-c1a1b85eb33c",
"b0a66976-c477-27b3-ac76-d3a701f5b335",
"fdd7daae-0000-0000-0000-000000000000"]
file = open("./decrypt.bin", "wb")
for i in a:
file.write(UUID(i).bytes_le)
file.close()
The script generated a file named “decrypt.bin” containing the shellcode. Launching it with scdbg reveals a call to MessageBox, with the flag as an argument.
Flag : CTF{101b77989fd88833b4e8bed339f0b278eb8db93d7a47ec2a8535bbf643746199}
References
- https://research.nccgroup.com/2021/01/23/rift-analysing-a-lazarus-shellcode-execution-method/
- http://ropgadget.com/posts/abusing_win_functions.html