Python 报告详解

在本章中,我们将介绍以下主题:

我们在本书中提供了执行 web 应用程序测试各个方面的方法。所以,我们得到了所有这些信息。我们已经从我们的食谱中获得了控制台输出,但是我们如何将所有这些收集成有用的格式呢?理想情况下,我们希望输出的格式可以使用。或者,我们可能希望将另一个应用程序(如 Nmap)的输出转换为我们正在使用的格式。它可以是逗号分隔变量CSV),也可以是 Maltego 转换,或者您想要使用的任何其他格式。

你刚才提到的这件事是什么?我听到你问。Maltego 是一款开源智能**OSIT**和取证应用软件。它有一个漂亮的 GUI,可以帮助您以一种漂亮、容易理解的方式可视化信息。

Nmap 是在 web 应用程序测试的侦察阶段使用的通用工具。它通常用于扫描具有多种选项的端口,以帮助您根据自己的喜好定制扫描。例如,您想使用 TCP 还是 UDP?您要设置什么 TCP 标志?是否有您想要运行的特定 Nmap 脚本,例如检查网络时间协议NTP)反射,但要在非默认端口上运行?这个清单可能是无穷无尽的。

Nmap 输出易于阅读,但不易于以编程方式使用。这个简单的方法将从 Nmap 转换 XML 输出(通过运行 Nmap 扫描时使用–oX 标志),并将其转换为 CSV 输出。

准备好了吗

虽然这个配方的实现非常简单,但您需要安装 Python 的nmap模块。您可以使用pip或从源文件构建它。您还需要 Nmap 扫描的 XML 输出。您可以通过扫描您选择的易受攻击的虚拟机或您有权在其上运行扫描的站点来实现此目的。您可以按原样使用 Nmap,也可以在 Python 脚本中使用 Python 的nmap模块来实现这一点。

怎么做…

就像我前面提到的,这个食谱很简单。这主要是因为nmap图书馆为我们做了大部分艰苦的工作。

下面是我们将用于此任务的脚本:

import sys
import os
import nmap

nm=nmap.Portscanner()
with open(“./nmap_output.xml”, “r”) as fd:
    content = fd.read()
    nm.analyse_nmap_xml_scan(content)
    print(nm.csv())

它是如何工作的…

因此,在导入必要的模块之后,我们必须初始化 Nmap 的Portscanner函数。虽然我们不会在此配方中进行任何端口扫描,但这是允许我们使用对象中的方法所必需的:

nm=nmap.Portscanner()

然后,我们有一个with声明。那是什么?以前,当您在 Python 中打开文件时,必须记住在完成后关闭它。在这种情况下,with语句将在执行完其中的所有代码后为您执行此操作。如果您没有很好的内存,并且总是忘记关闭代码中的文件,那就太好了:

with open(“./nmap_output.xml”, “r”) as fd:

with语句之后,我们将文件的内容读入一个content变量(我们可以随意调用这个变量,但为什么会使事情过于复杂?)

    content = fd.read()

使用我们之前创建的Portscanner对象,我们现在可以使用一种方法分析内容,该方法将解析我们提供的 XML 输出,然后我们可以将其打印为 CSV:

nm.analyse_nmap_xml_scan(content)
    print(nm.csv())

本书中还有一个配方,说明了如何使用BeautifulSoup库以编程方式获取域名。此配方将向您展示如何创建局部 Maltego 变换,然后您可以在 Maltego 内部使用该变换,以易于使用的图形方式生成信息。通过此转换收集的链接,还可以将其用作更大的爬行或爬行解决方案的一部分。

怎么做…

下面的代码显示了如何创建一个脚本,该脚本将枚举的信息输出为 Maltego 的正确格式:

import urllib2
from bs4 import BeautifulSoup
import sys

tarurl = sys.argv[1]
if tarurl[-1] == “/”:
  tarurl = tarurl[:-1]
print”<MaltegoMessage>”
print”<MaltegoTransformResponseMessage>”
print”  <Entities>”

