➜ ~

Playing Hacks and Stuffs!


Project maintained by h4ckyou Hosted on GitHub Pages — Theme by mattgraham

UCTF 2023

I played this ctf with my friends

Here’s the writeup to the challengs I solved:

Web

Cryptography

Pwn

Misc

Web

E Corp

image

From the challenge description we can immediately tell this would be some sort of SSRF

Going over to the web url shows this image

We have 4 various blog post

Clicking it just shows some word image

Looking at the request made when I click on a blog post shows this image

We have a POST request to /api/view.php

And the parameter passed is this image

It is using a file wrapper to view the content of /posts/Azita

With this we can basically read local files from disk image

curl -s -X POST "https://ecorpblog.uctf.ir/api/view.php" -H "Content-Type: application/json" -d '{"post":"file:///etc/passwd"}' | jq .post -r

But how would that help us in accessing the internal domain?

Well since it uses file wrapper it’s safe to assume we can also make use of other wrappers in this case it will be http

With that said we should be able to access the internal domain http://admin-panel.local

Doing that works! image

curl -s -X POST "https://ecorpblog.uctf.ir/api/view.php" -H "Content-Type: application/json" -d '{"post":"http://admin-panel.local"}' | jq .post -r

Here’s the flag

Flag: uctf{4z174_1n_urm14}

Htaccess

image

Going over to the url shows this image

So there are two htaccess rules placed on two portions of the flag

We need to bypass them inorder to get the flag

The first one is this:

RewriteEngine On
RewriteCond %{HTTP_HOST} !^localhost$
RewriteRule ".*" "-" [F]

What this rule enforce is basically that if the Host header isn’t localhost we won’t be able to access the file

So to bypass this we can just change the Host header to localhost

This is what happens if we fail to bypass and try to read the flag image

Cool so let’s bypass that image

curl -H "Host: localhost" http://htaccess.uctf.ir/one/flag.txt

We get the first portion of the flag

