WEB1

SQL injection(4) - Union SQL injection

이번 토픽에서는 2개 이상의 쿼리를 요청하여 결과를 얻는 UNION이라는 SQL연산자를 이용한 SQL injection 공격에 대해 알아보도록 하겠습니다.

 

우선 컬럼의 갯수를 알아내야합니다.

갯수를 알아내기 위해 앞의 쿼리문에 이어서 union select 1, %23 으로 쓴다면 에러가 뜰 것입니다.

그러나 union select 1, 2, %23 => union select 1, 2, 3, %23 ... 순으로  컬럼의 갯수를 늘려가다보면 에러가 나지 않는 때가 나올때, 즉 컬럼의 갯수가 일치할 때를 알 수 있습니다.

또한 컬럼 전체가 출력되는 것이 아니라 몇몇 컬럼들의 결과만 나오게 되는데 이를 사용하여 저희가 결과값을 불러올 수 있는 컬럼을 알 수 있게됩니다.

또한 order by 절을 이용하여 컬럼의 갯수를 알아낼 수 있습니다.

where 절의 뒤에 order by 1 %23 => order by 2 %23... 순으로 하나 씩 올려가다 보면 에러가 뜰텐데 이 에러가 뜨지 않는 최대의 수가 바로 컬럼의 갯수입니다.

 

컬럼의 갯수를 확인하였다면 숫자 대신 version(), user(), database()를 넣어줍니다.

이는 각각 사용 중인 my sql의 버전, 사용 중인 user의 이름과 권한, 그리고 현재 database의 이름을 알려줍니다.

이때 유의할 점은 아까 컬럼의 갯수를 알아낼 때 같이 알아낸, 저희가 결과값을 불러올 수 있는 컬럼에 넣어줘야 합니다.

 

my sql의 버전, 사용중인 user의 이름과 권한, 그리고 현재 database의 이름을 알아냈다면 table의 이름을 알아낼 차례입니다.

table의 이름을 불러오는 구문은 union select table_name from information_schema.tables where table_schema = database()입니다.

이때, web에서는 가장 상위에 있는 하나의 줄만을 가져오기 때문에 limit절을 사용해주어야 합니다.

union select table_name from information_schema.tables where table_schema = database() limit 0,1 %23

union select table_name from information_schema.tables where table_schema = database() limit 1,1 %23... 순으로 한 줄씩 내려가며 필요해보이는 table의 이름을 찾을 수 있습니다.

 

table의 이름을 찾았다면 컬럼의 이름도 찾아야겠죠.

찾아낸 table의 이름을 user라고 합시다.

그렇다면 컬럼의 이름을 불러오는 구문은 table과 동일하게 union select column_name from information_schema.columns where table_name = 'user'입니다.

당연하겠지만, table_name에는 아까 찾은 이름을 넣고 컬럼의 이름을 불러올때도 똑같이 limit 0,1 %23 => limit 1,1 %23 => limit 3,1 %23... 순으로 limit절을 사용하여 한줄씩 내려가며 찾아야 합니다.

 

이번 토픽에서는 UNION이라는 SQL연산자를 사용한 SQL injection 공격에 대해 알아보았습니다.

 

댓글

댓글 본문