NCS보안3기/웹 해킹2017. 6. 8. 21:29

- 개요


웹 어플리케이션이 외부 시스템이나 자체 운영체제에 접근할 때 입력받은 인자를 그대로 전달한다.

즉, 악성코드를 원하는 시스템에 전송할 수 있으며, SQL문 구문을 삽입하여 DB 서버에 침구가 가능하다. 또한 인수에 특수문자를 삽입하여 서버 내부에 명령 전달이 가능하다.


- 공격 행태


공격자가 해당 인자로 악의적인 명령어를 사입하는 경우, 해당 외부 시스템은 웹 어플리케이션으로 인해 입력받은 명령어를 실행하게 된다.

취약한 웹 어플리케이션을 통해 악성 코드를 전송하여 시스템 콜을 통한 OS 호출, 쉘 명령어를 통한 외부 프로그램 사용, SQL 구문을 통한 백엔드 데이터베이스 호출 등을 수행한다.


mysql> select * from user_db;

+----------+----------------------------------+---------------------+

| id       | pw                               | authtime            |

+----------+----------------------------------+---------------------+

| haha     | 925cc8d2953eba624b2bfedf91a91613 | 2017-06-07 14:37:35 |

| hihi     | e9f5713dec55d727bb35392cec6190ce | 2017-06-07 15:28:49 |

| Imp3rio  | 3b9e314227e9a1409b922049a088e8f0 | 2017-06-07 17:07:04 |

| test     | 098f6bcd4621d373cade4e832627b4f6 | 2017-06-07 21:52:33 |

| admin    | c62d929e7b7e7b6165923a5dfc60cb56 | 2017-06-08 20:51:24 |

| firewall | 7ef3645806013c9c2f9350f0f6d4d9fb | 2017-06-08 20:51:33 |

| 1341231  | 07a0dd7a3fd6670c9ef71de870c3c065 | 2017-06-08 20:51:43 |

+----------+----------------------------------+---------------------+


user_db 테이블에 위와 같은 데이터가 들어가 있다. pw의 경우 md5() 함수로 해쉬값이 들어가기 때문에 pw를 알아낼 방법이 없다. 

elseif($_SERVER['QUERY_STRING'] == "login") {

$_POST['pw'] = md5($_POST['pw']);

include "./config/config.php";

$db=dbconnect();

$query = "select id from user_db where id = '{$_POST[id]}' and pw = '{$_POST[pw]}'";

$result = mysqli_fetch_array(mysqli_query($db, $query));

if($result['id']) {

$_SESSION['site_id'] = $result['id'];

exit("<script>location.href='./main.php';</script>");

}

else exit("<script>alert('login fail'); history.go(-1);</script>");

}


index.php에 SQL 쿼리문이 위와 같이 되어 있다.
login 창에 다음과 같은 SQL Injection 코드를 넣어보자.
' or 1=1 #'

위와 같이 haha 라는 계정으로 로그인이 된다.

haha는 database에서 가장 처음에 입력된 계정이다. 즉, 데이터베이스에서 첫번째 id로 로그인됨을 알 수 있다.


admin으로 로그인하기 위해 다음과 같은 SQL Injection 코드를 넣어보자.

admin'#


위와 같이 admin으로 로그인이 된 것을 확인할 수 있다.


- 취약점 점검 방법


✓ SQL Injection 취약점을 이용하여 패스워드 없이 로그인이 가능한지 확인한다.

✓ 인수에 특수문자를 삽입하여 서버 내부에 명령 전달이 가능한지 확인한다.

✓ 외부 스크립트를 서버 내부에 삽입이 가능한지 확인한다.

✓ 시스템 명령어 삽입이 가능한지 확인한다.

✓ 관리자 ID와 패스워드에 아래 문자열을 입력하여 결과를 확인한다.


'or 1=1; --

' ' or 1=1--

"or 1=1 --

or 1=1--

'or 'a'='a

" or "a"="a

')or('a'='a

sql' or 1=1--

sql" or 1=1--

+ or 1=1--

';--



- 대응 조치


✓ 가능한 외부 인터프리터를 사용하지 않는다.

✓ 백엔드 데이터베이스 호출할 경우, 입력 값을 주의 깊게 검증한다.

