Avlyssning (programmering)
Interception ( English hooking ) är en teknik som låter dig ändra standardbeteendet för vissa komponenter i ett informationssystem.
Syftet med avlyssningsteknik
Mycket ofta i systemprogrammering finns det en uppgift att ändra standardbeteendet för systemfunktioner. Till exempel är en ganska intressant tillämpning av denna teknik omdefinieringen av fönsterproceduren i GUI för Windows-applikationer ( underklassning ). Detta är nödvändigt om programmeraren vill organisera sin egen bearbetning av ett fönstermeddelande och först därefter skicka det till standardfönsterproceduren. Efter underklassning kommer meddelandebearbetningsslingan att se ut så här:
Windows-meddelande->Fönster (fönsterprocedur)
Windows-meddelande->Vår fönsterprocedur->Fönster (fönsterprocedur)
Till exempel beskriver Iczelions Tutorials [1] ett exempel på hur underklassning kan användas för att styra indata till kontroller. Avlyssningsteknik behövs inte bara i det här fallet, utan även för till exempel förbearbetning av resultaten av systemfilsökningsfunktionerna FindFirst och FindNext, EnumProcess, som räknar upp processer i Windows, etc. Dessutom, för dessa syften, sådana teknologier används som antivirusverktyg [2 ] , såväl som olika typer av virus, rootkits och andra typer av skadlig programvara.
Mycket ofta är avlyssning viktigt för felsökningsprogram och är en av de viktigaste teknikerna som används i felsökningsverktyg. I det här fallet tillåter denna teknik ett program att kontrollera exekveringen av ett annat. För dessa ändamål tillhandahålls ptrace -systemanropet , vilket gör att du kan ansluta till processer, spåra registervärdena i samband med processen som felsöks, och bland annat styra andra systemanrop. Det är grunden för att implementera en sådan funktion hos debuggers som brytpunkter . Detta systemanrop är väldokumenterat och finns på alla större *Nix-system: Linux , FreeBSD , Solaris . [3] Används oftast i samband med gaffelsystemanropet , som anropar ptrace, och anger i anropsparametrarna att processen som startas är en underordnad. Microsoft Windows tillhandahåller också för liknande ändamål den så kallade. DebugAPI [4] .
Typer av avlyssning av systemfunktioner
De viktigaste metoderna för avlyssning är:
- Byte av adressen till en verklig funktion ( modifiering av IAT-tabeller , modifiering av SSDT / IDT - tabeller)
- Ändra en funktion direkt (skarvning, hooking i kärnläge med modifiering av funktionskroppen)
- Direkt ersättning av hela applikationen/systemkomponenten (till exempel bibliotek med målfunktion)
Metoder kan också delas in enligt exekveringslägeskriterierna:
- Anpassade ( ring3 ) metoder: modifiering av IAT-tabeller, skarvning. Deras egenhet är att det är omöjligt att ändra något i beteendet hos operativsystemkärnan och dess tillägg.
- Kärnläge: modifiering av SSDT/IDT-tabeller, avlyssning i kärnläge med modifiering av funktionskroppen. Låter dig ändra datastrukturerna och koden för valfri del av operativsystemet och applikationerna.
Splicing
Splicing (från engelska splice - "to splice or lime the ends of something") är en metod för att fånga upp API -funktioner genom att ändra koden för målfunktionen. Vanligtvis ändras de första 5 byten av funktionen. Istället infogas en övergång till en funktion som programmeraren definierar. För att säkerställa att operationen utförs korrekt måste applikationen som fångar upp funktionen tillåta att koden som ändrades som ett resultat av splitsningen exekveras. För att göra detta sparar applikationen den ersatta minnessektionen med sig själv, och efter att ha arbetat ut avlyssningsfunktionen återställer den den ändrade sektionen av funktionen och låter den verkliga funktionen exekveras helt. [5]
hot patch punkt
Alla standard Windows dll-funktioner stöder hot-patch-punkter. När man använder den här tekniken finns fem oanvända one-byte nop-operationer före funktionens start, medan själva funktionen börjar med en två-byte mov edi, edi-instruktion. Utrymmet som upptas av fem nops är tillräckligt för att rymma en greninstruktion till interceptorfunktionen. De två byten som upptas av mov edi, edi ger tillräckligt med utrymme för kommandot att hoppa till koden i stället för fem nop. Samtidigt, sedan mov edi, utför edi-instruktionen inga meningsfulla åtgärder, att skriva över den påverkar inte prestandan för den ursprungliga funktionen på något sätt. Således är programmeraren befriad från behovet av att spara det ursprungliga värdet på koden han har ändrat någonstans [6] .
Tillämpningar av skarvning och metoder för detektion
Det gäller:
- I programvara som behöver utföra systemövervakningsfunktioner
- Krokmekanismen i Windows
- Olika typer av skadlig programvara. Detta är den huvudsakliga stealth-tekniken för rootkits på användarnivå .
Huvudmetoden för att detektera faktumet av skarvning är en jämförelse av maskinkoden för den funktion som kontrolleras för skarvning och koden för systemfunktionen som erhålls i ett känt rent system. Dessutom kan övervakning av hoppadresser hjälpa till att upptäcka skarvning av en funktion.
Jämförelse med andra teknologier
- Ändra IAT-procestabeller [7] . Denna teknik tillåter dig inte att ändra beteendet hos själva systemfunktionen, utan gör det bara möjligt att "lura" den valda applikationen, vilket tvingar den att använda din funktion. IAT-tabell - en tabell med adresser för funktioner som importeras av processen. Tekniken är endast lokal till sin natur, även om den kan tillämpas omedelbart på en grupp av applikationer. Kan upptäckas ganska snabbt på grund av behovet av att ladda DLL [8] i adressutrymmet för målprocessen. Splicing, å andra sidan, kräver inte en DLL och injicering i någon annans process, den har förmågan att globalt fånga en funktion. Splitsning har en annan fördel: inte alla systemfunktioner importeras av en process via IAT. Till exempel kan en funktion laddas genom att anropa GetProcAddress. Att använda en direkt ändring av funktionskoden tar bort denna begränsning.
- Avlyssning i kärnläge . Tillåter dig att fånga upp alla funktioner, inklusive de som exporteras av kärnan. Svårast att upptäcka om det lyckas, eftersom det låter dig förfalska all data som tillhandahålls av operativsystemet. Kräver att skriva en speciell komponent för att interagera med drivrutinens kärna. Kan leda till BSOD om den programmeras felaktigt i kärnläge. Det kan upptäckas under drivrutinsladdningsfasen i kärnan eller vid kontroll av aktiva drivrutiner, såväl som vid kontroll av kärnan för ändringar [9] . En svårare programmeringsmetod än splitsning, men mer flexibel, eftersom den låter dig fånga upp funktionerna i själva kärnan, och inte bara WinAPI-funktionerna, som endast fungerar som en mellanhand mellan kärnan och programmet som begär något från operativsystemet systemet.
- Ersätter själva biblioteket med . En mycket radikal lösning på problemet, som har ett antal betydande nackdelar:
- Kräver utbyte av en fil på disken, vilket kan förbjudas och undertryckas av systemet självt. Om du till exempel ersätter Windows-systemfiler kommer Windows Filskydd (WFP) inte att köras , även om det kan stängas av. Sådana åtgärder kan också upptäckas under en statisk analys av systemet av revisorer.
- Full emulering av alla funktioner hos den ersatta DLL-filen eller annan komponent krävs, vilket är mycket mödosamt även i fallet med öppenhet och kompliceras av behovet av demontering i fallet med ett slutet målprogram.
Allt detta visar att detta är ett mycket irrationellt sätt att lösa problemet med att ändra programmets beteende om de två första tillvägagångssätten eller skarvningen är möjliga.
Avlyssning i kärnläge
Den är baserad på modifiering av kärnans datastrukturer och funktioner. Tabeller är de främsta målen för inflytande
- IDT- avbrottsutskickningstabell. Ganska viktigt att avlyssna är avbrottet som hanterar SSDT Service Table (0x2E) [10] .
- SSDT (System Service Dispatch Table) System Service Dispatch Table. Med hänvisning till den kan systemet, genom numret på den begärda tjänsten, erhålla adressen till motsvarande kärntjänst och anropa den. Och SSPT-tabellen innehåller den totala storleken på parametrarna som skickas till systemtjänsten.
- psActiveprocess En kärnstruktur som innehåller en lista över processer i systemet.
- IRP- drivrutinstabell som lagrar pekare till IRP-behandlingsfunktioner.
- EPROCESS En kärnstruktur som lagrar mycket information om en process, inklusive till exempel PID (Process ID).
Rootkits av detta slag kallas DKOM rootkits, det vill säga rootkits baserade på direkt modifiering av kärnobjekt. I rootkits för Windows Server 2003- och XP-system har denna teknik uppgraderats, eftersom dessa operativsystem nu har skrivskydd för vissa delar av kärnminnet [10] . Windows Vista och 7 fick ytterligare PatchGuard -kärnskydd , men alla dessa teknologier övervanns av rootkit-skrivare [11] . Samtidigt är avlyssning av systemfunktioner i kärnläge grunden för proaktiva försvarssystem och hypervisorer .
Andra former av avlyssning
Andra former av avlyssning kan särskiljas:
- Avlyssning av nätverksanslutningar och paket. [12]
- Lösenordsavlyssning. Till exempel genom att spionera på tangentbordsinmatning med en keylogger .
- Avlyssning av webbläsarförfrågningar till webbplatser som använder HTTP-proxy eller webbläsartillägg. Låter dig analysera och/eller ersätta data som utbyts mellan webbläsaren och servern.
Endast en del av tillämpningarna av denna teknik beskrivs här.
Exempel på program som använder avlyssning
Kodexempel
Avlyssning av Microsoft Windows -tangentbordshändelser i
C# med
Microsoft .NET Framework
använder System ;
använder System.Collections ;
använder System.Diagnostics ;
använder System.Runtime.InteropServices ;
namespace Hooks
{
public class KeyHook
{
#region Medlemsvariabler
skyddade static int hook ;
skyddad statisk LowLevelKeyboardDelegate dele ;
skyddat statiskt skrivskyddat objekt Lås = nytt objekt ();
skyddad statisk bool isRegistered = false ;
#ändregion
#region Dll-import
[DllImport("user32")]
privat statisk extern Int32 SetWindowsHookEx ( Int32 idHook , LowLevelKeyboardDelegate lpfn ,
Int32 hmod , Int32 dwThreadId );
[DllImport("user32")] privat statisk extern Int32 CallNextHookEx ( Int32 hHook , Int32 nCode , Int32 wParam , KBDLLHOOKSTRUCT lParam );
[DllImport("user32")]
privat statisk extern Int32 UnhookWindowsHookEx ( Int32 hHook );
#ändregion
#region Typdefinitioner & konstanter
skyddad delegate Int32 LowLevelKeyboardDelegate ( Int32 nCode , Int32 wParam , ref KBDLLHOOKSTRUCT lParam );
privat konst Int32 HC_ACTION = 0 ; privat konst Int32 WM_KEYDOWN = 0 x0100 ; privat konst Int32 WM_KEYUP = 0 x0101 ; privat konst Int32 WH_KEYBOARD_LL = 13 ; #endregion [StructLayout(LayoutKind.Sequential)] public struct KBDLLHOOKSTRUCT { public int vkCode ; public int scanCode ; offentliga int flaggor ; offentlig int tid ; public int dwExtraInfo ; }
statisk privat Int32 LowLevelKeyboardHandler ( Int32 nCode , Int32 wParam , ref KBDLLHOOKSTRUCT lParam )
{
if ( nCode == HC_ACTION )
{
if ( wParam == WM_KEYDOWN )
System . Konsol . ut . WriteLine ( "Key Down: " + lParam . vkCode );
annat om ( wParam == WM_KEYUP )
System . Konsol . ut . WriteLine ( "Key Up: " + lParam . vkCode );
}
returnera CallNextHookEx ( 0 , nCode , wParam , lParam );
}
public static bool RegisterHook ()
{
lock ( Lock )
{
if ( isRegistered )
return true ;
dele = new LowLevelKeyboardDelegate ( LowLevelKeyboardHandler );
hook = SetWindowsHookEx (
WH_KEYBOARD_LL , dele ,
Marshal . GetHINSTANCE (
System . Reflection . Assembly . GetExecutingAssembly (. GetModules ()[ 0 ]
). ToInt32 (), 0
);
if ( krok != 0 )
returnerar ärRegistered = sant ;
else
{
delete = null ;
returnera falskt ;
}
}
}
public static bool UnregisterHook ()
{
lock ( Lock )
{
return isRegistered = ( UnhookWindowsHookEx ( hook ) != 0 );
}
}
}
}
nätfilterkrok _
Det här exemplet visar hur krokar används för att styra nätverkstrafik i Linux-kärnan med hjälp av Netfilter .
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/in.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
/* Port vi vill släppa paket på */
statisk const uint16_t port = 25 ;
/* Detta är själva krokfunktionen */
static unsigned int hook_func ( unsigned int hooknum ,
struct sk_buff ** pskb ,
const struct net_device * in ,
const struct net_device * out ,
int ( * okfn )( struct sk_buff * ))
{
struct iphdr * iph = ip_hdr ( * pskb );
struct tcphdr * tcph , tcpbuf ;
if ( iph -> protokoll != IPPROTO_TCP )
returnera NF_ACCEPT ;
tcph = skb_header_pointer ( * pskb , ip_hdrlen ( * pskb ), sizeof ( * tcph ), & tcpbuf );
if ( tcph == NULL )
returnera NF_ACCEPT ;
returnera ( tcph -> dest == port ) ? NF_DROP : NF_ACCEPT ;
}
/* Används för att registrera vår krokfunktion */
statisk struktur nf_hook_ops nfho = {
. hook = hook_func ,
. hooknum = NF_IP_PRE_ROUTING ,
. pf = NFPROTO_IPV4 ,
. prioritet = NF_IP_PRI_FIRST ,
};
statisk __init int my_init ( void )
{
returnera nf_register_hook ( & nfho );
}
statisk __exit void my_exit ( void )
{
nf_unregister_hook ( & nfho );
}
module_init ( my_init );
module_exit ( my_exit );
Se även
Anteckningar
- ↑ Iczelions lektioner. Win32 API. Lektion 20
- ↑ Till exempel: det är omöjligt att komma åt Kaspersky Internet Security-processen med standardverktyg för Windows API, eftersom motsvarande funktioner fångas upp av antivirusprogrammet.
- ↑ Sida från Linux Ubuntu man page: man page om att anropa ptrace Arkiverad 21 januari 2010 på Wayback Machine och rysk version: rysk översättning på OpenNET Arkiverad 1 november 2014 på Wayback Machine
- ↑ Officiell beskrivning: The Debugging Application Programming Interface Arkiverad 30 maj 2014 på Wayback Machine , med användningsexempel: Win32 API. Lektion 28. Win32 Debug API Jag arkiverade 4 mars 2010 på Wayback Machine
- ↑ En serie artiklar om att fånga upp WindowsAPI-funktioner av Ms Rem (otillgänglig länk) . Tillträdesdatum: 24 juli 2010. Arkiverad från originalet den 23 december 2009. (obestämd)
- ↑ Varför börjar alla Windows-funktioner med en meningslös MOV EDI, EDI-instruktion? - Den gamla nya saken . Hämtad 11 januari 2017. Arkiverad från originalet 13 januari 2017.
- ↑ Metoder för att komma åt och modifiera IAT-tabellen beskrivs i detalj av Hoglund G., Butler J. - Rootkits: Implementation into the Windows Kernel. Kapitel 4 Den antika konsten att fånga
- ↑ Metoder för att injicera en DLL i en främmande process beskrivs i detalj av J. Richter Christopher Nazar Windows via C/C++. Programmering i Visual C++. Vissa implementeringsmetoder dokumenterades först av J. Richter själv
- ↑ Till exempel, en av de första KLISTNER rootkit- detektorerna Arkiverad 25 juli 2010 på Wayback Machine
- ↑ 1 2 G. Hoglund J. Butler Rootkits injicera i Windows-kärnan. Kapitel 4 Den antika konsten att fånga
- ↑ Sentry killing [[Chris Kaspersky|CHRIS KASPERSKY]], AKA MOUSE Special: Hacker #072, s. 072-072-5 . Hämtad 26 juli 2010. Arkiverad från originalet 4 december 2010. (obestämd)
- ↑ Till exempel sniffers gör detta. En gratis implementering av nätverkspaketfångst är nätverksdrivrutinen NDIS WinPCAP- lagret.
Litteratur
- Geoffrey Richter . Programmering i Visual C++ = Windows via C/C++. - St Petersburg. : Peter, 2010. - S. 689-728. - ISBN 978-5-7502-0367-3 .
- Hoagland, Greg , Butler J. Rootkits: Subverting the Windows kernel = Rootkits. Subverting the Windows kernel. - St Petersburg. : Peter, 2010. - S. 36-58,77-129. - ISBN 978-5-469-01409-6 .
Länkar