uctf{Sule_

For the second rule:

RewriteEngine On
RewriteCond %{THE_REQUEST} flag
RewriteRule ".*" "-" [F]

It checks if the request body contains the string flag

If it does then we will get 403 error

Here’s a sample image

So to bypass this we can just url encode the string flag in the url search bar

And what will happen is that the htaccess check will return False but where as on the server side it will get decoded to flag and we get access to it

This solution was given to me by @0xvenus

First I urlencoded flag then used it as the file name in the url image image

curl htaccess.uctf.ir/two/%66%6c%61%67.txt;echo

We can now join the two portion of the flag

Flag: uctf{Sule_Dukol_waterfall}

Captcha1 | the Missing Lake

image

Going over to the url shows this image

So we are to provide the captcha 300 times before we get the flag

The session cookie is provided image

On each page refresh the value of the image changes image

We can submit those words from the image manually but what’s the fun there 🙂

This is my approach in solving this challenge:

That sounds easy writing that but the script took me some good amount of time debugging 😂

Here’s my solve script and I must admit it takes about 12minutes (I should learn to optimize my coding ikr)

But after running the script I got this image

And back on the web page I got the flag image

Flag: UCTF{7h3_m1551n6_l4k3}

MongoDB NoSQL Injection

image

From the challenge name we can tell we will be doing NoSQL Injection

Going over to the url shows this image

We have a login page but since no credential was giving let us try bypass it using NoSQL Injection

I used burp to intercept the login request image

Failed login request just redirects to /login

Notice the header image

It’s running Express server which is like NodeJS and usually the database that runs on NodeJS is MongoDB

Also because of this we can pass the parameters in form of json image

We can see that on forwarding the request it works

To check for NoSQL Injection I used the not equal $ne parameter image

{"username":{"$ne":"uche"},"password":{"$ne":"uche"}}

What that does is to tell the MongoDB that the value of username is not equal to uche which is True because the database doesn’t have any username as uche also the same applies to the password

With that the login will be successfull

By intercepting the login request and modifying it to that payload I was able to bypass the login page image image

In the home page we can search for a user

But when I tried searching for some names it didn’t return any result

There’s a /users endpoint but that gives this error image

So we need to find a way to get the users

We can take advantage of the NoSQL injection to dump the users from the username column

The way to do it is by using regular expression

So basically this:

{"username":{"$regex":"^"},"password":{"$ne":"uche"}}

That will return True and get us logged in because ^ is a wildcard which basically checks if any of the users in the column first character is any value

Next we can try:

{"username":{"$regex":"^a"},"password":{"$ne":"uche"}}

This will check is any of the user in the column is starting from a if that returns True i.e gets us logged in

Then we can check for the second character

{"username":{"$regex":"^ab"},"password":{"$ne":"uche"}}

Basically we will keep doing that and eventually end up dumping the users

So now that we know that we can go ahead doing it manually but scripting it saves time

Here’s the dump script

If you check the script you will see commentated section of the code that’s so because while I was trying to solve this I was over complicating things lol

Anyways basically the script will dump the users 1 2

Now that we have the list of users this is where I started over complication things

I assumed the flag would be any of the users password

So I made a function to get the password length of each users

It’s just doing this regex

{"username":{each_users},"password":{"$regex":"[a-zA-Z0-9]{1}"}}

Basically that will check is the length of the user password is 1 if it is then it will return True and get us logged in

We can keep incrementing the values till we get a False return

But when I ran it I noticed the password length are all the same for the users 3

So it’s likely the password are hashes that’s why it’s the same

Therefore it’s of no use (i spent so many hours on this lool)

After this I decided to check the web out and saw the search user function which I had forgotten about image

I searched for the users I have and got their individual role

Right now it doesn’t work I guess the server is overloaded image

But user decre127 profile had the flag in his ID column

Just to confirm I ran the script again and saw that the users changed so that’s why it didn’t return any value image

Searching the first user returned it’s value image

So just search for all the users the one whose role is admin holds the flag :P

Cryptography

Noql

image

We are given an attached file to download with the key which is base64 encoded

Checking the attached file showed this image

The first thing I noticed was the first 6 bytes gAAAAA

That’s Fernet encryption and I knew cause I did something similar before and when ever something is encrypted using Fernet Cipher the first 6 bytes are gAAAAA

I wrote a script to decrypt it

from cryptography.fernet import Fernet

key = b"CT0cgUTU7gBBvA3DOk4H30JMQSFwNm-viqZm9eDwPK8="
token = open('noql.txt', 'r').read()

f = Fernet(key)
d = f.decrypt(token)

print(d.decode())

Running it gives the flag image

Flag: ucf{urum_noql}

Pwn

Moedo

image

This was a begineer pwn challenge and the source code was provided

Here’s the source code

Reading the source code we can see the main function image

What it does is this:

Here’s the check_moe function image

What that basically does is to like convert our user id to a moe value

So what’s the vulnerability with the code?

Well this:

image

It uses strcpy to copy the value of the MOE_CHANT environment variable to the chant array

And the chant array can only hold some amount of bytes since it already has some value stored in it

char chant[] = "Moe Moe Kyun!";

The use of strcpy cause a buffer overflow image image

Let us test this out

First I compiled it because no binary was provided just the source code :P image

➜  Moedo gcc src.c -no-pie -o src

Now I can cause a segfault image

➜  Moedo export MOE_CHANT=$(python2 -c print" 'A'*1000")
➜  Moedo ./src lol
UID: 1094795585 - GID: 1094795585 - Moe: 41414141
You're not moe enough!
[2]    125693 segmentation fault  ./src lol
➜  Moedo

Cool now we have confirmed the buffer overflow

What we should think of now is on how to exploit this?

Well we basically just need to meet the if condition done on the value of moeness

Since this will turn to be variables on the stack,

image

We can calculate the offset between the chant and moeness variables

With that we will be able to overwrite the value stored in moeness

To get the offset we can maybe look it up in gdb image

image

Or just check ghidra stack layout image

The offset is 0x2e - 0x14 = 26

So with 26 bytes we will get the moeness variable and on more input we would overwrite it’s content

Let’s check it out image

Cool it works

Now we just need to overwrite it to the expected moeness value which is 0x30e

#define MOE_ENOUGH 0x30e

The hex form will be \x0e\x03 doing that worked image

But we get an issue returned from setuid and that’s because it’s trying to set the user id to 0 which is for the root user and we are not root

We can just change permission and set the binary to have the suid perm image

And now if we run it again we should have command execution as root image

All we need now is to do the same thing on the server but unfortunately there’s no python on the server :(

image

I then used printf since it was available on the remote server image

export MOE_CHANT="AAAAAAAAAAAAAAAAAAAAAAAAAA$(printf '\x0e\x03')"

Here’s the flag

Flag: uctf{m45h1r0_d1dn7_61v3_up}

Misc

OTP (Onion Transfer Protocol)

image

I was writing on this challenge and was almost done but suddenly my firefox crashed (it’s been happening recently I have just few tabs open 😕) and I didn’t save this github edit progress 😭

Starting afresh is a bit of pain so I will just give the TDLR of it

We are given a host running ftp via the tor network proxy

Connecting to it normally won’t work so we need to setup a proxy where when we use ftp it will be passed via the tor network proxy

It can be configured by using starting tor service and using tor network which by default runs on port 9050 i think then add that in our proxychain config file as socks5 proxy

Then we should be able to connect to ftp!

The ftp contained 5000 directories all having different names and the same file in each directory

The file name was flag.txt but it contained a fake flag

Each of the directory had the same size so if you thought of just filtering the one of different size that won’t work (but congrats on thinking of that xD)

You might also maybe think of downloading all the files and grepping for the flag but that’s stressfull considering network speed and the amount of time it will take before it downloads :)

There was a hidden file which had the keyword: Think of IFUM!!!

At first that seemed weird but after few minutes I figured that a directory started with IFUM and on downloading the file in that directory lead to another hint

I have forgotten the word :( but it was also among a directory then that one contained the flag

That’s all for this ctf and the challenge I did 😜

Here’s the writeup to other challs solved by some of the team mates I played with:

Sensei gr33p

Btw Captcha2 was among the web challenge though it was solved, Sensei beat me in writing an auto solve script 😭

Do so to check the two writeups

Thanks for reading ( -_・)σ - - - - - - -