url = urllib2.urlopen(tarurl).read()
soup = BeautifulSoup(url)
for line in soup.find_all(‘a’):
  newline = line.get(‘href’)
  if newline[:4] == “http”:
    print”<Entity Type=\”maltego.Domain\”>” 
    print”<Value>”+str(newline)+”</Value>”
    print”</Entity>”
  elif newline[:1] == “/”:
    combline = tarurl+newline
    print”<Entity Type=\”maltego.Domain\”>” 
    print”<Value>”+str(combline)+”</Value>”
    print”</Entity>”
print”  </Entities>”
print”</MaltegoTransformResponseMessage>”
print”</MaltegoMessage>”

它是如何工作的…

首先我们导入此配方所需的所有模块。您可能已经注意到,对于BeautifulSoup,我们有以下行:

from bs4 import BeautifulSoup

因此,当我们使用BeautifulSoup时,我们只需键入BeautifulSoup而不是bs4.BeautifulSoup

然后,我们将参数中提供的目标 URL 分配到一个变量中:

tarurl = sys.argv[1]

完成后,我们检查目标 URL 是否以/结尾。如果是,那么我们通过将tarurl变量替换为tarurl的最后一个字符以外的所有字符来删除最后一个字符,以便以后在完全输出相对链接时可以在配方中使用它:

if tarurl[-1] == “/”:
  tarurl = tarurl[:-1]

然后,我们打印出构成 Maltego 转换响应一部分的标签:

print”<MaltegoMessage>”
print”<MaltegoTransformResponseMessage>”
print”  <Entities>”

然后我们用urllib2打开目标url并将其存储在BeautifulSoup中:

url = urllib2.urlopen(tarurl).read()
soup = BeautifulSoup(url)

我们现在使用“汤”查找所有<a>标签。更具体地说,我们将寻找带有超文本引用(链接)的<a>标记:

for line in soup.find_all(‘a’):
  newline = line.get(‘href’)

如果链接的前四个字符为http,我们将其输出为正确的格式,作为 Maltego 的实体:

if newline[:4] == “http”:
    print”<Entity Type=\”maltego.Domain\”>”
    print”<Value>”+str(newline)+”</Value>”
    print”</Entity>”

如果第一个字符是/,表示该链接是一个相对链接,那么我们将在为该链接添加目标 URL 后,将其输出为正确的格式。虽然此配方显示了如何处理相对链接的一个示例,但需要注意的是,还有其他类型的相对链接,如文件名(example.php)、目录以及相对路径点符号(../../example.php),如下所示:

elif newline[:1] == “/”:
    combline = tarurl+newline
    if 
    print”<Entity Type=\”maltego.Domain\”>”
    print”<Value>”+str(combline)+”</Value>”
    print”</Entity>”

处理完页面上的所有链接后,关闭在输出开始时打开的所有标记:

print”  </Entities>”
print”</MaltegoTransformResponseMessage>”
print”</MaltegoMessage>”

还有更多…

BeautifulSoup库包含其他可以使代码更简单的函数。其中一个函数称为SoupStrainer。SoupStrainer 将允许您只解析文档中所需的部分。我们将此作为练习留给您进行探索。

本书中还有另一个食谱,说明了如何从网站中提取电子邮件。本食谱将向您展示如何创建本地 Maltego 转换,然后您可以在 Maltego 自身中使用该转换生成信息。它可以与 URL 爬行转换结合使用,从整个网站中提取电子邮件。

怎么做…

以下代码显示了如何通过使用正则表达式从网站提取电子邮件:

import urllib2
import re
import sys

tarurl = sys.argv[1]
url = urllib2.urlopen(tarurl).read()
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])?)”))

print”<MaltegoMessage>”
print”<MaltegoTransformResponseMessage>”
print”  <Entities>”
emails = re.findall(regex, url)
for email in emails:
  print”    <Entity Type=\”maltego.EmailAddress\”>”
  print”      <Value>”+str(email[0])+”</Value>”
  print”    </Entity>”
print”  </Entities>”
print”</MaltegoTransformResponseMessage>”
print”</MaltegoMessage>”

它是如何工作的…

脚本顶部导入必要的模块。然后,我们将作为参数提供的 URL 分配给变量,并使用urllib2打开url列表:

tarurl = sys.argv[1]
url = urllib2.urlopen(tarurl).read()

然后,我们创建一个与标准电子邮件地址格式匹配的正则表达式:

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])?)”))