✓ 데이터베이스와 연동을 하는 스크립트의 모든 파라미터들을 점검한다.

✓ 사용자 입력 시 특수문자( ', ", /, \, ;, :, -, + 등 )가 포함되어 있는지 검사한다.

✓ 웹 어플리케이션이 사용하는 데이터베이스 사용자의 권한을 제한한다.

Posted by Imp3rio
NCS보안3기/웹 해킹2017. 6. 8. 20:28

- 개요


웹 어플리케이션에서 많이 나타나는 취약점의 하나로 웹 사이트 관리자가 아닌 이가 웹 페이지에 악성 스크립트를 삽입할 수 이는 취약점이다. 주로 여러 사용자가 보게 되는 전자 게시판에 악성 스크립트가 담긴 글을 올리는 형태로 이루어진다. 이 취약점으로 해커가 사용자의 정보( 쿠키, 세션 등 )를 탈취하거나, 자옫ㅇ으로 비정상적인 기능을 수행하게 하거나 할 수 있다.



❑ 반사형( Reflected ) XSS

공격 스크립트가 삽입된 URL을 사용자가 쉽게 확인할 수 없도록 변형시킨 후 이메일이나 다른 웹 사이트 등에 클릭을 유도하도록 하는 방법


❑ 저장형( Stored ) XSS

스크립트를 웹 서버에 저장하여 일반 게시판 등에 공격자가 게시글에 스크립트를 삽입하여 사용자가 해당 페이지를 클릭하는 순간 스크립트가 실행되도록 하는 방법이다.



입력란에 다음 스크립트를 실행하면 아래 그림처럼 공격이 성공되는 것을 볼 수 있다.

<script>alert("XSS Test!!");</script>

- 취약점 점검 방법


✓ 게시판에 HTML 코드나 자바스크립트가 삽입 가능한지 확인한다.

✓ 사이트의 검색란에 HTML 코드나 자바스크립트가 삽입 가능한지 확인한다.

✓ 서버 에러 메시지를 조작하여 HTML 코드나 자바스크립트가 삽입 가능한지 확인한다.


- 대응조치


✓ 사용자용 게시판 등과 같은 매개체들에 사용자 입력값 검증루틴을 거친다.

✓ 어플리케이션 차원에서 HTTP 헤더, HTML, Javascript/VBScript, Flash, GIF/JPG, 쿠키, 쿼리 스트링, 폼 필드, 히든 필드 등의 모든 인자( Parameter )들에 대해 허용된 유형의 데이터만 입력할 수 있도록 한다.


입력 값 

수정 값 

입력 값 

수정 값 

&lt; 

&#41; 

&gt; 

&#35; 

&#40; 

&#38; 


- 필터링


strip_tags($content) : HTML 태그 제거하기


if($_SERVER['QUERY_STRING'] == "write"){

#echo "<script>console.log(\"$_POST[content]\");</script>";

if($_POST['content'])

$_POST['content'] = strip_tags($_POST['content']);

mysqli_query($db, "insert into board(`no`,`id`,`content`,`time`) values(null,'{$_SESSION[site_id]}','{$_POST[content]}',now())");

echo "<script>location.href='./main.php';</script>";

}


content에 값이 있으면 쿼리문을 만들기 전에 strip_tags() 함수를 이용해 HTML 태그를 제거한다.

아래 스크립트를 이용해 입력하면 다음 그림과 같이 공격이 수행되지 않음을 볼 수 있다.

<script>alert("XSS Test!!");</script>


htmlspecialchars($content) : 강제 URL Encoding

태그에 사용되는 특수문자( <, >, &, " )가 있으면 URL 인코딩한다.


if($_SERVER['QUERY_STRING'] == "write"){

#echo "<script>console.log(\"$_POST[content]\");</script>";

if($_POST['content'])

$_POST['content'] = htmlspecialchars($_POST['content']);

mysqli_query($db, "insert into board(`no`,`id`,`content`,`time`) values(null,'{$_SESSION[site_id]}','{$_POST[content]}',now())");

echo "<script>location.href='./main.php';</script>";

}


content에 값이 있으면 htmlspecialchars() 함수를 이용해 URL 인코딩한다.

아래 스크립트를 이용해 입력하면 다음 그림과 같이 공격이 수행되지 않음을 볼 수 있다.

<script>alert("XSS Test!!");</script>


str_replace("<", "<", $string) : 발견된 문자를 지정한 문자로 치환


if($_SERVER['QUERY_STRING'] == "write"){

#echo "<script>console.log(\"$_POST[content]\");</script>";

if($_POST['content']) {

$_POST['content'] = str_replace("<", "$lt;",$_POST['content']);

$_POST['content'] = str_replace(">", "$gt;",$_POST['content']);

}

mysqli_query($db, "insert into board(`no`,`id`,`content`,`time`) values(null,'{$_SESSION[site_id]}','{$_POST[content]}',now())");

echo "<script>location.href='./main.php';</script>";

}


위 코드는 만약 문자 < 또는 > 가 있을 때 강제로 변경해 주어 스크립트가 실행되지 않게 한다.

아래 스크립트를 이용해 입력하면 다음 그림과 같이 공격이 수행되지 않음을 볼 수 있다.

<script>alert("XSS Test!!");</script>


Posted by Imp3rio
NCS보안3기/웹 해킹2017. 6. 7. 21:19

테스트 페이지는 git을 이용해 다운로드 받는다.

그러기 위해 터미널을 열고 다음 명령어로 git을 설치한다.

sudo apt-get install git


git 설치가 완료되면 다음 명령으로 clone 한다.

git clone https://github.com/ppkill00/web_html_template


web_html_template 디렉터리 안에 있는 예제 파일을 /var/www/html 디렉터리 안에 옮겨야 한다.

그 전에 /var/www/html에 있는 index.html, index.php는 다음 명령어로 먼저 지우도록 하자.

sudo rm /var/www/html/index.html

sudo rm /var/www/html/index.php


다음 명령어로 web_html_template 디렉터리에 있는 모든 파일 및 디렉터리를 /var/www/html 디렉터리로 옮긴다.

sudo mv ./web_html_template/* /var/www/html


다음 명령으로 /var/www/html 디렉터리로 이동하자.

cd /var/www/html


index.php는 다음과 같이 수정한다.


index.php에서 user_db 라는 이름의 테이블과 board 라는 이름의 테이블을 사용하는 것을 볼 수 있다.

즉, MySQL에 user_db 테이블과 board 테이블이 있어야 한다.


main.php는 다음과 같이 생성한다.


/var/www/html/config 디렉터리에 있는 config.php는 다음과 같이 수정한다.


config.php에서 mysql 데이터베이스와 연동한다.

database는 "hack01"이고 user는 "root"이다.

password는 설정한 값을 적어주면 된다.


코드를 보고 MySQL 유저는 root가 있어야 하고, hack01 이라는 이름의 데이터베이스가 존재해야 하며 해당 데이터베이스 안에 user_db 테이블과 board 테이블이 있어야 한다.


터미널에서 다음 명령어로 MySQL 서버에 접속한다.

mysql -u root -p


패스워드를 입력하면 접속이 된다.


- hack01 데이터베이스 생성

mysql> create database hack01;


- hack01 데이터베이스 접속

mysql> use hack01


- user_db 테이블 생성

mysql> create table user_db(
            id varchar(32) character set utf32 collate utf32_unicode_ci not null,
            pw varchar(32) not null,
            authtime varchar(32) not null
            )ENGINE=InnoDB default charset=utf8;

- board 테이블 생성

mysql> create table board(
            no int unsigned not null primary key auto_increment,
            id varchar(32) character set utf32 collate utf32_unicode_ci not null,
            content text not null,
            time datetiem not null
            )ENGINE=InnoDB default charset=utf8;



- 파일 업로드 추가

mysql> alter table board add(filepath varchar(50));


데이터베이스 설정이 모두 완료가 되면 config.php에서 root 계정의 패스워드를 작성한다.


이로써 모든 구축은 완료가 되었다.

웹 브라우저로 127.0.0.1 에 접속해 보면 다음과 같은 페이지를 볼 수 있다.



join 버튼을 눌러 id, password를 작성하면 다음과 다음과 같이 main.php로 넘어간다.


입력창에 아무거나 입력하고 Write 버튼을 누르면 다음과 같은 화면을 볼 수 있다.



Posted by Imp3rio