Spørsmål:
Serversides spørringsavlytting med MS SQL Server
Hernán
2013-04-06 00:45:12 UTC
view on stackexchange narkive permalink

Jeg forsker på avskjæring av spørsmål som kommer til SQL Server 2008-prosessen.

SQLOS-arkitektur er delt inn i følgende system-DLLer:

  • sqlmin .dll : Lagring, replikering, sikkerhetsfunksjoner osv.
  • sqllang.dll : TransactSQL spørreutførelsesmotor, uttrykksvurdering osv.
  • sqldk.dll : Oppgaveplanlegging og utsendelse, bearbeidet trådoppretting, meldingsløkker osv.

SQLSERVR serviceprosess forekomster av SQLOS komponenter gjennom sqlboot.dll og sqldk.dll , og arbeidertrådene mottar spørsmål gjennom den valgte tilkoblingsmetoden på serveren (TCP / IP, lokalt delt minne eller navngitte rør

Jeg har feilsøkt sqlservr.exe-prosessadresseområdet og søker etter tekstlige spørsmål. Det ser ut til at spørringsstrenger er lesbare, men jeg kunne ikke finne et punkt der spørringer kan avskjæres mens de går inn i SQLOS-planleggeren.

Å lytte til rør eller TCP / IP er ikke et alternativ for øyeblikket; Jeg vil gjerne injisere på et høyere nivå, helst på SQLOS-komponentnivå.

Noen ideer om hvor du skal begynne å se på?

Hvorfor utelukker du de åpenbare førstevalgene i ditt neste siste avsnitt?
Jeg er med 0c00l, men spørsmålet mitt er hvorfor ikke bruke skriv inn et spørsmål med noe tynt shim-program (for eksempel en odbc-kontakt) og kjør spor. koble til en stikkontakt og kjør spor (begynner med recv eller hva som helst). så sjekk foreningen mellom de to sporene for når de begynner å krysse for å se om det er en levedyktig tilnærming?
Jeg tror ikke at avlytting på protokollnivå er den beste måten å håndtere sikkerhetstrusler som SQL-injeksjon. Hvis du vil fjerne trusselen, må du vite mye mer om protokollen. Hvis du bare har spørringen, kan du fokusere innsatsen på et enkelt punkt. Hvis du også avlytter på klientnivå, kan du ikke håndtere serverangrep.
@sw .: Jeg leser flere ganger nå, dette ser ikke ut til å være målet.
@0xC0000022L Hernan er åpenbart klar over de andre alternativene. Han vil vite spesifikt hvor han skal fange opp funksjonene på et høyere nivå (dvs. ved hjelp av kroker). Det ville være interessant å vite det fordi jeg søkte og ikke fant en ressurs om det, mens det finnes mange ressurser om å hekte andre ting. Jeg har nettopp funnet en anbefaling fra Microsoft om ikke å instrumentere SQL Server: "Bruk av tredjeparts omveier eller lignende teknikker støttes ikke i SQL Server" http://support.microsoft.com/kb/920925
@sw .: alt jeg sa er at Hernan ikke nevnte noe om avlytting * på grunn av xyz *.
@0xC0000022L, beklager hvis jeg var frekk. Jeg tror at det å vite hvordan man kobler til SQL Server ville være interessant på grunn av det Hernan sa "Jeg vil gjerne injisere på et høyere nivå, helst på SQLOS-komponentnivå."
@sw .: ikke bekymre deg, i skriftlig kommunikasjon antar jeg best hensikt før annet er bevist. Trodde ikke det var frekt eller så.
Akkurat som @sw sier, er jeg klar over andre alternativer som ODBC-nivå avlytting. For å være mer konsis, vil jeg ikke lappe på flere punkter (f.eks. Delt minne, rør og TCP / IP I / O), men på et enkelt punkt der alle spørsmål er planlagt for planlegging og utføring, uavhengig av klienten- servergrensesnitt eller kommunikasjonsmetode.
Er WMI en god mulighet for deg å gjøre dette?
@Lizz WMI har ikke et grensesnitt for å se på alle spørsmål
Fire svar:
Brendan Dolan-Gavitt
2013-04-15 06:05:42 UTC
view on stackexchange narkive permalink

Dette virket som et morsomt prosjekt for en søndag ettermiddag, så jeg fikk prøve det. For å komme rett til poenget, her er anropstakken for en funksjon i SQL-server som analyserer og deretter utfører spørringen (adresser og forskyvninger hentet fra SQL Server 2008 R2 som kjører på Windows 7 SP1 32-bit):

  0x7814500a msvcr80.i386! memcpy + 0x5a0x013aa370 sqlservr! CWCharStream :: CwchGetWChars + 0x5c0x013a9db5 sqlservr! CSQLStrings :: CbGetChars + 0x350x012ffa50 sqlservr! CParser :: FillBuffer + 0x3d0x0138bbfd sqlservr! CParser :: CParser + 0x3c80x01352e96 sqlservr! sqlpars + 0x7b0x013530f2 sqlservr ! CSQLSource :: FParse + 0x16d0x013531ed sqlservr! CSQLSource :: FParse + 0x2680x012ff9e8 sqlservr! `streng '+ 0x3c0x015894b8 sqlservr! CSQLSource :: Utfør + 0x2c80x0158ad31 sqlservr! process_request + 0x2ac0x0158a328 sqlservr! process_commands + 0x15f0x015cf8b4 sqlservr! SOS_Task :: Param :: Utfør + 0xdd0x015cf9ea sqlservr! SOS_Scheduler :: RunTask + 0xb40x015cf575 sqlservr! SOS_Scheduler :: IsShrinkWorkersNødvendig + 0x480x77f06854 ntdll! ZwSignalAndWaitForSingleObject + 0xc0x  CSQLSource  -klassen, og spesielt dens  Execute  -metode.  

Bevæpnet med denne informasjonen var jeg også i stand til å grave opp et par blogginnlegg av noen hos Microsoft om hvordan du trekker ut spørringsstrengen fra en minnedump av SQL Server. Innlegget ser ut til å bekrefte at vi er på rett spor, og gir deg et sted å legge inn og en måte å trekke ut spørringsstrengen.

Metodikk

Jeg følte at dette ville bli lettest taklet ved hjelp av en eller annen form for Dynamic Binary Instrumentation (DBI); siden vi mistenker at spørringsstrengen vil bli behandlet et sted i SQL Server-prosessen, kan vi se på minnelesninger og skrivinger laget av prosessen, og søke etter et punkt som leser eller skriver spørringsstrengen. Vi kan deretter dumpe samtalestakken på det tidspunktet og se hvilke interessante adresser som vises, og kartlegge dem tilbake til symboler (siden SQL Server har feilsøkingssymboler tilgjengelig, som Rolf påpeker). Det var egentlig så enkelt som det!

Selvfølgelig er kunsten å ha noe rundt som lar deg enkelt instrumentere en prosess. Jeg løste dette ved hjelp av et (forhåpentligvis snart utgitt) dynamisk analyserammeverk for hele systemet basert på QEMU; dette lar meg unngå ubehageligheter involvert i å få SQL Server til å kjøre under, f.eks. PIN. Fordi rammeverket inkluderer støtte for rekord og avspilling, måtte jeg heller ikke bekymre meg for å bremse serverprosessen med instrumentasjonen min. Når jeg hadde ringestakken, brukte jeg PDBParse for å få funksjonsnavnene.

bare for å avklare: fungerer metoden din bare hvis serveren kjører i QEMU? og sidespørsmål: kan du faktisk endre spørringen?
Den spesifikke metoden jeg brukte fungerer bare hvis serveren kjører i QEMU, ja. Men du kan gjøre det samme med for eksempel PIN ved å instrumentere minne som leser / skriver. Jeg er ikke sikker på om du kan endre spørringen på dette tidspunktet; Jeg så minst et annet sted der den bruker spørringsstrengen til å konstruere en MD5-hash (CSQLStrings :: GenerateDurableSqlHandle + 0x40), så du må endre den før det punktet.
Sofistikert, veldig interessant tilnærming og teknisk korrekt. Takk for tiden og hjelpen!
MERKNAD om feilsøkingssymboler: SQL Server 2012 RTM (11.0.2100.60) har offentlige feilsøkingssymboler. For øyeblikket kunne jeg ikke skaffe PDB for 11.0.3128.0, pluss at jeg ikke vet om de er tilgjengelige for SP1 ennå (11.0.3000). Så husk dette når du spiller med SQL 2012-system-DLLer. For informasjon om bygg, se http://sqlserverbuilds.blogspot.com.ar/
Etter Brendan-svaret er Hernans arbeidseksempel tilgjengelig på: https://github.com/nektra/SQLSvrIntercept
0xC0000022L
2013-04-17 05:43:34 UTC
view on stackexchange narkive permalink

Bare å snuse trafikk ... er lett

Hvis du bare ville snuse trafikken, kan du bruke TDS-protokollsniffer som følger med WireShark.

La latskapen veilede deg - latskap er reverserens venn

Å lytte til rør eller TCP / IP er ikke et alternativ på dette øyeblikk; Jeg vil gjerne injisere på et høyere nivå, helst på SQLOS-komponentnivå.

Jeg vet ikke hvorfor du insisterer på å gjøre dette på en bestemt måte når all informasjon er lett tilgjengelig og alt du trenger å gjøre er å sette sammen stikksagbitene. Dette ser ut til å være den enkleste, raskeste - kort sagt: lateste - metoden. I tillegg til at TCP / IP er det høyere nivået, fordi du kan fange det selv før det når den faktiske SQL-serveren maskinen hvis du kan kapre IP / navnet til SQL-serveren og sette en "proxy" i mellom. Hvordan høyt nivå vil du ha det? Det du insisterer på, er faktisk å bore ned i nedre nivåer på MS SQL Server.

MS SQL Server bruker en dokumentert protokoll og bruker en LSP du burde / ville være i stand til å snuse, avskjære og til og med manipulere den trafikken. Så vidt jeg husker kjøres LSPer i prosessområdet til applikasjonen hvis trafikk de filtrerer. Du kan betrakte dem som en provisorisk brannmur på applikasjonsnivå, bokstavelig talt.

Alternativt - og sannsynligvis det bedre valget uansett - kan du skrive en proxy basert på eksisterende og gratis FreeTDS (lisensiert under LGPL). tdspool -programmet vil være et godt poeng å starte dette arbeidet. Og ja, dette skal være egnet for faktisk avlytting , ikke bare for å snuse videresendt trafikk. Du kan bruke biblioteket (FreeTDS) til å dekode og omkode spørsmålene. Dette biblioteket vil selvsagt også være det som skal brukes inne i LSP.

Jeg vil spare tid for å gå i detaljer om demonteringen, selv om jeg installerte MS SQL Server 2008 og kort så på det i IDA Pro. Brendans svar gir en god oversikt, selv om jeg er uenig i denne altfor involverte metoden der en enklere er tilgjengelig. Men så, du (Hernán) ba om det.

Rolf Rolles
2013-04-13 05:19:48 UTC
view on stackexchange narkive permalink
Generelt sett vil jeg si at problemer som denne er applikasjonsspesifikke. Derfor, til tross for at brukerens bredbane ble nedstemt for svaret, var det nøyaktig det samme rådet jeg ville gitt hvis jeg ikke var klar over noen fine, spesielle løsninger som var spesifikke for problemet. Det du må gjøre er å se dataene komme inn i prosessen og deretter følge dem når de kopieres og manipuleres gjennom hele programmet. Denne oppgaven vil være enklere enn den generelle saken på grunn av at feilsøkingssymboler er tilgjengelige for SQL Server. Har du prøvd noe i denne retning? Si, angi et brytpunkt på nettverkets mottaksfunksjoner i sammenheng med SQL Server, angi et hardware-RW-brytpunkt på dataene som kommer inn over nettverket, og se hvordan dataene beveger seg gjennom koden?
Ja, hvis det er noe applikasjonsspesifikk kunnskap noen allerede har for denne saken, vil de kanskje avsløre den, men kort av det, er dette den åpenbare etterforskningsveien. Imidlertid kan SQL-servere ha ganske komplekse systemer som utfører SQL-setninger, så reversering kan være tidkrevende. ELLER kanskje det er enkelt. Man * forestiller seg * noen funksjoner som godtar SQL-setningen som inndata;).
broadway
2013-04-11 19:34:56 UTC
view on stackexchange narkive permalink

Jeg har ingen spesifikk kunnskap om det målet, men tilnærmingen jeg sannsynligvis vil ta er å sende den samme meldingen over et rør, tcp og delt minne og spore dem med pin, og lete etter hvor den grunnleggende blokken treffer konverger med alle spor skal gi deg noen utgangspunkt for finjustering av et godt injeksjonspunkt.

Kanskje det bare er meg, men jeg kan ikke følge løsningen din. Kanskje du kan konkretisere dette med lenker, mer informasjon, beskrivelser og detaljer?
Jeg tror han bare sier utføre SQL-kommandoer, lage notater av koden som ser ut til å kjøres, dykke ned i den koden, og spore den tilbake til den første funksjonen i kjeden av SQL-kommandokjøring. Selvfølgelig, hvem vet om det er "så enkelt", det har sannsynligvis et ganske komplekst utførelsessystem. Uansett, ikke svaret mitt, bare avklare hva jeg tror jeg leser.
Ikke akkurat. Jeg sier bruk hver av inngangstypene for å legge inn den samme spørringen og undersøke banen gjennom programmet. Pin er et veldig tilgjengelig verktøy for å gjøre denne typen ting (selv om det selvfølgelig ikke er den eneste).


Denne spørsmålet ble automatisk oversatt fra engelsk.Det opprinnelige innholdet er tilgjengelig på stackexchange, som vi takker for cc by-sa 3.0-lisensen den distribueres under.
Loading...