前面的正则表达式应与格式为email@address.com的电子邮件地址或地址为.com 的电子邮件地址相匹配。

然后我们输出有效 Maltego 变换输出所需的标签:

print”<MaltegoMessage>”
print”<MaltegoTransformResponseMessage>”
print”  <Entities>”

然后,我们在url内容中找到与正则表达式匹配的所有文本实例:

emails = re.findall(regex, url)

然后,我们获取找到的每个电子邮件地址,并将其以正确的格式输出,以进行 Maltego 转换响应:

for email in emails:
  print”    <Entity Type=\”maltego.EmailAddress\”>”
  print”      <Value>”+str(email[0])+”</Value>”
  print”    </Entity>”

然后关闭之前打开的打开标签:

print”  </Entities>”
print”</MaltegoTransformResponseMessage>”
print”</MaltegoMessage>”

Sslscan 是一个用于枚举 HTTPS 站点支持的密码的工具。了解站点支持的密码在 web 应用程序测试中很有用。如果某些支持的密码较弱,则这在渗透测试中更有用。

怎么做…

此配方将在指定的 IP 地址上运行 Sslscan,并将结果输出为 CSV 格式:

import subprocess
import sys

ipfile = sys.argv[1]

IPs = open(ipfile, “r”)
output = open(“sslscan.csv”, “w+”)

for IP in IPs:
  try:
    command = “sslscan “+IP

    ciphers = subprocess.check_output(command.split())

    for line in ciphers.splitlines():
      if “Accepted” in line:
        output.write(IP+”,”+line.split()[1]+”,”+ line.split()[4]+”,”+line.split()[2]+”\r”)
  except:
    pass

它是如何工作的…

我们首先导入必要的模块,并将参数中提供的文件名分配给一个变量:

import subprocess
import sys

ipfile = sys.argv[1]

提供的文件名应指向包含 IP 地址列表的文件。我们以只读方式打开此文件:

IPs = open(ipfile, “r”)

然后用w+代替r打开文件进行读写输出:

output = open(“sslscan.csv”, “w+”)

现在既然我们有了我们的输入和输出,我们就可以开始了。我们首先遍历 IP 地址:

for IP in IPs:

对于每个 IP,我们运行 Sslscan:

  try:
    command = “sslscan “+IP

然后,我们将命令的输出分为多个块:

    ciphers = subprocess.check_output(command.split())

然后我们逐行检查输出。如果该行包含单词Accepted,则我们安排该行的元素进行 CSV 输出:

    for line in ciphers.splitlines():
      if “Accepted” in line:
        output.write(IP+”,”+line.split()[1]+”,”+ line.split()[4]+”,”+line.split()[2]+”\r”)

最后,如果出于任何原因,尝试在 IP 上运行 SSL 扫描失败,我们只需转到下一个 IP 地址:

  except:
  pass

有时候拥有数据的可视表示真的很好。在这个配方中,我们将使用plot.lypython API 生成一个漂亮的图形。

准备好了吗

在这个配方中,我们将使用plot.lyAPI 生成图形。如果您还没有账户,您需要在注册一个账户 https://plot.ly

一旦您拥有一个帐户,您将需要准备好使用plot.ly的环境。

最简单的方法是使用pip安装,所以只需运行以下命令:

$ pip install plotly

然后,您需要运行以下命令(用您自己的命令替换{username}{apikey}{streamids},这些命令可以在plot.ly站点上的您的帐户订阅下查看):

python -c “import plotly;  plotly.tools.set_credentials_file(username=’{username}’,  api_key=’{apikey}’, stream_ids=[{streamids}])”

如果您遵循这个示例,那么我使用了在线提供的用于测试的pcap文件:http://www.snaketrap.co.uk/pcaps/hbot.pcap

我们将枚举pcap文件中的所有 FTP 数据包,并根据时间绘制它们。

为了解析pcap文件,我们将使用dpkt模块。与早期配方中使用的Scapy类似,dpkt也可用于解析和操作数据包。

最简单的方法是使用pip安装。只需运行以下命令:

$ pip install dpkt

怎么做…

此配方将读取一个pcap文件,并提取任何 FTP 数据包的日期和时间,然后将此数据绘制成图形:

