728x90
[Dreamhack] phpMyRedis
기본 페이지는 위와 같이 생겼다.
<?php
include_once "./core.php";
?>
<html>
<head></head>
<link rel="stylesheet" href="/static/bulma.min.css" />
<body>
<div class="container card">
<div class="card-content">
<div class="columns">
<div class="column is-10">
<h1 class="title">phpMyRedis</h1>
</div>
<div>
<div class="column is-2"><a href="/config.php" class="card-footer-item">Config</a></div>
</div>
</div>
<form method="post">
<div class="field">
<label class="label">Command</label>
<div class="control">
<textarea class="textarea" name="cmd"><?=isset($_POST['cmd'])?$_POST['cmd']:'return 1;'?></textarea>
</div>
<label class="checkbox">
<input type="checkbox" name="save">Save
</label>
</div>
<div class="control">
<input class="button is-success" type="submit" value="submit">
</div>
</form>
<?php
if(isset($_POST['cmd'])){
$redis = new Redis();
$redis->connect($REDIS_HOST);
$ret = json_encode($redis->eval($_POST['cmd']));
echo '<h1 class="subtitle">Result</h1>';
echo "<pre>$ret</pre>";
if (!array_key_exists('history_cnt', $_SESSION)) {
$_SESSION['history_cnt'] = 0;
}
$_SESSION['history_'.$_SESSION['history_cnt']] = $_POST['cmd'];
$_SESSION['history_cnt'] += 1;
if(isset($_POST['save'])){
$path = './data/'. md5(session_id());
$data = '> ' . $_POST['cmd'] . PHP_EOL . str_repeat('-',50) . PHP_EOL . $ret;
file_put_contents($path, $data);
echo "saved at : <a target='_blank' href='$path'>$path</a>";
}
}
?>
</div>
</div>
<br/>
<div class="container card">
<div class="card-content">
<div class="columns">
<div class="column is-10">
<h1 class="title">Command History</h1>
</div>
<div class="column is-2"><a href="/reset.php" class="card-footer-item">Reset</a></div>
</div>
<div class="content">
<ul>
<?php
for($i=0; $i<$_SESSION['history_cnt']; $i++){
echo "<li>".$_SESSION['history_'.$i]."</li>";
}
?>
</ul>
</div>
</div>
</div>
</body>
</html>
if(isset~ 부분을 보자. $redis변수는 Redis클래스의 인스턴스임을 알 수 있다. 따라서 Redis의 모든 기능을 사용할 수 있는 것을 알 수 있다. 중간에 -> 이 있길래 저게 사용이 가능한가싶어서 알아보니 해당 객체의 안쪽을 지칭할 때 사용하는 것을 알 수 있었다. 그 다음 eval메소드의 인수 값을 사용자가 입력한 값으로 받아온다.(eval함수 참고 => https://support.microsoft.com/ko-kr/office/eval-%ED%95%A8%EC%88%98-8c4a1b10-85ba-40db-b0c8-5290da4d4166)
(redis 공식 사이트에서 eval함수 사용법 참고 https://redis.io/commands/eval/)
자 그럼 이제 flag를 가져오기 위한 과정을 시작해보자!
위치를 /var/www/html로 변경(현재 위치가 /var/www/html 되어있었지만 확실함을 위해..)
Redis의 dbfilename을 slow.php로 바꿨다.(whebshell에 업로드하기 위함.)
생성한 webshell을 Redis에서 인식하게 만들기 위하여 save명령어 사용(Redis메모리는 휘발성임을 기억하자. save명령어로 파일의 경로, 이름, 데이터를 함께 설정할 수 있음.)
webshell에 올렸다. 그리고 slow.php에 들어갔을 때 바로 /flag가 출력되도록했다.
flag값을 획득할 수 있었다.
728x90
'Webhacking-Write-Up > Dreamhack' 카테고리의 다른 글
[Dreamhack] File Vulnerability Advanced for linux (0) | 2023.01.11 |
---|---|
[Dreamhack] Command Injection Advanced (0) | 2023.01.11 |
[Dreamhack] csrf-2 (0) | 2023.01.11 |
[Dreamhack] NoSQL-CouchDB (0) | 2023.01.11 |
[Dreamhack] SQL Injection Bypass WAF Advanced (0) | 2023.01.11 |