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

- DOS Stub Code


DOS Stub Code는 필수 구성 요소가 아니기 때문에 DOS Stub Code가 없더라도 프로그램이 실행되는 데는 아무런 지장이 없다. 

DOs Stub Code는 도스 모드에서 실행시켰을 때 실행되는 코드이며, 보통 "This Program must be run under Microsoft Windows"라는 메시지를 출력하고 종료되는 코드가 삽입된다. 또는 오브젝트 파일을 링킹할 때 STUB 옵션을 이용하여 원하는 스텁 코드를 삽입할 수 있다는 점 정도만 알아두면 된다.


- PE 만들기 1

PE 파일 제작의 첫번째 단계는 DOS Header를 만들기다.

Hex 에디터를 열고 64바이트의 새 파일을 생성한다. ( 필자는 HxD를 이용한다 )













[편집]-[바이트 삽입] 메뉴를 선택하고 64바이트를 생성한다.




[그림 1] 64 바이트 크기의 새로운 파일 생성


[그림 2]와 같이 처음 2 바이트 부분의 값을 "4D 5A"로 수정한다. 이는 DOS Header의 시그니처인 MZ를 의미한다.


[그림 2] DOS 시그니처 입력


[그림 3]과 같이 마지막 4바이트의 값을 0x40으로 설정한다. DOS Stub Code는 생략이 가능하기 때문에 생략하도록 한다. 즉, DOS Header 다음에 바로 PE Header가 온다. 그리고 기본적으로 리틀엔디안 방식이므로 40 00 00 00으로 입력해야 한다.

[그림 3] PE Header의 시작 지점을 지정


이 파일은 계속 사용해야 하기 때문에 CreatePE라는 이름으로 저장한다.



참고

http://zesrever.tistory.com

'NCS보안3기 > 리버스 엔지니어링' 카테고리의 다른 글

[Reverse Engineering] PE 구조  (0) 2017.05.22
Posted by Imp3rio

1. PE란 ?


PE( Portable Executable )는 윈도우 운영체제에서 사용되는 실행파일, DLL, object 코드 등을 위한 파일형식이다. 이는 윈도우 로더가 실행 가능한 코드를 관리하는데 필요한 정보를 캡슐화한 데이터 구조체이다.



2. PE 구성요소



PE는 위와 같은 구조를 갖고 있으며, DOS stub은 PE 파일의 필수 구성요소가 아니기 때문에 생략이 가능하다.


- DOS Header

PE 파일은 DOS Header로 시작한다. 따라서 디스크 상에서는 파일의 첫 부분이 DOS header가 된다. 메모리 상에서 PE 파일은 ImageBase에서 시작하기 때문에 DOS header는 ImageBase에서 찾을 수 있다.

stud_PE 프로그램으로 Test.exe 파일을 열었을 때 확인할 수 있는 PE 헤더의 일부분이다.

실제로 해당 위치에 존재하는지 Immunity Debugger로 확인을 하면 다음과 같다.

00400000 번지에 MZ 문자가 찍혀있는 것을 볼 수 있다.

MZ는 DOS Header의 시그니처다. 이로써 메모리에 Image base에 DOS Header가 로드됨을 알 수 있다.


- DOS stub

윈도우용 어플리케이션을 도스 모드에서 실행시킨 경우 어플리케이션이 정상적으로 동작하지 않는다. 이러한 경우 윈도우는 어플리케이션 대신에 스텁 코드를 실행한다. 스텁 코드에는 DOS 모드에서 실행 가능한 프로그램이면 어느 것이나 삽입이 가능하다. 


- PE Header

PE Header는 위와 같은 구조체로 정의되어 있다.

디스크 상이나 메모리 상에서 PE 헤더의 위치는 DOS Header에 있는 e_lfanew 값을 이용하여 계산할 수 있다. e_lfanew는 DOS Header구조체의 마지막에 위치한다.

e_lfanew에는 파일의 시작점에서부터 PE 헤더까지의 오프셋 값이 저장되어 있다.

Hex 에디터로 열어보게 되면 위와 같이 DOS Header 마지막에 e_lfanew 값이 들어 있고, 이 값과 DOS Header의 시작 주소를 더하면 PE Header를 찾을 수 있다.


- 섹션 테이블

섹션 테이블은 PE Header 바로 뒤에 위치한다. 즉, 섹션 테이블을 찾으려면 PE Header 시작 주소에서 PE Header 사이즈를 더해주면 된다.

PE 헤더는 PE 시그너처( 4바이트 고정 )와 File Header( 20바이트 고정 ) 그리고 Optional Header( 224바이트, 가변 )로 구성되어 있다. Option Header의 크기는 File Header에 저장되어 있다.


- 섹션 위치