import time, dpkt
import plotly.plotly as py
from plotly.graph_objs import *
from datetime import datetime

filename = ‘hbot.pcap’

full_datetime_list = []
dates = []

for ts, pkt in dpkt.pcap.Reader(open(filename,’rb’)):
    eth=dpkt.ethernet.Ethernet(pkt) 
    if eth.type!=dpkt.ethernet.ETH_TYPE_IP:
        continue

    ip = eth.data
    tcp=ip.data

    if ip.p not in (dpkt.ip.IP_PROTO_TCP, dpkt.ip.IP_PROTO_UDP):
        continue

    if tcp.dport == 21 or tcp.sport == 21:
        full_datetime_list.append((ts, str(time.ctime(ts))))

for t,d in full_datetime_list:
    if d not in dates:
        dates.append(d)

dates.sort(key=lambda date: datetime.strptime(date, “%a %b %d %H:%M:%S %Y”))

datecount = []

for d in dates:
    counter = 0
    for d1 in full_datetime_list:
        if d1[1] == d:
            counter += 1

    datecount.append(counter)

data = Data([
    Scatter(
        x=dates,
        y=datecount
    )
])
plot_url = py.plot(data, filename=’FTP Requests’)

它是如何工作的…

我们首先导入必要的模块,并将pcap文件的文件名分配给一个变量:

import time, dpkt
import plotly.plotly as py
from plotly.graph_objs import *
from datetime import datetime

filename = ‘hbot.pcap’

接下来,我们设置我们的列表,当我们迭代我们的pcap文件时,我们将填充这些列表。Full_datetime_list变量将保存所有 FTP 数据包日期,而dates将用于保存完整列表中唯一的datetime

full_datetime_list = []
dates = []

然后我们打开pcap文件进行读取,并在for循环中对其进行迭代。本节检查数据包是否为 FTP 数据包,如果是,则将时间附加到我们的阵列:

for ts, pkt in dpkt.pcap.Reader(open(filename,’rb’)):
    eth=dpkt.ethernet.Ethernet(pkt) 
    if eth.type!=dpkt.ethernet.ETH_TYPE_IP:
        continue

    ip = eth.data
    tcp=ip.data

    if ip.p not in (dpkt.ip.IP_PROTO_TCP, dpkt.ip.IP_PROTO_UDP):
        continue

    if tcp.dport == 21 or tcp.sport == 21:
        full_datetime_list.append((ts, str(time.ctime(ts))))

现在我们有了 FTP 流量的datetime函数列表,我们可以从中获得唯一的datetime函数并填充我们的dates数组:

for t,d in full_datetime_list:
    if d not in dates:
        dates.append(d)

然后,我们对日期进行排序,使其在图表上按顺序排列:

dates.sort(key=lambda date: datetime.strptime(date, “%a %b %d H:%M:%S %Y”))

然后,我们只需迭代唯一的日期,并计算在此期间从较大的数组发送/接收的所有数据包,然后填充计数器数组:

datecount = []

for d in dates:
    counter = 0
    for d1 in full_datetime_list:
        if d1[1] == d:
            counter += 1

    datecount.append(counter)

只需使用我们的日期数组对plot.ly进行 API 调用,并将数组作为数据点进行计数:

data = Data([
    Scatter(
        x=dates,
        y=datecount
    )
])
plot_url = py.plot(data, filename=’FTP Requests’)

当您运行脚本时,它会弹出浏览器,打开您新创建的plot.ly图形,如下所示:

How it works…

这就是全部。plot.ly有很多不同的方法来可视化您的数据,值得一试。想想当你的老板看到你开始发送的所有漂亮图表时,他们会给你留下多么深刻的印象。

教程来源于Github,感谢apachecn大佬的无私奉献,致敬!

技术教程推荐

接口测试入门课 -〔陈磊〕

Web安全攻防实战 -〔王昊天〕

WebAssembly入门课 -〔于航〕

Spark核心原理与实战 -〔王磊〕

React Hooks 核心原理与实战 -〔王沛〕

PyTorch深度学习实战 -〔方远〕

Vue 3 企业级项目实战课 -〔杨文坚〕

深入拆解消息队列47讲 -〔许文强〕

结构会议力 -〔李忠秋〕