아래는 서버 코드이다.
<html>
<head></head>
<link rel="stylesheet" href="/static/bulma.min.css" />
<body>
<div class="container card">
<div class="card-content">
<h1 class="title">Online Curl Request</h1>
<?php
if(isset($_GET['url'])){
$url = $_GET['url'];
if(strpos($url, 'http') !== 0 ){
die('http only !');
}else{
$result = shell_exec('curl '. escapeshellcmd($_GET['url']));
$cache_file = './cache/'.md5($url);
file_put_contents($cache_file, $result);
echo "<p>cache file: <a href='{$cache_file}'>{$cache_file}</a></p>";
echo '<pre>'. htmlentities($result) .'</pre>';
return;
}
}else{
?>
<form>
<div class="field">
<label class="label">URL</label>
<input class="input" type="text" placeholder="url" name="url" required>
</div>
<div class="control">
<input class="button is-success" type="submit" value="submit">
</div>
</form>
<?php
}
?>
</div>
</div>
</body>
</html>
코드를 보면
1.shell_exec으로 먼저 curl을 디폴트로 실행시켜주는 것을 볼 수 있다.
2.문자열에 http가 있는지 검사한다.
3.이상한 파일을 삽입하는 것에 대비해 md5로 url을 해싱한다.
4.그 후 cache디렉토리 안에 그 md5 해싱을 파일명으로 하여 파일 내용을 저장한다.
5.파일 내용은 요청으로 받은 값이다.
위의 내용으로 보아 아마도 일반적으로 127.0.0.1요청을 보내면 똑같은 웹페이지가 나오되 백엔드는 구현되어있지 않은 html문서만 나올 것이다.
자 그러면 curl의 인자를 받는 곳에 또 curl을 쓰고 -o옵션으로 파일을 생성하자.
그렇게 되면 두번 curl이 실행되면서 인자 안에서 실행되는 curl은 md5로 해싱되지 않을 것이다.
아래로 test를 해보자
아래와 같이 url이 해싱되어 파일명으로 쓰이고 cache디렉토리에 저장된 것을 볼 수 있다.
그럼 나는 웹 쉘을 미리 만들어놓겠다.
이번에도 깃허브 호스팅 서비스를 이용했다.
아래처럼 나의 서버에 웹 쉘을 올려놓았다.
아래처럼 익스플로잇 코드를 작성한다.
나의 웹서버에 있는 hack.php를 -o 옵션으로 cache디렉토리에 hack.php라는 이름으로 저장해달라는 코드이다.
아파치의 기본적인 경로는 var/www/html인 점을 참고했다.
그렇게 하면 md5로 해싱된 파일 경로가 나올건데 그거는 전체적인 url이 해싱된 것이고 우리는 따로 hack.php라는 파일을 저장했다.
그럼 그 경로로 가보자
그렇게 되면 아래처럼 웹쉘이 등장한다.
아래와 같이 ls -al로 상세한 ls를 확인해보게 되면 잘 나오는 것을 볼 수 있다.
flag는 파일로 되어있다고 했으니
/flag를 입력해서 flag를 실행시키고 flag를 얻을 수 있다.
감사합니다 주찬이형