• .NET UIAutomation实现Word文档加密暴力破解


    .NET UIAutomation简介
    UIAutomation是.Net 3.5之后提供的“界面自动化测试”技术,主要依靠通过Win32程序窗口和控件句柄获得控制权(反射和HOOK机制),从而达到利用程序脚本实现各类操作的目的,一般利用其实现针对Windows平台应用程序的自动化测试。
    
    暴力破解方法
    对于一个设置了密码访问限制的Word文档,可以利用UIAutomation的特点,使用不断穷举密码和密码字典的方式进行破解。
    
    破解方法实现
    可以穷举字母和数字的组合作为密码输入数据,当然你如果愿意也可以加入特殊字符,主要实现代码参见:
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    
    namespace PasswordCrack
    {
        class Util
        {
    
            public void ReadLineAndCrack(string path, CrackHandler crack) {
                StreamReader reader = null;
                try
                {
                    reader = new StreamReader(path, Encoding.Default);
                    String line = null;
                    while ((line = reader.ReadLine()) != null)
                    {
                        crack(line);
                    }
                }
                catch (IOException e)
                {
                    System.Console.WriteLine(e.StackTrace);
                }
                finally
                {
                    if (reader != null) {
                        reader.Close();
                    }
                }
    
            }
    
            /**
            *通过设置需要生成的第几列字符串,生成暴力破解字符串
            *
            *参数说明:
            *@column 第几列
            *@crack 破解处理方法
            **/
            public void GenCrackWordByColumn(int column, CrackHandler crack) {
                string[] columns = new string[column];
                GenColumnsWord(columns, 0, columns.Length, crack);
            }
    
            /**
            *通过设置需要生成的字符串位数范围,生成暴力破解字符串
            *
            *参数说明:
            *@begin 起始位
            *@length 从起始位开始的长度范围
            *@crack 破解处理方法
            **/
            public void GenCrackWordByScope(int begin, int length, CrackHandler crack) {
                for (int i = begin; i < begin + length; i++)
                {
                    if ((begin < 1) || (length < 0)) {
                        break;
                    }
                    string[] columns = new string[i];
                    GenColumnsWord(columns, 0, columns.Length, crack);
                }
            }
    
            /**
            *通过设置需要生成的字符串最大位数,生成暴力破解字符串
            *
            *参数说明:
            *@bit 数组位数
            *@crack 破解处理方法
            **/
            public void GenCrackWord(int bit, CrackHandler crack) {
                for (int i = 0; i < bit; i++) {
                    string[] columns = new string[i + 1];
                    GenColumnsWord(columns, 0, columns.Length, crack);
                }
            }
            /**
            *按列数生成暴力破解字符串,生成方式为遍历该函数中所设定的字符组合
            *
            *参数说明:
            *@columns 用于保存所生成字符串的数组
            *@index 生成第几列数据,初始引用是需设置为0
            *@bit 数组位数
            *@crack 破解处理方法
            **/
            public void GenColumnsWord(string[] columns, int index, int bit, CrackHandler crack) {
                const int lowerAlpha = 'a';
                const int upperAlpha = 'A';
                const int number = '0';
                const int total = 10 + 26 + 26;
                int alpha = number;
    
                for (int i = 0; i < total; i++){
    
                    if (i == 36) {
                        alpha = upperAlpha;
                    }
    
                    if (i == 10) {
                        alpha = lowerAlpha;
                    }
    
                    columns[index] = ((char)alpha).ToString();
    
                    //迭代处理,当不是最高位时,只顺序生成1个字符,是最高位时,依次顺序生成所有字符
                    if (index != (bit - 1)) {
                        index++;
                        GenColumnsWord(columns, index, bit, crack);
                        index--;
                    }
    
                    StringBuilder sb = new StringBuilder();
                    for (int j = 0; j < bit; j++) {
                        sb.Append(columns[j]);
                    }
    
                    crack(sb.ToString());
    
                    alpha++;
    
                 }
             }
        }
    }
    
    获取Word密码输入窗口句柄链
    我们使用UIAutomationSpy获取Word密码输入窗口句柄链:
    
    
    UIAutomation公共方法
    在此需要实现一些公共方法,尤其是实现自动化启动Word主程序进程以及通过进程Id号获得主窗体句柄,主要实现代码参见:
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using System.Threading;
    using System.Windows.Automation;
    
    namespace PasswordCrack
    {
        class UIAutomationHelper
        {
            private string path;
    
           /**
           *启动进程方法
           *
           **/
           private void StartProcess()
           {
               Process ps = Process.Start(path);
           }
    
           /**
           *通过进程名称获取进程Id,如果该进程没有启动,启动该进程后获取其Id
           *
           *参数说明:
           *@path 进程程序路径
           *@name 进程名称
           *@wait 启动后,等待时间
           **/
            public int GetProcessId(string path, string name, int wait) {
                int pId = 0;
                int timer = 0;
                this.path = path;
                const int timeout = 60000;
                //启动程序处理子线程
                ThreadStart ts = new ThreadStart(StartProcess);
                Thread thread = new Thread(ts);
    
                if (Process.GetProcessesByName(name).Length > 0) {//当进程已经存在
    
                    thread.Start();
                    if (wait > 0)
                    {
                        Thread.Sleep(wait);
                    }
                    else {
                        Thread.Sleep(500);
                    }
                    return Process.GetProcessesByName(name)[0].Id;
                }
    
    
                thread.Start();
    
                while (pId == 0)
                {
    
                    if (Process.GetProcessesByName(name).Length > 0)
                    {
                        pId = Process.GetProcessesByName(name)[0].Id;
                    }
    
                    Thread.Sleep(1000);
                    timer += 1000;
                    if (timer > timeout) {
                        break;
                    }
                }
    
                return pId;
            }
    
            /**
            *通进程Id号获得主窗体句柄
            *
            *参数说明:
            *@pId 进程Id
            **/
            public AutomationElement GetMainAutomationElementByPid(int pId)
            {
                Process process = Process.GetProcessById(pId);
                AutomationElement handle = AutomationElement.FromHandle(process.MainWindowHandle);
                if (handle != null) {
                    return handle;
                }
                return null;
            }
    
    
            public AutomationElement GetHandleByClassAndControlTypeFromParentHandle(AutomationElement parent, ControlType type, string className)
            {
                AutomationElement handle = null;
                PropertyCondition classCondition = new PropertyCondition(AutomationElement.NameProperty, className);
                PropertyCondition typeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, type);
                AndCondition and = new AndCondition(classCondition, typeCondition);
                handle = parent.FindFirst(TreeScope.Children, and);
                return handle;
            }
    
            public AutomationElementCollection GetHandlesByControlTypeFromParentHandle(AutomationElement parent, ControlType type)
            {
                AutomationElementCollection handleCollection = null;
                PropertyCondition typeCondition = new PropertyCondition(AutomationElement.ControlTypeProperty, type);
                handleCollection = parent.FindAll(TreeScope.Children, typeCondition);
                return handleCollection;
            }
    
            public AutomationElement GetWindowByClassFromParentHandle(AutomationElement parentHandle, string className)
            {
                return GetHandleByClassAndControlTypeFromParentHandle(parentHandle, ControlType.Window, className);
            }
    
            public AutomationElement GetButtonByClassFromParentHandle(AutomationElement parentHandle, string className)
            {
                return GetHandleByClassAndControlTypeFromParentHandle(parentHandle, ControlType.Button, className);
            }
    
            public AutomationElementCollection GetTextEditsFromParentHandle(AutomationElement parentHandle)
            {
                return GetHandlesByControlTypeFromParentHandle(parentHandle, ControlType.Edit);
            }
    
            public AutomationElement GetTextEditByClassFromParentHandle(AutomationElement parentHandle, string className)
            {
                return GetHandleByClassAndControlTypeFromParentHandle(parentHandle, ControlType.Edit, className);
            }
    
            public AutomationElement GetTextButtonByClassFromParentHandle(AutomationElement parentHandle, string className)
            {
                return GetHandleByClassAndControlTypeFromParentHandle(parentHandle, ControlType.Button, className);
            }
    
    
            /**
            *为TextEdit设置数据
            *
            *参数说明:
            *@textEditHandle TextEdit句柄
            *@strData 所设置的数据
            **/
            public bool SetTextEditData(AutomationElement textEditHandle, string strData) {
                ValuePattern vpTextEdit = null;
    
                if (!textEditHandle.Current.IsEnabled)
                {
                    throw new InvalidOperationException("The control is not enabled.
    ");
                }
    
                if (!textEditHandle.Current.IsKeyboardFocusable)
                {
                    throw new InvalidOperationException("The control is not focusable.
    ");
                }
    
                vpTextEdit = textEditHandle.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
                if (null == vpTextEdit)
                {
                    return false;
                }
    
                if (vpTextEdit.Current.IsReadOnly)
                {
                    throw new InvalidOperationException("The control is read-only.
    ");
                }
    
                vpTextEdit.SetValue(strData);
    
                return true;
            }
    
            /**
            *左键单击Button
            *
            *参数说明:
            *@buttonHandle Button句柄
            **/
            public bool ButtonLeftClick(AutomationElement buttonHandle)
            {
                object objButton = null;
                InvokePattern ivkpButton = null;
                try
                {
                    if (null == buttonHandle)
                    {
                        return false;
                    }
                    if (!buttonHandle.TryGetCurrentPattern(InvokePattern.Pattern, out objButton))
                    {
                        return false;
                    }
                    ivkpButton = (InvokePattern)objButton;
                    ivkpButton.Invoke();
                    return true;
                }
                catch (System.Exception e)
                {
                    throw new InvalidProgramException("Left click buttion failed", e);
                }
            }
        }
    }
    
    核心破解方法实现
    利用.NET委托技术实现在穷举字母和数字的组合过程中实现破解方法:
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Automation;
    
    namespace PasswordCrack
    {
        public delegate void CrackHandler(string word);
    
        class Crack
        {
            private const string PATH = "test.docx";
            private const string PROCESS_NAME = "WINWORD";
    
            public CrackHandler GetCrack() {
                CrackHandler @crack = Print;
                @crack += DoCrack;
                return @crack;
            }
    
            private void Print(string word)
            {
                System.Console.WriteLine(word);
            }
    
            private void DoCrack(string word) {
                UIAutomationHelper uiah = new UIAutomationHelper();
                int pid = uiah.GetProcessId(PATH, PROCESS_NAME, 500);
                System.Console.WriteLine(pid);
                Thread.Sleep(1000);
                AutomationElement mainHandle = uiah.GetMainAutomationElementByPid(pid);
    
                AutomationElement passwd = uiah.GetWindowByClassFromParentHandle(mainHandle, "密码");
                AutomationElement passwdEdit = uiah.GetTextEditsFromParentHandle(passwd)[0];
                uiah.SetTextEditData(passwdEdit, word);
                AutomationElement btn = uiah.GetButtonByClassFromParentHandle(passwd, "确定");
                uiah.ButtonLeftClick(btn);
                Thread.Sleep(1000);
                AutomationElement failedWindow;
                if ((failedWindow = uiah.GetWindowByClassFromParentHandle(mainHandle, "Microsoft Office Word")) != null)
                {
                    AutomationElement failedBtn = uiah.GetButtonByClassFromParentHandle(failedWindow, "确定");
                    uiah.ButtonLeftClick(failedBtn);
    
                }
                else {
                    System.Console.WriteLine(word);
                }
            }
    
        }
    }
    
    程序入口
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    using System.Windows.Automation;
    
    namespace PasswordCrack
    {
    
        class Program
        {
            static void Main(string[] args)
            {
    
                Util util = new Util();
                Crack crack = new Crack();
                util.GenCrackWord(6, crack.GetCrack());
    
    
    
            }
        }
    }
    
    
    ————————————————
    版权声明:本文为CSDN博主「xreztento」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/xreztento/article/details/50325037
    

      

  • 相关阅读:
    局域网文件实时同步工具
    SQLServer备份恢复助手(太强大了!)
    SQLServer 统计查询语句消耗时间
    如何将Sql server数据库中的模型图转化到Word中--并能够查看字段的属性信息
    创建Database Diagrams时遇到的问题
    bat 操作数据库(附加,分离,删除,还原)
    Bat 多个执行操作选择
    Redis Windows下查看版本号
    ThinkPHP 数据库操作(七) : 视图查询、子查询、原生查询
    ThinkPHP 数据库操作(六) : 查询事件、事务操作、监听SQL
  • 原文地址:https://www.cnblogs.com/soundcode/p/12425621.html
Copyright © 2020-2023  润新知