Post

3108 CTF: Warkah Untuk Perwira Writeup

Welcome to my write-up for the 3108 CTF: Warkah Untuk Perwira organized by BahteraSiber. This CTF presented numerous smaller challenges, but I will be focusing on providing in-depth writeups of the main challenges that highlight key ethical hacking methodologies.

Tugasan Utama

This main task consists of 3 parts which are Tugasan I, Tugasan II & Tugasan III.

Tugasan I: Seruan Perwira

1727422997291

It seems like a local hacker group called ITSLOKI has been threatening Malaysia’s cybersecurity landscape, their motivations is mainly about revenge as their efforts have been stopped by the government before. Lee, working as a spy sends us a link saying that we must analyze a certain file in that link. Let’s open it right away…

https://www.youtube.com/watch?v=DFBNEsKJW6I&ab_channel=BahteraSiberMY

1727425761973

The video appears to be from the ITSLOKI group, claiming possession of a substantial amount of local data and threatening to sell it. The individual is challenging others to prevent this action. In the video description, there is a download link provided by Lee, as mentioned earlier. We should proceed to download and analyze the file.

It is a zip file, so we extract it to see the contents, and it seems to be an eml file which is an electronic mail format or email saved in plain text. There is also an zipped attachment inside the email.

1727426342871

1727425930854

Inside appears to be a morse code, let’s try to decrypt it right away.

1727425831695

We assume that the secret 4 digit code is 3108. Let’s keep that in mind and try to extract the attachment in the email.

1727426695725

There seems to be two files inside, an image file and a flag.txt file. Now if we try to extract, it asks for a password. With the earlier hint, we entered “3108”” as the password and we get the flag for the first part of the task. The flag is 3108{1E2A3C68CC5C0207886EDE403EEF230DC7C0FBD0}

1727426815597

1727426778788

Tugasan II: Tali Barut

1727426912517git

The task seems to hint us at performing some OSINT on the group to find out more information about them. The group seems to have been promoting hacking classes on social media with the intention of recruiting more black hat hackers on their side. Sambanthan tells us that he has left multiple files and secret message for us to analyze in a server.

Inspecting the image earlier that we got from the eml file, there seems to be names of the ITSLOKI members. So let’s start with that, we try to look for the next clue through searching social media using their usernames on the image.

1727427234769

After doing some OSINT, we find this account @p3tualang on TikTok. After checking out all the videos one by one, we find that there is a discord link in one of the posts. Let’s enter their server to investigate further.

1727427316805

Now that we have entered in their discord, let’s see if there any further clues, and remember that Sambathan has left us some secret messages and files. Let’s try to find that by going through all the channels one by one.

1727427400625

After examining all the channels, we noticed what appears to be a hidden message within the “TOPI HITAM” channel category

1727427819031

1727427834325

1727427849637

It seems to be some sort of cipher, and there is the number 31 and 08 which seems to indicate that this is a encrypted flag. We just need to find out what type of encryption is this and try to decrypt it. First, let’s combine all of this into a proper order. The code which contains 31 probably precedes the 08. It will look something like this.

baabbaaaaaaabbbabbababaaaaaaaaaabbb abbbbaabaabaaabbabbaabaaabaaabaaaaa! aaaaaabbabaaabbaaaaa baabbaabaaababbaaaaaaabbb abbaaaabaaabbababaabbabaaabbaaabbbbaaaaaabaaa abaabaaaaababbaaaaaaabbbbaaaaaabbab. 3108{baaba3abbabbaabb14baabaaaaaa_abbbb3ababaaaaaa}. abaaabaabbbaabaababbabbbaababaabaaa aabbababaaabbabaaaaa aaaba2 babaaabbabbaabbbabaaababa abbaaaabaaabbabbbaaaaabaabaaabaaaaaabbabaabba abbaaaaaaaababbaaaaabbaaabaabaabaaaaaaaa. aaabaaaaaabaaababaaa aabaaabbabaaababaaabbba aaabbbbbaabbaabaaaaabb baabbaabaababbbbaabb aaabbababbabbaa baabaaabaabaaabbababaabaabaaab aaabbabaaabaabaaaabaabbbabaaabaaabb abaaabaabbbaabaababbabbbaababaabaaa aaabbaaaaaabbab baabaaabaabaaabaaaaaabbabaabba baabaaabaabaaabbababaabaabaaab aaaba2 abbaaaabaabaaabaabaaababaaaaaa! -baabaaaaaaabbaaaaaabaaaaabaabbaabbbaaaaaabbab

1727428218644

Using a tool to analyze the cipher text, it seems to be encrypted with Bacon Cipher. Let’s try to decrypt it now.

