Playing Hacks and Stuffs!
I played this ctf with my friends
Here’s the writeup to the challengs I solved:
From the challenge description we can immediately tell this would be some sort of SSRF
Going over to the web url shows this
We have 4 various blog post
Clicking it just shows some word
Looking at the request made when I click on a blog post shows this
We have a POST
request to /api/view.php
And the parameter passed is this
It is using a file
wrapper to view the content of /posts/Azita
With this we can basically read local files from disk
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!
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}
Going over to the url shows this
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
Cool so let’s bypass that
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
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
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}
Going over to the url shows this
So we are to provide the captcha 300 times before we get the flag
The session cookie is provided
On each page refresh the value of the image changes
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
And back on the web page I got the flag
Flag: UCTF{7h3_m1551n6_l4k3}
From the challenge name we can tell we will be doing NoSQL Injection
Going over to the url shows this
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
Failed login request just redirects to /login
Notice the header
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
We can see that on forwarding the request it works
To check for NoSQL Injection I used the not equal $ne
parameter
{"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
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
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
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
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
I searched for the users I have and got their individual role
Right now it doesn’t work I guess the server is overloaded
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
Searching the first user returned it’s value
So just search for all the users the one whose role is admin
holds the flag :P
We are given an attached file to download with the key which is base64 encoded
Checking the attached file showed this
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
Flag: ucf{urum_noql}
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
What it does is this:
moeness
is the value returned when the check_moe
function is called passing the user id as the argumentcustom_chant
stores the value of the environment variable MOE_CHANT
chant
holds a set of characterscustom_chant
variable it will then use strcpy
to copy the value to the array chantmoeness
with the expected moeness
value which is 0x30e
userid
and groupid
to 0
calls execve
on our input which is basically command executionHere’s the check_moe
function
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:
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
Let us test this out
First I compiled it because no binary was provided just the source code :P
➜ Moedo gcc src.c -no-pie -o src
Now I can cause a segfault
➜ 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,
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
Or just check ghidra stack layout
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
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
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
And now if we run it again we should have command execution as root
All we need now is to do the same thing on the server but unfortunately there’s no python on the server :(
I then used printf
since it was available on the remote server
export MOE_CHANT="AAAAAAAAAAAAAAAAAAAAAAAAAA$(printf '\x0e\x03')"
Here’s the flag
Flag: uctf{m45h1r0_d1dn7_61v3_up}
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:
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 ( -_・)σ - - - - - - -