,, MMP""MM""YMM `7MM P' MM `7 MM MM MMpMMMb. .gP"Ya MM MM MM ,M' Yb MM MM MM 8M"""""" MM MM MM YM. , .JMML. .JMML JMML.`Mbmmd' `7MMF' `7MF' `7MMF' `7MMF' `MA ,V MM MM VM: ,V `7M' `MF' MM MM .gP"Ya ,6"Yb.`7M' `MF'.gP"Ya `7MMpMMMb. MM. M' `VA ,V' MMmmmmmmMM ,M' Yb 8) MM VA ,V ,M' Yb MM MM `MM A' XMX MM MM 8M"""""" ,pm9MM VA ,V 8M"""""" MM MM :MM; ,V' VA. MM MM YM. , 8M MM VVV YM. , MM MM VF .AM. .MA..JMML. .JMML.`Mbmmd' `Moo9^Yo. W `Mbmmd'.JMML JMML. ,, ,, ,, .g8"""bgd `7MM `7MM mm db .dP' `M MM MM MM dM' ` ,pW"Wq. MM MM .gP"Ya ,p6"bo mmMMmm `7MM ,pW"Wq.`7MMpMMMb. MM 6W' `Wb MM MM ,M' Yb 6M' OO MM MM 6W' `Wb MM MM MM. 8M M8 MM MM 8M"""""" 8M MM MM 8M M8 MM MM `Mb. ,'YA. ,A9 MM MM YM. , YM. , MM MM YA. ,A9 MM MM `"bmmmd' `Ybmd9'.JMML..JMML.`Mbmmd' YMbmd' `Mbmo.JMML.`Ybmd9'.JMML JMML. -- Contact -- https://twitter.com/vxunderground firstname.lastname@example.org
Nowdays more and more people explore the wonderfull world of parasitic code.
ELF parasites are usually written in pure assembler code. due to this, code can get really huge in pure ASM, while the same stuff could be done much faster with C code and inline asm().
This text focuses on the idea of implementing ASM syscall functions so that they can be used to code parasitic (payload) code in C.
oh and dont get confused, parasitic code is a wide range of possible codes, but in this document im talking about the payload of ELF infectors which insert data in segments of a target binary/lib etc. or code that will be injected into a proccess using the ptrace() function.
so the definition of 'parasitic' code in this document is basicially the payload.
by the way, this article is linux specific ;)
i started to explain this a little in the intro already, but lets get a bit more into detail. as example we will use two common known technics:
both of those "infection" methodes usually use payloads fully written in asm.
a payload deppends on the situation and 'infection' methode that is used. if we look at ptrace(), we could take over a terminal and inject code that will print some text.
a banal example, but we keep it simple so its easy to understand.
lets get to a more advanced (maybe unknown to the public) theory - infecting read() using ptrace().
there is some unused space at 0x8048000 (about 240bytes) that space is occupied by ELF headers, which arent used during runtime.
you can basicly change it and put whatever you want into that address and nothing would happen.
so instead of destorying data by putting the parasite on %eip (like ES-ptrace-poo does) you can put it there or at least a initial parasite, which will deploy a bigger parasite, since the space is very limited.
lets have a look at the GOT table:
[root@mail /]# objdump -R /bin/cat | grep read 0804c428 R_386_JUMP_SLOT read [root@mail /]#
whenever the process wants to call read(), it calls the address WITHIN 0804c428. i.e. at 0804c428 there is another address which points to the actual read,
if you write a different address to 0804c428, then next time someone calls read(), its going to jump to something else.
if you would do:
then next time read will be called you will segfault on 0x41414141. now think of the possibilitys yourselfe ;)
ELF infection is different to that, code will be injected into (for example) the text segment of a binary, so the payload will be triggered everytime it will be executed.
ELF infection is much more serious than ptrace() injection, because you can actually build powerfull working viruses and/or worms. if you want more detailed info about ELF parasites/viruses, i sugest you to read silvio`s great textware =)
by the way, at this point it should be obvious why it is called parasite :) well this should be enough of background information about a few forms of parasitic code.
well if you didnt figure yet, it saves you a lot of time and is pretty usefull if you work on big payloads. if you are a hardcore asm coder, surely pure asm is better, but then again harder,bigger and much more time consuming. its a good and clean way to write the payload, especially if you want to keep updating the code.
so for those who only know basic asm, or not enough to write the payload in pure asm (or just dont have 24/7 to do it in asm), this way is surely a good sollution. as soon as you got a hand on it, you will see the advantages yourselfe =)
basicially you need ansi C and basic ASM knowledge, if you are a beginner C coder this textware is probably nothing for you (yet). besides that, you should be familiar with ELF infection or ptrace() or both :) ,because if you arent into these things, you will most likely not find any good use for this tekneeq.
We mainly talk about a way to create the payload used in various infectors/injectors in C code instead of asm.
You also have to think of what you want your infector todo - do you want it to open up a bindshell or do you want it to be silent and execute commands or connect back to you ?
obviously if you dont know what you want todo with it, you should first think of that befor you start to code, but probably you already got something in mind =)
well i guess you are familiar with all the nice functions like memcpy(),accept(),sock(),send() etc etc.. those usefull functions can all be found in the nice headers in /usr/src/linux/* ..
forget about them,as you cant call any function outside your parasite (like memcpy() which is a libc function). but you can use #definitions like AF_INET or whatsoever. you can #include them at the beginning of your parasite.
we can only work with pure syscalls here, but calm down, keep on reading till the bell rings hehe.
obviously you cannot execute library functions from within a C parasite, because they are outside the parasite. so you have to execute syscalls directly.
since we cant use the usual include files we got to work with pure syscalls as i said before and so we write ourselfes a syscall implementation in assembly.
if you now start wondering about the title of this article, i didnt say 100% C ;) anyways if you think about it for a while you will soon see the use of all this.
It saves you a lot of time, because you dont have to write everything in pure ASM and especially if you arent that familiar with asm, or just know the basics.
you code yourselfe some API functions in ASM, on that way you can develope about 80% of the payload code in C.
lets have a look at syscalls in linux and how we implement our own, shall we ?
in linux you insert syscall parameters like this:
[eax = syscall number ] [ebx = first parameter ] [ecx = second parameter ] [edx = third parameter ] [...]
for example if you want to do exit(4553); then you would do it like:
eax = 1 ebx = 4553 int $0x80
open asm/unistd.h, you will see all the syscalls and their decimal number. we call them with the following code:
first we define the syscall we want to implement. for example if we wanted to have a fork() implementation
we would do it like this:
now instead of:
we can just do:
as you can see, at first it took 2 lines (and 22 characters) of code and now we just need 1 line (and 8 chars) ! now you can probably imagine how it would look like on some bigger code.
this is just one simple function, now compare that little example to a full functional backdoor code...
make sure you include <asm/unistd.h> !
put this function INSIDE the parasite i.e. between the "parasite_start" and "parasite_end" boundries which are assembly labels, just like the C labels.
goto blah blah: [...];
i guess you know what i mean :) .. got it so far ? if not read over it once more.. because we now move on to some example code...
ok here we go our first little parasite payload is finished! compile it and insert the shellcode into your infector. infect a binary/proccess and strace the infected host.
ok thats it, i hope you could learn from it. i would like to thank sectorx, because he helped me a lot with ELF stuff in the past - keep the spirit alive bro ;)