각 섹션의 위치는 섹션 테이블에 저장된 섹션 헤더를 통해서 확인이 가능하다. 섹션 헤더에는 해당 섹션의 위치와 관련하여 Virtual Address라는 값과 PointerToRawData라는 값이 저장되어 있다. PointerToRawData는 디스크 상의 섹션의 위치를 가리키는 offset 값이고, VirtualAddress는 메모리 상에서의 section의 위치를 가리키는 offset 값이다.

Stud_PE로 Section Header를 보면 위와 같다.

.text 섹션의 RawOffset 값이 0x200임을 알 수 있다. 이는 디스크 상의 .text 섹션이 파일의 시작점으로부터 0x200 떨어진 곳에서 시작한다는 것을 의미한다.

마우스 오른쪽 클릭한 후 "GoTo Section Start"를 선택하면 .text 섹션의 시작 위치로 이동할 수 있다.

Cursor를 첫번째 바이트에 위치하고 하단 정보를 확인하면 Cursor offset이 앞서 살펴본 PointerToRawData 값과 같음을 확인할 수 있다. Virtual offset 값은 ImageBase 값인 0x400000에 Virtual offset 값인 0x1000을 더하면 된다.

Immunity Debugger로 보면 위와 같다. 


* PE 파일은 디스크 상의 모습과 메모리 상의 모습이 거의 같다.


DOS Header에서 Section table까지의 구성은 디스크 상의 PE 파일이나 메모리 상의 PE 파일 모두 동일하다. 이는 디스크 상의 PE 파일이 메모리로 로드될 때 DOS Header부터 Section table까지는 그대로 로드됨을 의미한다. 차이가 발생하는 부분은 각 세션인데, 이는 alignment와 관련이 있다. alignment와 관련해서 기억해야 할 사실은 아래와 같다.


> 섹션들의 디스크 상의 정렬 단위와 메모리 상의 정렬단위가 다를 수 있다.

> 디스크 상의 정렬 단위와 메모리 상의 정렬 단위는 각각 Optional Header의 File Alignment와 Section Alignment에 저장된다.

> 디스크 상의 섹션은 File Alignment의 배수가 되는 주소에서 시작한다.

> 메모리 상의 섹션은 Section Alignment의 배수가 되는 주소에서 시작한다.



참고

http://zesrever.tistory.com

Posted by Imp3rio

스택 버퍼 오버플로우 공격은 모든 경우에 가능하지 않고 프로그래머가 취약한 특정 함수를 사용해야 가능하다. 다음 예를 통해 스택 버퍼 오버플로우 공격을 실습해보자.


stack1.c 파일을 다음과 같이 작성을 하고 다음 명령으로 컴파일을 한다.

gcc -o stack1 stack1.c -m32 -fno-stack-protector 

그러면 위와 같이 stack1 실행파일이 생성된다.


먼저 stack1.c의 코드를 분석하면 다음과 같다.

1. modified 변수와 buffer 변수가 있다.

2. buffer의 크기는 64바이트이다.

3. 프로그램을 실행할 때 인자가 없으면 에러를 뱉어내고 종료한다.

4. modified 변수를 0으로 초기화한다.

5. 실행 시 받은 인자를 buffer에 복사한다.

6. modified의 값이 0x61626364이면 공격 성공

7. 그렇지 않으면 공격 실패


분석을 통해 알아낸 것은 modified 변수의 값은 절대 0x61626364 값을 가질 수 없는데 이 값을 가지고 분기를 한다는 사실과 buffer의 값을 프로그램 실행 시 입력을 받는 다는 것 그리고 buffer의 크기가 64바이트라는 것이다.

즉, buffer에 오버플로우를 일으켜 modified 변수를 변조시켜야 한다는 것이다.

다음 명령으로 공격을 해보자.

./stack1 `python -c 'print "A"*64 + "dcba"'`


공격이 성공한 것을 확인할 수 있다.


왜 이러한 현상이 발생하는지 그 원리를 살펴보도록 하자.

위 코드에서 strcpy로 buffer에 데이터를 저장한 뒤의 스택 상황은 위와 같다.

buffer에 64바이트 만큼 A가 채워지고 dcba가 modified 영역에 저장이 된다.

즉, 오버플로우가 발생해서 다른 변수에 영향을 주는 것이다.


이렇듯 strcpy와 같이 오버플로우에 취약한 함수를 사용하는 프로그램에 대해 버퍼 오버플로우 공격을 수행할 수 있다.

'NCS보안3기 > 시스템 해킹' 카테고리의 다른 글

[System Hacking] 메모리  (0) 2017.05.16
[System Hacking] CPU와 레지스터  (0) 2017.05.16
[System Hacking] 운영체제  (0) 2017.05.15
Posted by Imp3rio

- 스택


