little_trick
web的第一道题
打开以后是php的代码
解读一下这段代码
1.先用GET接收两个变量,变量名为nep,len
2.判断这两个变量,若判断为真,则执行eval()函数,否则,输出too long 结束
3.总之就是不能让它输出too long呗
所以先分析一下这里涉及的四个函数intval()、strlen()、eval()、substr()
intval($len):这个函数的意思是取$len的十进制数值(比如十六进制、八进制变成十进制,10abc——>10,abc10——>0),intval($len)<8我们暂时可以直接当成$len<8。
strlen():相当于c++的strlen,就是计算字符长度
eval():把括号里的文字作为php代码运行
substr($nep,0,$len):就是从$nep中截取字符段,第二个数字表示从第几位开始截取,0的意思是从第一个字开始,后面的$len意思是截取多少个字符(但是这个量分正负,正数就是从正向开始截取几个字符,负数就是从最后数少截取几个字符)
所以通篇读下来就是$len<=7,字符串$nep长度<=12
然后从$nep中截取$len个字符并运行。
那么似乎只能截取7个字符,那$nep再长没用
没什么思路,所以从绕过两个字数限制开始吧。
首先搜了一下绕过intval()的
发现了这篇文章
https://blog.csdn.net/weixin_43536759/article/details/106785184
其中列出了溢出和一个“var_dump(intval(‘0xa’+1)) //int(11)数值形式输入(此漏洞php7被修复)”这样的漏洞
试验了一下,都没用
但是,我前面说过,$len在substr($nep,0,$len)函数中是可以取负值的。
所以我试了一下传入len=-1,因为这样会舍弃$nep的最后一个字符,所以我需要在nep最后加一个“废字符”(这里用a)
所以最后的传值就是len=-1&nep=phpinfo();a(顺便看一下php的配置)
效果如下:
这之后发现php版本大于7,怪不得前面那个漏洞用不了。
到这,对len的绕过算是结束了,可运行php代码的数量扩充到了12(但是要补一个废字符a,所以相当于11)
strlen()我是实在没找到能绕过的地方,就此作罢。
之后,就没思路了……
还好这时这道题突然崩了,然后看见群里有人反馈他做完题后不小心rm -rf / *
了一下,把一开始的静态环境弄炸了(夺笋呐)
等恢复(换成靶机)的这段时间里想到了用shell
(刚刚的phpinfo()顺便得到了是linux系统)
然后就搜了一下让php实现shell的方法
最常见的是以下三种函数:
1.system
2.exec
3.passthru
但都太长了,根本不可能使用(因为还要加上;a)(其实后来想想,exec或许可以)
之后我找到了一种最简便的方法——``(用反引号括起来)
然后我尝试了len=-1&nep=echo `ls`;a(echo相当于输出shell的回显)
发现真的有回显
回显显示了一个文件nepctf.php
先尝试打开它
发现是个空白页
那么flag很有可能在这个文件里
为了读这个文件,我尝试了很多方法(以下为试错笔记,以此来记录一些好方法,只想看这道题的可以直接跳到下面的“正确方法”)
首先想到的是限制字符的shell
因此搜到了这个————
http://www.bubuko.com/infodetail-3316599.html
乍一看我这个是12字符,完全可以用7字符的方法,建一个a文件
然后通过”echo (字符) >>a”的方式来完成,然后通过sh a来运行shell,甚至可以写木马了
但事实上无论是哪种数量,都是在直接写shell的情况下计算的
如果补` `;a的话,就变成了`echo n>>a`;a(假设向a文件里输入n,也就是最小的输入量)
这都有13个字符了,直接超标
所以实际上我只能用4字符的方法
而四字符的方法,是通过\号实现shell转译,来实现多行的输入
再通过> v,以及*v来倒叙读取这些代码来运行
但是这就要保证代码的完整性的同时还要兼顾“反序”,网上有写脚本来输入验证完整性的
但我不会python,所以只能用burpsuite实现一次性输入
事实上,因为我看不到回显的缘故,我甚至不知道每次的``是否在同一个命令框,还是打开了一个新的命令框
最后反正是失败了
正确方法!!!
简化代码,想到linux下文件可以用简化
比如nepctf.php 可以直接简化为n
但是无论如何echo `cat n*`;a是字数超标的
所以想到:nepctf.php之所以是空白面,是因为电脑用php来读取它,所以没有回显
那么,把它的内容转移到没有后缀的新文件是不是就可以看到了呢
所以用参数len=-1&nep=`cp 1 n*`;a(相当于把n*文件(这里也就是nepctf.php)的内容写入文件名为1的文件中,如果没有就创一个)
然后ls一下,看见1文件已被创立
然后访问1文件,得到flag