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
NCS보안3기/웹 해킹2017. 6. 7. 19:56

대략적인 서버구축에 필요한 OS, 및 소프트웨어는 다음과 같다.


➢ Parallels 가상머신

➢ Ubuntu 16.04 LTS 버전의 리눅스

➢ Apache 웹 서버

➢ MySQL 데이터베이스 서버 & 클라이언트

➢ php


필자는 Mac을 사용하기 때문에 주로 사용하는 Virtual Machine인 Parallels를 이용한다. 윈도우를 이용하는 방문자는 VMware player 또는 Virtual Box를 이용하도록 한다.


우선 가상머신에 Ubuntu 16.04 LTS 버전의 리눅스를 설치하기 위해 OS를 다운받는다.( LINK )

* 리눅스는 오픈소스 기반 운영체제로 무료로 다운받아 설치할 수 있다.


ios 파일을 다운로드 받은 후 가상머신을 실행하여 Ubuntu를 설치한다.










VMware Fusion에서 설치할 경우의 모습이며 대부분 이와 비슷하게 구성되어 있다.

[Install from disc or image]를 클릭해 다운받은 iso 파일을 선택하여 설치하면 된다.








Parallels에서 설치할 경우의 모습이며, Parallels를 사용할 경우 iso를 다운받을 필요 없이 가상머신에서 바로 다운로드하여 설치할 수 있다.

iso 파일이 있을 경우

[DVD 또는 이미지 파일의 Windows나 다른 OS 설치]를 클릭해 설치하고, iso 파일이 없을 경우 아래 [무료리스템]-[Ubuntu]를 클릭해 설치한다.






설치를 완료하면, Ubuntu를 구동시킨 다음 왼쪽 상단에 우분투 로고를 클릭하여 "terminal"을 실행시킨다.


계정을 방금 만들었기 때문에 root 계정에 대한 비밀번호가 설정되지 않았다. 다음 명령어를 이용해 root의 비밀번호를 설정한다.

sudo passwd root


계정의 비밀번호를 입력하면 root 계정의 비밀번호를 설정할 수 있다.


root 비밀번호 설정이 완료가 되면 다음 명령어를 이용해 apt-get을 업데이트 및 업그레이드 한다.

sudo apt-get update

sudo apt-get upgrade


업데이트 및 업그레이드가 완료되면 apache 웹서버를 다운받기 위해 다음 명령어를 실행한다.

sudo apt-get install apache2


MySQL 서버와 클라이언트를 다운받기 위해 다음 명령을 실행한다.

sudo apt-get install mysql-server mysql-client


php를 설치하기 위해 다음 명령을 실행한다.

sudo apt-get install phpmyadmin


혹시 중간에 dpkg 에러가 발생하게 되면 LINK 를 보고 해결하기 바란다.


설치를 마친 후 브라우저를 이용해 127.0.0.1 ( localhost )에 접속하면 다음과 같은 화면을 볼 수 있다.



위 화면이 확인되면 apache와 php가 제대로 설치된 것이다.


이로써 서버 구축을 위한 기본적인 준비를 마쳤다.

다음엔 데이터베이스를 설정하고 실제 php를 이용해 웹 페이지를 작성한다.


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

- 웹 어플리케이션이란 ?


웹 기반 소프트웨어로써 ( 기능적으로 ) 사용자 입력을 기반으로 동작하고, 종종 이면의 시스템과 상호작용하는 일체의 웹 기반 소프트웨어라고 한다. 즉, 사용자가 웹 사이트와 상호작용하여 로그인하든가 쇼핑이나 전자 금융거래를 한다면 그것이 바로 웹 어플리케이션이다.


- 웹 서버에 대해 알아야 할 것


웹 서버는 서버의 운영체제 위에서 돌아가는 한 뭉치의 소프트웨어일 뿐이며 웹 어플리케이션이 접근하는 것을 허용한다. 가장 대표적인 웹 서버는 윈도우 서버에서의 인터넷 정보 서비스( IIS )와 리눅스 서버에서의 아파치( HTTP )가 있다. 이러한 서버들은 일반적인 컴퓨터와 같은 디렉터리 구조를 갖고 있는데, 바로 그 곳에 웹 어플리케이션이 자리잡는다.


