supersqli
看题目得知是SQL注入题
提交单引号报错,说明可能存在注入,单引号后加’--’,报错,说明网站已将其过滤,换#号,没报错,说明#注释符可用。
加语句‘order by 2#未报错
使用select时发现某些关键字被过滤,preg_match()函数作用为正则表达式匹配,’\.’中\为转义符,.在正则表达式中代表任一符号,转义后即代表本身。i代表匹配模式为大小写不敏感。
因此需要将所用关键字绕过,使用union注入时发现大小写、注释、不等号等绕过方式都不行,因此考虑到堆叠查询,通过show语句我们可以查到藏有flag的文件的位置。
但是由于select被过滤了,因此需要其他方式获得flag中的内容。
方法一:
由图可知该数据库默认查询的表是words,故将所需查询表的表名换成words,即可通过默认查询表的设定获取flag
此时需要用到rename语句,语法为rename table old to new;
但是还需将flag的字段名改为id,alter table `words` change `flag` `id` varchar(100);在靶场试验修改字段名后发现靶场瘫痪了,输入什么语句都不起反应了,搞不懂具体原因,先存疑。
法2:预编译
由于网站将select过滤了,所以可以思考如何将其绕过
在此介绍set、prepare语句
set语句可以将变量赋值,格式为set @value=xxx
prepare语句可以将某条指定语句赋予某文本,格式为 prepare txt from select....
那么txt即代表select....语句,execute txt即可执行select...语句
根据这两个语句的特性,set @sql=concat(‘s’,’elect * from `1919810931114514`;)通过该语句,先将select * from `1919810931114514` 语句分为两个字符串,从而绕过过滤,再利用concat函数的特性将两个字符串合并,再将其赋予变量@sql
再进行预编译 prepare sq from @sql;
最后将sq执行:execute sq;
warmup
找到source.php文件的代码,大致分为两部分,第一部分定义了类emmm,第二部分是一个if语句,先分析if语句
$_REQEUST:可以获得post、get的参数,但缺点是速度慢
empty():检查变量是否为空,!即非。
is_string():检测变量是否为字符串
再看第一部分的代码
isset():检测函数是否已设置
In_array($txt,$array):在array数组中检测是否有txt
mb_substr($str,a,b):获取部分字符串,在字符串str中的第a位开始获取b位
mb_strpos($str1,$str2),查询str1中str2出现的第一个字符位置
&为引用符,可以改变
过程:将$page传入函数,第一个if语句检测$page是否已经设置且为字符串,不是则返回false。
第二个if语句检测$page中是否有whitelist中规定的内容,有则退出方法且返回true。
再通过mb_substr截取?前的字符串(若$page不含字符串则截取全部)存入$_page中
第三个if语句作用同第二个
通过urldecode()函数将$_page进行url解码
再通过mb_substr()函数截取$_page字符串中?前的部分存入$_page中
最后进行if语句检测,作用同上
据题意可知需要通过file变量上传文件路径,且checkFile函数返回true,即可通过include函数查询文件内容
在第二个if语句时,由于file参数必须包含ffffllllaaaagggg文件路径才能使include函数进行查询,因此该语句肯定无法通过
再通过mb_substr()函数截取?前的部分,此时可以想到构造source.php?......(文件路径)的语句将路径绕过白名单检测。
根据include函数的功能,以字符‘/’分隔(而且不计个数),若是在前面的字符串所代表的文件无法被PHP找到,则PHP会自动包含‘/’后面的文件——注意是最后一个‘/’。可以发现若输入source.php?/../../../../ffffllllaaaagggg时会将第一个../前的代码忽略
unserialize3
此题考查序列化与反序列化相关内容
先了解魔术方法:
魔术方法以’__’作为开头,当php文件进行到某些特定时刻时将被自动调用,方法本身无任何作用,需要自己事先规定方法内容。
__wakeup()特性:若对象的属性个数与真实属性个数相同则执行,若不相同则跳过。
将对象xctf序列化可得O:1:"xctf":1:{s:4:"flag";s:3:"111";}
通过code函数传参,?code=O:1:"xctf":1:{s:4:"flag";s:3:"111";},即可得到”bad requests”返回
说明在反序列化该对象前调用了__wakeup()方法,直接执行exit
故可想到若希望得到flag应跳过__wakeup(),利用__wakeup()方法的特性,方法属性的个数不同与实际方法属性的个数则跳过,?code=O:2:"xctf":1:{s:4:"flag";s:3:"111";},即可得到flag