https://webhacking.kr/challenge/web-08/
Challenge 8
webhacking.kr
[문제]
[풀이]
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 8</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
</style>
</head>
<body>
<br><br>
<center>
<?php
$agent=trim(getenv("HTTP_USER_AGENT"));
$ip=$_SERVER['REMOTE_ADDR'];
if(preg_match("/from/i",$agent)){
echo("<br>Access Denied!<br><br>");
echo(htmlspecialchars($agent));
exit();
}
$db = dbconnect();
$count_ck = mysqli_fetch_array(mysqli_query($db,"select count(id) from chall8"));
if($count_ck[0] >= 70){ mysqli_query($db,"delete from chall8"); }
$result = mysqli_query($db,"select id from chall8 where agent='".addslashes($_SERVER['HTTP_USER_AGENT'])."'");
$ck = mysqli_fetch_array($result);
if($ck){
echo "hi <b>".htmlentities($ck[0])."</b><p>";
if($ck[0]=="admin"){
mysqli_query($db,"delete from chall8");
solve(8);
}
}
if(!$ck){
$q=mysqli_query($db,"insert into chall8(agent,ip,id) values('{$agent}','{$ip}','guest')") or die("query error");
echo("<br><br>done! ({$count_ck[0]}/70)");
}
?>
<a href=./?view_source=1>view-source</a>
</body>
</html>
소스코드이다.
agent에 HTTP_USER_AGENT 정보를 저정하고 ip에 ip정보를 저장한다.
agent에 from 문자열이 포함되어 있다면 agent 정보를 출력한다.
count_ck에 쿼리 정보가 저장된다.
count_ck가 70이상이면 테이블 내용을 삭제한다.
chall8 테이블에 agent에 HTTP_USER_AGENT 값이 있다면 hi [문자열]로 출력한다.
만약 id가 admin이라면 문제가 풀린다.
USER_AGENT를 수정하여 문제에 접근해야 하기에 burp suite를 사용해서 문제를 풀었다.
웹 페이지가 돌아가는 방식은
chall8테이블에서 USER_AGENT의 이름의 agent 유무를 확인하고 없다면 chall8테이블에
id가 guest인 USER_AGENT 정보를 추가하는 방식이다.
우리는 id가 admin으로 웹페이지에 접속해야 문제가 풀린다.
insert into chall8(agent,ip,id) values('{$agent}','{$ip}','guest')
이 부분을 공격하는 것인데.
insert into chall8(agent,ip,id) values('admin','127.0.0.1','admin')
위 같은 형식으로 테이블에 저장된다면 USER_AGENT를 admin으로 패킷을 보내면 문제가 풀린다.
우리는 burp suite로 USER_AGENT 값을 수정할 수 있기에 SQL Injection을 시도해본다.
insert into chall8(agent,ip,id) values('admin','127.0.0.1','admin')','{$ip}','guest')
값이 이런식으로 들어간다. 이런식으로 패킷을 보내게 되면 정상적인 문법이 아니기에 querry error가 출력된다.
뒷 부분을 처리해줘야하는데
insert 쿼리에서 insert into values('','',''),('','','') 형식으로 insert를 2번 처리가 가능하다.
insert into chall8(agent,ip,id) values('admin','127.0.0.1','admin'),('a','{$ip}','guest')
이런식으로 쿼리에 들어가고 정상적인 쿼리가 완성된다.
패킷 전송하면
정상적으로 등록이 되고
USER_AGENT를 admin으로 바꿔 패킷을 보내면
문제가 풀린다.