본문 바로가기

Wargame(hacking)/LOS

LORD OF SQLINJECTION : dragon

Write-Up

 

  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_dragon 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>"; 
  if($result['id'] == 'admin') solve("dragon");

 

해당 challenge에 해당하는 필터링 조건 및 pass 조건은 위와 같다. 눈에 띄는 점은 query에 #이 들어가 있다는 점이다.

 

#은 주석을 의미한다. 다만, 한라인에서 # 다음에 오는 것들을 주석처리 하는 것이다. 그러므로 pw 파라미터의 인자 값으로 %0d%0a (개행) 문자를 넣어주면 문제를 해결할 수 있다. 

 

 

처음 시도한 payload :  id='guest'# and pw=%27%0d%0aor%201=1%23

 

주황색 부분이 주석 및 개행처리되어진다고 생각하면 된다. ( %0d%0a 는 개행을 담당 ) 다만, 위의 payload는 정답이 아니다. 그 이유는 id='guest'or 1=1%23과 같이 해석되기에 guest가 페이지에 출력된다. 그러므로 앞의 id='guest' 인 부분을 false 값으로 만들어 줄 수 있는 방법을 생각해야 한다. 

 

두번째 payload : pw=%0d%0aand pw='12' or id='admin'%23

 

위와 같은 payload로 문제를 해결할 수 있었다. ( %0d%0a가 아닌, %0a 만으로도 개행이 이뤄지긴한다. )

 

그림 1

 

 

참고

 

https://zetawiki.com/wiki/%EA%B0%9C%ED%96%89%EB%AC%B8%EC%9E%90,_%EB%9D%BC%EC%9D%B8%ED%94%BC%EB%93%9C,_%EC%BA%90%EB%A6%AC%EC%A7%80%EB%A6%AC%ED%84%B4#google_vignette

 

개행문자, 라인피드, 캐리지리턴 - 제타위키

다음 문자열 포함...

zetawiki.com

 

LF : 커서( \n, 0x0a  )를 한칸 아래로 이동 = 새로운 행 추가(new line feed)
CR 커서( \r, 0x0d  )를 맨왼쪽으로 이동 = 시작위치로 복귀(return)

 

참고로, 리눅스에서는 개행문자로 LF (0x0a) 만 사용되지만, 윈도우에서는 개행문자로 CRLF (0x0d 0x0a) 로 표시하여 1Byte가 더 크게 적용된다.