윈도우에서 IIS 웹 서버를 설치하면 C:/Inetpub/wwwroot 디렉터리에 설치되며, wwwroot 다음 응용 프로그램이 각각의 디렉터리를 가지며 그 속에 모든 중요한 웹 어플리케이션의 자원이 포함된다.


리눅스는 대개의 웹 어플리케이션이 /var/www/ 디렉터리에 위치한다. 리눅스 웹 서버에서는 다음과 같이 특별히 웹 해킹과 관련된 몇 개의 디렉터리가 있다.


/ect/shadow : 이 파일에 시스템의 모든 사용자 비밀번호 해쉬 값이 저장된다.

/usr/lib : 이 디렉터리에는 일반 사용자나 쉘 스크립트로 실행되지 않는 오브젝트 파일내부 바이너리

                  를 포함한다. 또한 응용 프로그램에서 사용하는 모든 의존성 데이터 역시 이 디렉터리에 있다.

/var/* : 이 디렉터리에는 데이터베이스에 관련된 파일, 시스템 로그, 웹 어플리케이션 자체의 소스코드

                가 있다.

/bin : 이 디렉터리는 쉘, ls, grep 과 같은 프로그램은 물론이고 시스템이 동작하는 데 필요한 기본적이

             고 중요한 실행 파일을 갖고 있다.


- HTTP에 대해 알아야 할 것


HTTP는 웹 어플리케이션과 상호 동작하고 통신하는 것으로 합의된 프로세스다. HTTP 프로토콜은 상태를 관리하지 않는 프로토콜이므로 이전의 요청 상황을 알지 못한다. 따라서 모든 클라이언트의 요청과 웹 어플리케이션의 응답은 완전히 새롭고 독립적인 사건일 뿐이다.


❍ HTTP 사이클

브라우저는 사용자가 입력한 값을 매개변수에 담아 요청으로 보내면 웹 서버는 제출된 요청이 지시하는 응답을 회신한다. 웹 어플리케이션은 매개변수 값에 근거하여 동작하기 때문에 해커가 웹 어플리케이션과 웹 서버를 공격할 때 악의적인 값을 입력하여 공격하는 가장 중요한 목표물이 된다.


❍ HTTP 헤더

❑ 웹 서버가 설정해서 클라이언트 브라우저에 보내주는 주요 헤더 정보

Set-Cookie : 이 값은 사용자의 세션이 유지되도록 보장하기 위하여 가장 흔하게 클라이언트에 제

                        공하는 세션 식별자( 쿠키 )다.

Content-Length : 이 값은 응답문의 바이트 단위 길이다.

Location : 이 값은 응용프로그램이 사용자를 다른 페이지로 보낼 때 사용된다.


❑ 클라이언트 브라우저가 웹 서버에 보내는 주요 헤더 정보

Cookie : 하나( 또는 여러 개 )의 쿠키는 사용자의 세션을 유지하기 위해 헤더에 담겨 서버로 되돌

                  려 보내진다. 이 쿠키의 헤더 값은 서버가 set-cookie로 발행한 헤더 값과 언제나 일치해

                  야한다. 이 값은 응용프로그램의 유효한 세션 값을 제공하므로 다른 응용프로그램 사용자

                  를 공격할 때 사용할 수 있다.

Referrer : 이 헤더 값은 다른 웹 페이지를 요청할 때 이전에 열었던 페이지를 목록으로 만든다. 이 

                    헤더 값은 곧 "마지막으로 방문한 페이지"를 뜻하며, 이 값은 쉽게 바꿀 수 있다.


HTTP 상태 코드

100번대 : 웹 서버가 순수하게 정보를 알려주기 위한 것으로, 보통 웹 서버가 보충 응답을 보낼 것임을 

                    나타낸다.

200번대 : 클라이언트의 요청이 성공적으로 접수되고 웹 서버가 처리한 다음 그 응답이 브라우저로 되

                    돌려 보내졌음을 뜻한다.

300번대 : 다른 페이지로 돌리는 경우 표시한다. 사용자가 웹 어플리케이션에 성공적으로 인증한 후에 

                    브라우저를 안전한 페이지로 전달할 때 가장 많이 사용된다.

400번대 : 클라이언트로부터 온 요청에 오류가 있음을 나타낸다. 즉, 사용자가 보낸 요청을 웹 어플리케

                    이션이 처리할 수 없음을 뜻한다.

500번대 : 서버 측의 오류를 표시한다.

Posted by Imp3rio