文章作者:l0om
__ __ __
.-----.--.--.----.| |.--.--.--| |.-----.--| | .-----.----.-----.
| -__|_ _| __|| || | | _ || -__| _ |__| _ | _| _ |
|_____|__.__|____||__||_____|_____||_____|_____|__|_____|__| |___ |
by l0om - member of excluded-team |_____|
TRYING TO MAKE YOUR BINARY SHUT UP
0x00 short intro
0x01 hiding strings
0x02 Prevent tracing
0x03 Prevent from changing our code
0x04 Confusing
ret end
0x00 short intro
################
Once i have written a small virus on a linux box for infecting ELF binarys. When i was ready i started to think about how to prevent someone from detecting the sence of the program itself. I tryed to prevent the techniqs i use on new binarys before i execute them on my box. That are thinks like dumping strings, debugging etc..
Most of the things i have written down are of course well known and most of the techniqs are stolen by sources of viruses, trojans, textfiles and stuff like that.
0x01 Hiding strings
###################
One of our aims is to prevent someone from viewing strings which can be found in the binary.
Those could include IP addresses, shell commands or filenames which could lead someone to detect eg payload, trigger or even the whole propose of the program itself. Furthermore think of software where hard coded pathnames can be found. A found pathname like "/tmp/.antivir_pid.%d" could lead someone to try to put up a symlink attack (nearly the same could happen to shell command strings).
Mostly someone will try to dump cleartext strings with the "strings" utiltiy. In "strings" manaul is meantioned that it will show all strings which are four or more bytes long.
Lets take a small example:
#include <stdio.h>
void main(void) {
FILE *fd = fopen("/etc/passwd", "r");
if(fd == NULL) return;
else printf("file opend\n");
}
admin@box:~> strings k
/lib/ld-linux.so.2
libc.so.6
printf
fopen
_IO_stdin_used
__libc_start_main
__gmon_start__
GLIBC_2.1
GLIBC_2.0
PTRh0
/etc/passwd
file opend
As the pathname is longer than four bytes the strings command dumps the path in cleartext.
How to prevent this?
One simple method would be to cut the string in parts about three bytes and put them together dynamicly if needed. The "strings" utility would show nothing. An example:
#include <stdio.h>
#include <string.h>
#define ETC_PASSWD "3412" // put the parts together in this combination
static char *bstr(char *construct);
void main(int argc, char **argv)
{
FILE *fd;
fd = fopen(bstr(ETC_PASSWD), "r");
if(fd == NULL) return;
else printf("file opend\n");
}
static char *bstr(char *construct)
{
char *ptr, *part, *finstr;
size_t nlen;
nlen = strlen(construct);
if(!nlen) return NULL;
finstr = (char *)malloc(1);
ptr = construct;
while(nlen--) {
switch(*ptr++) {
case '3':
part = "/et";
break;
case '4':
part = "c/";
break;
case '1':
part = "pas";
break;
case '2':
part = "swd";
break;
}
finstr = (char *)realloc(finstr, strlen(finstr)+strlen(part));
strcat(finstr, part);
}
return finstr;
}
admin@box:~> strings newk
strings test
/lib/ld-linux.so.2
libc.so.6
printf
malloc
strcat
realloc
fopen
_IO_stdin_used
__libc_start_main
strlen
__gmon_start__
GLIBC_2.1
GLIBC_2.0
PTRh
QVh\
3412
file opend
Anyone have seen a path?
Another method is to save the string encrypted and decrypt the string "on the fly" if needed. In this case we dont need a strong encryption because our iam is simple: no one should see the string in plaintext.
#include <stdio.h>
#define CCHAR(x) ((x)+10) // rot13 like ascii shifting
#define DCHAR(x) ((x)-10)
static char *bstr(char *chiffer, int nbytes);
void main(void) {
char filename[] = { CCHAR('/'), CCHAR('e'), CCHAR('t'), CCHAR('c'), CCHAR('/'),
CCHAR('p'), CCHAR('a'), CCHAR('s'), CCHAR('s'), CCHAR('w'),
CCHAR('d'), '\0' };
FILE *fd = fopen(bstr(filename,11), "r");
if(fd == NULL) return;
else printf("file opend\n");
}
static char *bstr(char *chiffer, int nbytes)
{
char *ptr;
ptr = chiffer;
while(nbytes--) *ptr = DCHAR(*ptr++);
return(chiffer);
}
The macro CCHAR shifts the ascii character plus 10. This way the string isnt saved in the binary in cleartext.
As you can see the DCHAR macro is used to decrypt the string and "Tadaa!" - "strings" utility will show us nothing.
0x02 Prevent tracing
####################
All this preventing from dumping strings does not prevent from simple trace the program and find out what it is doing. for normal "trace" programs like "strace" or "ltrace" work with the "ptrace" function.
<from the ptrace manual>
"The ptrace system call provides a means by which a parent
process may observe and control the execution of another
process, and examine and change its core image and regis