" 후입선출( LIFO : Last In First Out ) 방식에 의해 정보를 관리하는 데이터 구조. 스택에는 TOP이라고 불리는 스택의 끝부분에서 데이터의 삽입과 삭제가 발생한다. 즉, 스택에 데이터를 삽입하면 TOP 위치에 정보가 위치한다. 그리고 스택에서 정보를 읽어오려 하면 스택의 TOP 위치에 있는 정보가 반환된다. 따라서 스택에는 가장 나중에 삽입된 정보가 가장 먼저 읽히는 특징이 있다. "


컴퓨터 메모리상의 스택은 프로그램의 함수 내에서 정의되는데, 함수 종료와 동시에 사라지는 자동 변수가 저장되고 함수가 호출될 때 함수 내 로컬 변수 등이 저장되는 곳이다. 스택에 저장된 로컬 변수는 함수가 실행되는 동안만 존재하며 함수 실행이 종료되면 해당 변수들도 사라진다.


- 힙


" 프로그램의 실행 중 필요한 기억 장소를 할당하기 위해 운영체제에 예약되어 있는 기억 장소 영역. 프로그램 실행 중에 데이터를 저장하기 위해 기억 장소를 요청하면 운영체제는 힙에 존재하는 기억 장소를 프로그램에 할당한다. 프로그램에서는 기억 장치가 더 이상 필요 없으면 할당받았던 기억 장소를 운영체제에 반납하는데, 이때 운영체제에서는 반납된 기억 장소를 다시 힙에 돌려준다. 힙에 대한 기억 장소는 포인터를 통해 동적으로 할당되거나 반환되며 연결 리스트, 트리, 그래프처럼 동적인 특성이 있는 데이터 구조에서 널리 사용된다. "


힙은 프로그램이 실행될 때까지 미리 알 수 없는 가변적인 양의 데이터를 저장하기 위해, 프로그램의 프로세스가 사용할 수 있도록 예약되어 있는 메인 메모리의 영역이다. 


- 데이터 세그먼트


초기화된 데이터 세그먼트라고도 불리며, 초기화된 외부 변수나 static 변수 등이 저장되는 영역이다. 


- BSS 세그먼트


초기화되지 않은 데이터 세그먼트라고도 불리며, 프로그램이 실행될 때 0이나 NULL 포인터로 초기화되는 영역이다. 


- 텍스트 세그먼트


CPU에 의해 실행되는 머신 코드가 있는 영역으로, EIP가 다음에 실행하는 명령을 가리키고 있다.

'NCS보안3기 > 시스템 해킹' 카테고리의 다른 글

[System Hacking] Stack Buffer Overflow  (0) 2017.05.16
[System Hacking] CPU와 레지스터  (0) 2017.05.16
[System Hacking] 운영체제  (0) 2017.05.15
Posted by Imp3rio


- 연산장치( ALU : Arithmetic and Logic Unit )

연산장치는 CPU의 핵심 부분 중 하나로, 산술과 논리 연산을 수행하는 연산 회로 집합으로 구성된다.


   구성요소

 기능

 내부

 장치

 가산기

 덧셈 연산 수행

 보수기

 뺄셈 연산 수행, 1의 보수나 2의 보수 방식 이용

 시프터

 비트를 오른쪽이나 왼쪽으로 이동하여 나눗셈과 곱셈 연산 수행

 관련

 레지

 스터

 누산기

 연산의 중간 결과 저장

 데이터 레지스터

 연산에 사용할 데이터 저장

 상태 레지스터

 연산 실행결과로 나타나는 양수와 음수, 자리올림, 오버플로우의 상태 기억


- 제어장치( Control Unit )

제어장치는 입력, 출력, 기억, 연산 장치를 제어하고 감시하며, 주기억 장치에 저장된 명령을 차례로 해독하여 연산 장치로 보내 처리되도록 지시한다.


  구성요소

 기능

 내부

 장치

 명령 해독기

 명령 레지스터에 있는 명령을 해독하여 부호기로 전송

 부호기

 명령 해독기가 전송한 명령을 신호로 만들어 각 장치로 전송

 주소 해독기

 명령 레지스터에 있는 주소를 해독하여 메모리의 실제 주소로 변환한 후, 

 이를 데이터 레지스터에 저장

 관련

 레지

 스터

 프로그램 카운터

 다음에 실행할 명령의 주소 저장

 명령 레지스터

 현재 실행 중인 명령 저장

 메모리 주소 레지스터

 주기억 장치의 번지 저장

 메모리 버퍼 레지스터

 메모리 주소 레지스터에 저장된 주소의 실제 내용 저장


- 레지스터

레지스터는 처리 중인 데이터나 처리 결과를 임시 보관하는 CPU 내의 기억 장치로, 대개 연산 장치나 제어 장치에 함께 포함되어 있다.



- 레지스터 종류

