云计算百科
云计算领域专业知识百科平台

DVWA靶场——JavaScript Attacks(前端攻击)

JavaScript Attacks表面上是一个修改"短语(phrase)

你输入一段文字(比如 ChangeMe)——点击 Submit——页面显示"你的短语已更新"

但其真正目的在于告诉我们"把所有安全逻辑都放在前端 JavaScript 里"是多么危险的事情

一个正常的 Web 应用,修改用户数据时,应该由服务器端完成验证,浏览器只负责提交和展示

low

源码分析

<?php
$page['body'] .= <<<EOF
<script>
/*
MD5 code from here
https://github.com/blueimp/JavaScript-MD5
*/
!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<<t|n>>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<<r%32,n[14+(r+64>>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e<n.length;e+=16)i=l,a=g,d=v,h=m,g=f(g=f(g=f(g=f(g=c(g=c(g=c(g=c(g=u(g=u(g=u(g=u(g=o(g=o(g=o(g=o(g,v=o(v,m=o(m,l=o(l,g,v,m,n[e],7,-680876936),g,v,n[e+1],12,-389564586),l,g,n[e+2],17,606105819),m,l,n[e+3],22,-1044525330),v=o(v,m=o(m,l=o(l,g,v,m,n[e+4],7,-176418897),g,v,n[e+5],12,1200080426),l,g,n[e+6],17,-1473231341),m,l,n[e+7],22,-45705983),v=o(v,m=o(m,l=o(l,g,v,m,n[e+8],7,1770035416),g,v,n[e+9],12,-1958414417),l,g,n[e+10],17,-42063),m,l,n[e+11],22,-1990404162),v=o(v,m=o(m,l=o(l,g,v,m,n[e+12],7,1804603682),g,v,n[e+13],12,-40341101),l,g,n[e+14],17,-1502002290),m,l,n[e+15],22,1236535329),v=u(v,m=u(m,l=u(l,g,v,m,n[e+1],5,-165796510),g,v,n[e+6],9,-1069501632),l,g,n[e+11],14,643717713),m,l,n[e],20,-373897302),v=u(v,m=u(m,l=u(l,g,v,m,n[e+5],5,-701558691),g,v,n[e+10],9,38016083),l,g,n[e+15],14,-660478335),m,l,n[e+4],20,-405537848),v=u(v,m=u(m,l=u(l,g,v,m,n[e+9],5,568446438),g,v,n[e+14],9,-1019803690),l,g,n[e+3],14,-187363961),m,l,n[e+8],20,1163531501),v=u(v,m=u(m,l=u(l,g,v,m,n[e+13],5,-1444681467),g,v,n[e+2],9,-51403784),l,g,n[e+7],14,1735328473),m,l,n[e+12],20,-1926607734),v=c(v,m=c(m,l=c(l,g,v,m,n[e+5],4,-378558),g,v,n[e+8],11,-2022574463),l,g,n[e+11],16,1839030562),m,l,n[e+14],23,-35309556),v=c(v,m=c(m,l=c(l,g,v,m,n[e+1],4,-1530992060),g,v,n[e+4],11,1272893353),l,g,n[e+7],16,-155497632),m,l,n[e+10],23,-1094730640),v=c(v,m=c(m,l=c(l,g,v,m,n[e+13],4,681279174),g,v,n[e],11,-358537222),l,g,n[e+3],16,-722521979),m,l,n[e+6],23,76029189),v=c(v,m=c(m,l=c(l,g,v,m,n[e+9],4,-640364487),g,v,n[e+12],11,-421815835),l,g,n[e+15],16,530742520),m,l,n[e+2],23,-995338651),v=f(v,m=f(m,l=f(l,g,v,m,n[e],6,-198630844),g,v,n[e+7],10,1126891415),l,g,n[e+14],15,-1416354905),m,l,n[e+5],21,-57434055),v=f(v,m=f(m,l=f(l,g,v,m,n[e+12],6,1700485571),g,v,n[e+3],10,-1894986606),l,g,n[e+10],15,-1051523),m,l,n[e+1],21,-2054922799),v=f(v,m=f(m,l=f(l,g,v,m,n[e+8],6,1873313359),g,v,n[e+15],10,-30611744),l,g,n[e+6],15,-1560198380),m,l,n[e+13],21,1309151649),v=f(v,m=f(m,l=f(l,g,v,m,n[e+4],6,-145523070),g,v,n[e+11],10,-1120210379),l,g,n[e+2],15,718787259),m,l,n[e+9],21,-343485551),l=t(l,i),g=t(g,a),v=t(v,d),m=t(m,h);return[l,g,v,m]}function a(n){var t,r="",e=32*n.length;for(t=0;t<e;t+=8)r+=String.fromCharCode(n[t>>5]>>>t%32&255);return r}function d(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t<r.length;t+=1)r[t]=0;var e=8*n.length;for(t=0;t<e;t+=8)r[t>>5]|=(255&n.charCodeAt(t/8))<<t%32;return r}function h(n){return a(i(d(n),8*n.length))}function l(n,t){var r,e,o=d(n),u=[],c=[];for(u[15]=c[15]=void 0,o.length>16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(d(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="";for(r=0;r<n.length;r+=1)t=n.charCodeAt(r),e+="0123456789abcdef".charAt(t>>>4&15)+"0123456789abcdef".charAt(15&t);return e}function v(n){return unescape(encodeURIComponent(n))}function m(n){return h(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this);
function rot13(inp) {
return inp.replace(/[a-zA-Z]/g,function(c){return String.fromCharCode((c<="Z"?90:122)>=(c=c.charCodeAt(0)+13)?c:c-26);});
}
function generate_token() {
var phrase = document.getElementById("phrase").value;
document.getElementById("token").value = md5(rot13(phrase));
}
generate_token();
</script>
EOF;

  • 从页面中获取 id="phrase" 的输入框的值(用户输入的短语)
  • 对该值进行 ROT13 编码
  • 再对 ROT13 的结果进行 MD5 哈希
  • 将最终结果赋值给 id="token" 的隐藏字段
  • 关键点

    generate_token() 在页面加载时立即执行(最后一行),这意味着Token的值完全由用户输入的phrase决定

    其核心问题就在于

    Token的生成算法完全暴露在客户端token === MD5(ROT13(phrase)),且依赖于用户输入的phrase,因此任何用户都可以为自己想要的任何phrase生成一个"合法"的Token

    提示我们提交单词 "success" 即可获胜

    根据我们刚刚的分析

  • Token 是由 md5(rot13(phrase)) 计算得出的
  • 服务器验证的就是这个公式
  • 需要提交 phrase=success 和对应的正确Token
  • 第一步:计算 ROT13

    "success" 经过 ROT13 编码:
    s → f
    u → h
    c → p
    c → p
    e → r
    s → f
    s → f

    结果: "fhpprff"

    第二步:计算 MD5

    对 "fhpprff" 进行 MD5 哈希。

    使用浏览器开发者工具(F12 → Console):

    md5("fhpprff")

    第三步:构造请求

    开发者工具里,改变token和phrase的值分别为 value="38581812b435834ebf84ebcc2c6424d6" ,value="success" 点击submit

    提示我们成功了

    Medium

    源码分析

    function do_something(e)
    {
    for(var t = "", n = e.length – 1; n >=0; n–)
    t += e[n];
    return t
    }

    setTimeout(function()
    {
    do_elsesomething("XX")
    },300);

    function do_elsesomething(e)
    {
    document.getElementById("token").value = do_something(e + document.getElementById("phrase").value + "XX")
    }

    1. do_something() 函数 – 字符串反转

    • 输入:"hello"
    • 输出:"olleh"

    2.setTimeout() – 延迟执行,等待 300毫秒 后,调用 do_elsesomething("XX")

    3.do_elsesomething() – Token生成核心,

    • 参数 e 的值是 "XX"
    • 获取输入框 phrase 的值
    • 拼接字符串:"XX" + phrase + "XX"
    • 调用 do_something() 进行反转
    • 将反转后的结果赋给 token 字段

    开发者可能认为做了以下"加强":

  • 增加了盐值(Salt):"XX" + phrase + "XX"
      • 看起来像是加了密钥,让Token不那么容易被猜中
  • 增加了延迟执行:setTimeout() 让代码不那么直观
      • 可能认为这样能阻止自动化脚本
  • 改变了算法:从MD5改为字符串反转
      • 认为换算法能迷惑攻击者

    实际情况是

    • 算法仍然完全暴露在客户端
    • 所谓的"盐值"是硬编码的
    • 反转算法是可逆的
    • 延迟执行可以用调试器跳过

    漏洞利用

    第一步:计算正确的Token

    对于 phrase = "success":
    token = reverse("XX" + "success" + "XX")
    = reverse("XXsuccessXX")
    = "XXsseccusXX"

    第二步:构造攻击请求

    我们依旧直接改变表单元素

    没毛,注入成功了

    high

    源码分析

    function do_something(e) {
    for (var t = "", n = e.length – 1; n >= 0; n–) t += e[n];
    return t
    }

    function token_part_3(t, y = "ZZ") {
    document.getElementById("token").value = sha256(document.getElementById("token").value + y)
    }

    function token_part_2(e = "YY") {
    document.getElementById("token").value = sha256(e + document.getElementById("token").value)
    }

    function token_part_1(a, b) {
    document.getElementById("token").value = do_something(document.getElementById("phrase").value)
    }

    document.getElementById("phrase").value = "";
    setTimeout(function() {
    token_part_2("XX")
    }, 300);
    document.getElementById("send").addEventListener("click", token_part_3);
    token_part_1("ABCD", 44);

    跟前两个等级差不多,依次执行

    第1步:token_part_1()

    // 反转 phrase
    token = do_something("success")
    = "sseccus"

    第2步:token_part_2("XX")

    // 拼接 + SHA256
    拼接 = "XX" + "sseccus" = "XXsseccus"
    token = sha256("XXsseccus")

    第3步:用户点击Submit → token_part_3()

    // 获取当前token,拼接"ZZ",再SHA256
    拼接 = token + "ZZ" = sha256("XXsseccus") + "ZZ"
    token = sha256(拼接)

    最终Token:

    text

    最终Token = sha256( sha256("XX" + reverse(phrase)) + "ZZ" )

    其问题:

    算法仍然完全在客户端,盐值是硬编码的,可以手动调用函数,可以绕过延迟

    所以利用漏洞也是同样的流程

    第一步:计算token

    第二步:构造攻击请求

    impossible

    你永远不能信任任何来自用户的东西,也无法阻止用户篡改它,因此不存在"不可能"级别

    DVWA靶场的最后一个关卡在屏幕上弹出"Success"提示的那一刻,我知道这段短暂却充实的Web安全探索之旅迎来了尾声。回首这段学习的日日夜夜,从最初面对漏洞时的茫然无措,到如今能够从容分析代码、构造攻击载荷并提出防御方案,其中的每一次突破都离不开许多人的帮助与支持

    首先,我要由衷感谢DVWA(Damn Vulnerable Web Application)项目及其开发者团队。这个由Digininja发起并持续维护的开源项目,以其精心设计的漏洞环境和循序渐进的四级难度体系,为我这样的Web安全初学者搭建了一座从理论通往实践的金色桥梁。从Low级别将安全逻辑赤裸裸地暴露在客户端,到Impossible级别将验证逻辑深植服务器端,DVWA不仅是漏洞的陈列馆,更是一部活生生的安全思想演进史。正是这个"在危险中学习"的平台,让我深刻理解了"永远不要信任用户输入"这条Web安全的金科玉律

    同时,我要特别感谢互联网上无数开源的网络安全社区与知识分享者。Burp Suite的官方文档、各大安全论坛中前辈们的实战经验与踩坑记录,以及GitHub上数不清的Payload集合与绕过技巧——这些散落在数字世界各处的智慧碎片,在我最需要指引的时刻点亮了前路。感谢那些素未谋面却毫不吝啬分享知识的博主与安全从业者,是你们的无私筑就了后来者学习的阶梯。

    我也要感谢这段学习过程中遇到的每一个"漏洞"本身。SQL注入教会我,最危险的往往不是复杂的攻击手法,而是一个未被转义的单引号;XSS向我证明,安全防御不能止步于输入过滤,输出编码同样不可或缺;而JavaScript Attacks模块则用最简单的方式展示了那个最深刻的道理——所有摆在客户端的安全措施,都不过是防君子不防小人的装饰品。感谢这些漏洞以最生动的方式为我上了一堂堂安全之课。

    我要感谢未来的自己和所有正在学习安全的朋友们。DVWA只是万里长征的第一步,真正安全的系统需要在实战中千锤百炼,真正的安全工程师需要在攻防对抗中持续成长。我将带着这段学习经历沉淀下的技术、思维与敬畏之心,继续在这个充满挑战与魅力的领域前行。

    愿我们都能用技术让这个世界变得更加安全

    peace and love

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » DVWA靶场——JavaScript Attacks(前端攻击)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!