
CVE-2021-44228의 log4j RCE를 핫패치하는 에이전트.
이 도구는 실행 중인 JVM 프로세스에 Java 에이전트를 주입하는 도구입니다. 에이전트는 로드된 모든 org.apache.logging.log4j.core.lookup.JndiLookup 인스턴스의 lookup() 메서드를 패치하여 무조건 문자열 "Patched JndiLookup::lookup()"을 반환하도록 시도합니다. 이 도구는 Java 프로세스를 재시작하지 않고 Log4j의 CVE-2021-44228 원격 코드 실행 취약점을 해결하기 위해 설계되었습니다. 이 도구는 CVE-2021-45046도 함께 해결합니다.
현재 Linux에서 JDK 8, 11, 15 및 17로만 테스트되었습니다!
Linux, Mac 및 Linux용 Windows 하위 시스템에서 빌드하려면:
./gradlew build
Windows에서 빌드하려면:
.\gradlew.bat build
빌드하는 플랫폼에 따라 build/libs/Log4jHotPatch.jar가 생성됩니다.
Maven을 사용하여 빌드하려면 다음을 사용하십시오:
mvn clean package
이렇게 하면 target/Log4jHotPatch.jar가 생성됩니다.
JDK 8
java -cp <java-home>/lib/tools.jar:Log4jHotPatch.jar Log4jHotPatch <java-pid>
JDK 11 이상
java -jar Log4jHotPatch.jar <java-pid>
다음과 같이 Java 명령줄에 에이전트를 추가하기만 하면 됩니다:
java -classpath <class-path> -javaagent:Log4jHotPatch.jar <main-class> <arguments>
Gradle이나 Maven 외부에서 실행할 수 있는 일련의 테스트가 있습니다.
build-tools/bin/run_tests.sh Log4jHotPatch.jar <JDK_ROOT>
다음과 같은 오류가 발생하면:
Exception in thread "main" com.sun.tools.attach.AttachNotSupportedException: The VM does not support the attach mechanism
at jdk.attach/sun.tools.attach.HotSpotAttachProvider.testAttachable(HotSpotAttachProvider.java:153)
at jdk.attach/sun.tools.attach.AttachProviderImpl.attachVirtualMachine(AttachProviderImpl.java:56)
at jdk.attach/com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:207)
at Log4jHotPatch.loadInstrumentationAgent(Log4jHotPatch.java:115)
at Log4jHotPatch.main(Log4jHotPatch.java:139)
이는 JVM이 -XX:+DisableAttachMechanism으로 실행 중이어서 모든 종류의 지원을 거부하고 있음을 의미합니다.
다음과 같은 오류가 발생하면:
com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:106)
at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
at Log4jHotPatch.loadInstrumentationAgent(Log4jHotPatch.java:182)
at Log4jHotPatch.main(Log4jHotPatch.java:259)
이는 대상 JVM과 다른 사용자(루트 포함)로 실행 중임을 의미합니다. JDK 8은 루트 사용자로 패치하는 것을 처리할 수 없으며(대상 JVM에서 무해한 스레드 덤프가 트리거됨) JDK 11에서는 루트 프로세스에서 비루트 프로세스를 패치하는 것이 정상적으로 작동합니다.
대상 프로세스에서 다음과 같은 오류가 발생하면:
Exception in thread "Attach Listener" java.lang.ExceptionInInitializerError
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:386)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:411)
Caused by: java.security.AccessControlException: access denied ("java.util.PropertyPermission" "log4jFixerAgentVersion" "write")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:886)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.System.setProperty(System.java:794)
at Log4jHotPatch.<clinit>(Log4jHotPatch.java:66)
이는 대상 프로세스에 보안 관리자(security manager)가 설치되어 있음을 의미합니다. 대상 프로세스에서 다음 명령줄 옵션을 찾아보십시오:
-Djava.security.policy=/local/apollo/.../apollo-security.policy
이 오류가 발생하면 최신 버전의 도구를 사용하고 있는지 확인하십시오.
중요: 잘못된 사용자로 패치를 시도한 경우 다시 시도하기 전에 .attach_pid<pid> 파일(/tmp 및/또는 VM 프로세스의 CWD에서 찾을 수 있음)을 삭제해야 할 수 있습니다. attach가 성공하려면 이러한 파일의 소유권이 올바르게 설정되어 있어야 합니다.