1. 범용 레지스터

범용 레지스터는 연산 장치가 수행한 계산 결과의 임시 저장, 산술 및 논리 연산, 주소 색인 등의 여러 목적으로 사용될 수 있는 레지스터이며, EAX, EBX, ECX, EDX 등이 있다.


> EAX

입출력과 대부분 산술 연산에 사용된다.

다른 레지스터보다 EAX를 사용하면 더 효율적인 기계코드를 생성하는 명령어도 있다.


> EBX

DS 세그먼트에 대한 포인터를 주로 저장하며, ESI나 EDI와 결합하여 인덱스에 사용된다.

메모리의 주소 지정을 확장하기 위해 인덱스로 사용될 수 있는 유일한 범용 레지스터다.


> ECX

루프가 반복되는 횟수를 제어하는 값, 왼쪽이나 오른쪽으로 이동되는 비트 수 등을 포함할 수 있다.


> EDX

입출력 연산에 사용하며 큰 수의 곱셈과 나눗셈 연산에서 EAX와 함께 사용된다.



2. 세그먼트 레지스터

세그먼트는 프로그램에 정의된 메모리상의 특정 영역으로, 코드, 데이터, 스택 등을 포함하며, 메모리의 대부분에 위치할 수 있다.


> CS( Code Segment )

코드 세그먼트는 실행될 기계 명령을 포함한다.

코드 세그먼트의 시작 주소를 가리키며, 일반 프로그래밍에서는 이 레지스터를 직접 참조할 필요가 없다.


> DS( Data Segment )

프로그램에 정의된 데이터, 상수, 작업 영역을 포함한다.

데이터 세그먼트의 시작 주소를 가리키는데, 프로그램은 참조하려는 데이터의 오프셋을 DS 레지스터에 저장된 주소 값에 더해 데이터 세그먼트 내에 위치해 있는 데이터의 주소를 참조한다.


> SS( Stack Segment )

프로그램이 실행될 때, 실행 과정에서 필요한 데이터나 연산 결과 등을 임시로 저장하거나 삭제할 때 사용된다.


> ES, FS, GS

메모리 주소 지정을 다루는 스트링 연산에 사용되고, EDI 레지스터와 함께 사용된다.



3. 포인터 레지스터

포인터 레지스터는 프로그램 실행 과정에서 사용되는 주요 메모리 주소값을 저장한다.


> EBP

스택 세그먼트에서 현재 호출되어 사용되는 함수의 시작 주소 값을 저장한다.

함수로 전달되는 지역변수 등을 참조할 때 기준이 되며, ESP 레지스터와 함께 사용되어 스택 프레임을 형성한다.


> ESP

현재 스택 영역에서 가장 하위 주소를 저장한다.

스택은 상위 주소에서 하위 주소로 이동하며 데이터를 저장하므로 스택이 확장되면 스택 포인터도 상위 주소에서 하위주소로 값이 변경된다.


> EIP

다음에 실행될 명령의 오프셋을 포함한다.

현재 실행 중인 코드 세그먼트에 속한 현재 명령을 가리킨다.



4. 인덱스 레지스터

인덱스 레지스터는 데이터를 복사할 때 출발지와 목적지 주소를 각각 가리키는 레지스터로 사용된다.


> ESI & EDI

주로 메모리의 한 영역에서 다른 영역으로 데이터를 연속적으로 복사할 때 사용된다.


5. 플래그 레지스터

크기가 32비트로, 컴퓨터의 다양한 상태를 나타내는 비트를 포함한다.


> 상태 플래그

상태플래그는 산술 명령 결과를 반영한다.

- CF : 산술 연산 결과로 자리올림이나 자리내림이 발생할 때 세트된다.

- ZF : 산술 연산 결과가 0이면 세트된다.

- OF : 부호가 있는 수의 오버플로우가 발생하거나 MSB가 변경되었을 때 세트된다.

- PF : 산술 연산 결과가 짝수면 세트된다.

- AF : 8비트 피연산자를 사용한 산술 연산에서 비트 3에서 비트 4로 자리올림이 발생하면 세트된다.

- SF : 산술 및 논리 연산의 결과로 음수가 생기면 세트된다.


> 제어 플래그

DF는 스트링 명령을 제어한다. 

DF가 1이면 스트링 명령은 자동 감소된다. 

DF가 0이면 스트링 명령은 자동 증가된다.


> 시스템 플래그

시스템 플래그는 운영체제나 장치 드라이버를 제어한다.

'NCS보안3기 > 시스템 해킹' 카테고리의 다른 글

[System Hacking] Stack Buffer Overflow  (0) 2017.05.16
[System Hacking] 메모리  (0) 2017.05.16
[System Hacking] 운영체제  (0) 2017.05.15
Posted by Imp3rio