TAHNIAHPERWIRAANDATELAHMENJUMPAIJAWAPANSNTSAPKAITSLOKIGUNACUNTUKMENYERANGMALAYSIACARIENCRYPTEDTEXTDLMSERVERDISCORDITSLOKIDANSERANGSERVERCMEREKASAMBATHAN

We get this when decrypting the message, however it still seems to be a little scrambled. This is probably because there are characters and numbers in the message which shouldn’t be in a Bacon Cipher. Now let’s try to remove all the unneeded characters and only focus on the flag part which starts with 3108{ }. Let’s try to decrypt the text by breaking it down like this

3108{baaba3abbabbaabb14baabaaaaaa_abbbb3ababaaaaaa}.

1727429527845

Now the spaces should probably be replaced by the numbers in the original cipher text as Bacon Cipher should only contain ‘a’s and ‘b’s. Combining all of them yields us the second flag!

The flag is 3108{S3NT14SA_P3KA}

Tugasan III: Pangkalan Gelap

1727429712836

It appears that ITSLOKI is running a web server to sell and leak hacked data. According to the task, someone has already breached their server and left us a message. Our objective now is to perform penetration testing on the box hosting this web server. We have two options to access the box: either through a Google Drive link or a TryHackMe room. Let’s head back to the Discord server to search for any clues.

In the #chat-biasa2 channel, there seems to be a python code. This python code seems to consist of index based references as can be seen with the “a” variable. There are also some syntax errors that we have to fix in order to get the actual string outputs.

Before:

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
a = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ \
            "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "

stored_xxx = 'a[71]+a[83]+a[83]+a[79]+a[82]+a[25]+a[14]+a[14]+a[67]+\
+a[67]+a[81]+a[72]+a[85]+a[68]+a[13]+a[70]+a[78]+a[78]+a[70]+a[75]+\
+a[68]+a[13]+a[66]+a[78]+a[76]+a[14]+a[69]+a[72]+a[75]+a[68]+a[14]+\
+a[67]+a[14]+a[16]+a[42]+a[88]+a[46]+a[74]+a[45]+a[85]+a[48]+a[24]+\
a[57]+a[20]+a[18]+a[32]+a[32]+a[75]+a[37]+a[62]+a[44]+a[20]+a[17]+\
+a[35]+a[73]+a[32]+a[68]+a[42]+a[69]+a[24]+a[56]+a[72]+a[45]+a[23]+\
+a[12]+a[52]+a[14]+a[85]+a[72]+a[68]+a[86]+a[30]+a[84]+a[82]+a[79]+\
+a[28]+a[82]+a[71]+a[64]+a[81]+a[72]+a[77]+a[70]'

right_arg111 = 'a[82]+a[64]+a[76]+a[65]+a[64]+a[83]+a[71]+\
+a[64]+a[77]'

sebab_boleh_dik = input("a[36]+a[77]+a[83]+a[68]+a[81]+a[94]+\
+a[83]+a[71]+a[68]+a[94]+a[79]+a[64]+a[82]+a[82]+a[86]+a[78]+\
+a[81]+a[67]+a[25]+a[94]")

if sebab_boleh_dik == right_arg111:
    print("a[32]+a[66]+a[66]+a[68]+a[82]+a[82]+a[94]+a[70]+\
    +a[81]+a[64]+a[77]+a[83]+a[68]+a[67]+a[13]+a[94]+a[40]+\
    +a[77]+a[72]+a[94]+a[84]+a[81]+a[75]+a[94]+a[34]+a[17]+\
    a[94]+a[40]+a[51]+a[50]+a[43]+a[46]+a[42]+a[40]+a[0]+\
    +a[94]+a[38]+a[78]+a[94]+a[70]+a[68]+a[83]+a[94]+a[83]+\
    +a[71]+a[68]+a[76]")
    print(stored_xxx)
else:
    print("a[50]+a[64]+a[75]+a[64]+a[71]+a[94]+a[83]+a[84]+\
    +a[0]+a[94]+a[32]+a[66]+a[66]+a[68]+a[82]+a[82]+a[94]+\
    +a[67]+a[68]+a[77]+a[72]+a[68]+a[67]")

After:

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
a = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"+ \
            "[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "

stored_xxx = a[71]+a[83]+a[83]+a[79]+a[82]+a[25]+a[14]+a[14]+a[67]+\
a[67]+a[81]+a[72]+a[85]+a[68]+a[13]+a[70]+a[78]+a[78]+a[70]+a[75]+\
a[68]+a[13]+a[66]+a[78]+a[76]+a[14]+a[69]+a[72]+a[75]+a[68]+a[14]+\
a[67]+a[14]+a[16]+a[42]+a[88]+a[46]+a[74]+a[45]+a[85]+a[48]+a[24]+\
a[57]+a[20]+a[18]+a[32]+a[32]+a[75]+a[37]+a[62]+a[44]+a[20]+a[17]+\
a[35]+a[73]+a[32]+a[68]+a[42]+a[69]+a[24]+a[56]+a[72]+a[45]+a[23]+\
a[12]+a[52]+a[14]+a[85]+a[72]+a[68]+a[86]+a[30]+a[84]+a[82]+a[79]+\
a[28]+a[82]+a[71]+a[64]+a[81]+a[72]+a[77]+a[70]

right_arg111 = a[82]+a[64]+a[76]+a[65]+a[64]+a[83]+a[71]+\
a[64]+a[77]

sebab_boleh_dik = a[36]+a[77]+a[83]+a[68]+a[81]+a[94]+\
a[83]+a[71]+a[68]+a[94]+a[79]+a[64]+a[82]+a[82]+a[86]+a[78]+\
a[81]+a[67]+a[25]+a[94]

if sebab_boleh_dik != right_arg111:
    print(a[32]+a[66]+a[66]+a[68]+a[82]+a[82]+a[94]+a[70]+\
    a[81]+a[64]+a[77]+a[83]+a[68]+a[67]+a[13]+a[94]+a[40]+\
    a[77]+a[72]+a[94]+a[84]+a[81]+a[75]+a[94]+a[34]+a[17]+\
    a[94]+a[40]+a[51]+a[50]+a[43]+a[46]+a[42]+a[40]+a[0]+\
    a[94]+a[38]+a[78]+a[94]+a[70]+a[68]+a[83]+a[94]+a[83]+\
    a[71]+a[68]+a[76])
    print(stored_xxx)
else:
    print("a[50]+a[64]+a[75]+a[64]+a[71]+a[94]+a[83]+a[84]+\
    +a[0]+a[94]+a[32]+a[66]+a[66]+a[68]+a[82]+a[82]+a[94]+\
    +a[67]+a[68]+a[77]+a[72]+a[68]+a[67]")

And the output that we get is,

1727445091607

https://drive.google.com/file/d/1KyOkNvQ9Z53AAlF_M52DjAeKf9YiN8-U/view

1727445156467

The downloadable file is an .ova file which is a virtual appliance package file that contains files for distribution of software that runs on a virtual machine. This is probably the box containing the web server belonging to ITSLOKI and we can access it by running it on a hypervisor software like VirtualBox.

In the #rat channel, there seems to be a broken C code. Let’s fix it and try to run it to see the output of the code.

Before:

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
#include <stdio.h>

int main() {
    int part1[] = { 122, 120, 226, 140, 130, 110, 103, 105, 113, 115, 107, 52 };
    int part2[] = { 105, 117, 115, 53, 112, 120, 53, 57, 55, 54, 62, 105, 122, 108, 125 };
    int part3[] = { 103, 120, 113, 103, 110, 123, 116, 122, 123, 113, 118, 107, 120, 125, 111, 120, 103 };

    char finalValue[50]; 

    int = 0;
    for (int i = 0; i < sizeof(xxxx) / sizeof(part1[0]); i++) {
        finalValue[index++] = (char)part1[i];
    }
    for (int 0 = 0; i < sizeof(part2) / sizeof(part2[0]); i++) {
   
    }
    for (int i = 0; i < sizeof(part3) / sizeof(part3[0]); i++) {
        finalValue[index++];


    printf("Final value: %s\n", finalValue);

    return 0;
}

After:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>

int main() {
    int part1[] = { 122, 120, 226, 140, 130, 110, 103, 105, 113, 115, 107, 52 };
    int part2[] = { 105, 117, 115, 53, 112, 120, 53, 57, 55, 54, 62, 105, 122, 108, 125 };
    int part3[] = { 103, 120, 113, 103, 110, 123, 116, 122, 123, 113, 118, 107, 120, 125, 111, 120, 103 };

    char finalValue[50]; 

    int index = 0;
    for (int i = 0; i < sizeof(part1) / sizeof(part1[0]); i++) {
        finalValue[index++] = (char)part1[i];
    }
    for (int i = 0; i < sizeof(part2) / sizeof(part2[0]); i++) {
        finalValue[index++] = (char)part2[i];
    }
    for (int i = 0; i < sizeof(part3) / sizeof(part3[0]); i++) {
        finalValue[index++] = (char)part3[i];;
    }

    printf("Final value: %s\n", finalValue);

    return 0;
}

Now that the code has been fixed, let’s try to run it now.

1727431487002

The output that we get is,

1
zx⌂ngiqsk4ius5px5976>izl}gxqgn{tz{qvkx}oxg@

1727431675558

It seems to be a ROT ciphertext, decrypting it yields us a TryHackMe room.

https://tryhackme.com/jr/3108ctfwarkahuntukperwira

1727432203419

We now have two ways to access their server as stated earlier, which is via TryHackMe room or the box we downloaded. It doesn’t matter which one we choose. Let’s configure our attacking machine along with the box. Now the first step is to get the box’s IP so that we can perform an nmap scan. For this, we can use The IP is 10.0.2.4

1727449746196

Next, run a basic nmap scan nmap -sC -sV 10.0.2.4

1727456524243

In the nmap scan, we found a HTTP server on port 80. Let’s now access the web server via a browser.

1727456285448

This means that we need to add this ip into our hosts file, but first we need to find out the original domain name of the web server. Let’s now bruteforce the web server to find if there are interesting files and directories.

1727456086261

Using dirb, we found a file called note.txt. Now we can examine the contents of the text file.

1727456622663

itsloki.bs seems to be the original domain name for the server. Now we just need to insert this into our hosts file located at /etc/hosts

1727456733989

Now we can access the website in a browser via itsloki.bs

1727456907525

Let’s first view the page source to find if there are any helpful hints.

1727456864134

In the page source, we found an interesting text that contains, what it looks to be someone’s credentials. In the website, we can find the same name “rok14h” which is the author of the posts. Also another intesting thing to note is that the website is built using a content management system called ““Textpattern.”

Let’s again do some enumeration on the website now that we have its domain name. We will be bruteforcing for files and directories to see if there any ways we can get into the web.

1727457503063

1727457546136

We found the textpattern directory. Let’s examine it.

1727457593604

It appears that this is the admin page of the textpattern CMS. We need some credentials to access this. We can use the credentials obtained earlier in the page source of the website which is rok14h:rok14h@l33t

1727457705828

Next, let’s inspect the admin page further to see if there any interesting things that we can potentially use to get into the box. It seems that there is an upload file functionality, we can possibly use this to do a reverse shell.

1727457785384

We can use this reverse shell php file that can be downloaded from here

https://github.com/xdayeh/Php-Reverse-Shell/blob/master/PHP-Reverse-Shell.php

In the code, we need to edit the ip and port to our own. We will use port 4444

1727459315295

Next is to set up a netcat listener using the same port that we have entered.

1727459379076

Now let’s upload the file and activate it by browsing into the file via a browser. It can be browsed here http://itsloki.bs/files (we found this directory earlier with dirb) and clicking on the file.

1727459435814

Go back to the terminal and now we should have access to the box.

1727459582516

Next, let’s find the flag by using the find command find / -name "*.txt" or find / -iname "Flag*.txt"

1727460728801

1727461471509

We have found the final flag! The flag is 3108{h4sil_bum!_d1r0b3k_dem1_kep3nt!ng4n_d1r1}

Bonus Merdeka Quest

This is a small write up for the bonus Merdeka giveaway.

Let’s start by going into the google drive link provided. Download the files and examine the contents.

1727355020330

A quick analysis using these two commands.

1
2
cat info.txt
file dumb.raw

1727355157259

1727355164240

After examining, it seems like we would have to find a flag with the format 3108{FLAG} inside the .raw file which we further analyzed using the file command. We reckon that it might be a windows memory dump file.

For memory dumps, we can use volatility3 for further analysis… let’s download the tool.

https://github.com/volatilityfoundation/volatility3

1
2
git clone https://github.com/volatilityfoundation/volatility3.git
cd volatility3

Start the tool and let’s check out the help page to see what we can work with. Since we know this is a windows dump file, we will just focus on the windows plugins.

1
python3 vol.py -h

1727355253606

Considering that we would have to somehow find a flag, the flag text might be placed in a file. So, let’s first scan for files by using the** windows.filescan** plugin. The plugin lists all the files that are in the memory dump.

1
vol.py -f dumb.raw windows.filescan 

1727355285381

After the scan finishes.. as a start, let’s just try using the search function (CTRL + SHIFT + F) in the terminal to find any files named “flag”… and we found two files named flag.rtf and flag or not.txt.

1727355311089

1727355325691

Now that we found the flag files, we can examine the content by dumping the files using the **windows.dumpfiles **plugin. We take the respective offset number from the filescan results for each of the files so we can examine individually. We output the results in a folder we created name “files”.

OffsetFile name
0x96080108ec30flag.rtf
0x960802c47830flag_or_not.txt
1
2
python3 vol.py -f dumb.raw -o ./files windows.dumpfiles --virtaddr 0x96080108ec30
python3 vol.py -f dumb.raw -o ./files windows.dumpfiles --virtaddr 0x960802c47830

Examine the content of the files in the folder that we outputted using a rich text format editor for the** .rtf **file.

1727355467525

1727355473273

The flag is 3108{MEMORY-DUMP}

This post is licensed under CC BY 4.0 by the author.

Trending Tags