Vulnerability Development mailing list archives

Re: asm shellcode techniques (especially relevant for win32)


From: "Enrique A. Compañ Gzz." <enrique () virtekweb net>
Date: Wed, 5 Sep 2001 17:33:06 -0500

I don't know what exactly you are trying to do... but...
are you trying to get EIP to be able to address vars?

Here's a way:

        call dumb
dumb:
        pop esi     <---- at this poing esi = eip ("pop esi")

From here you can address variables like this:

VARS_OFFSET     EQU     (vars-start)

start:

    call dumb
dumb:
    pop esi

    add esi, VARS_OFFSET+(other value)         <---- now you can address
vars with esi

vars:

    var1 db "blah", 0FFh                                       <---- the FFh
is a NULL byte XORed with FFh... (see below)
    var1 db "blah", 0FFh

end start

About the nulls in the strings...

XOR them, say with FFh using an hexeditor, declare the strings in your code
and decode them by XORing them
again with FFh (this way you provide 1. encryption (kinnda), 2. you can pass
"bad" chars such as nulls  to the program you're
trying to exploit that filters unwanted chars). For example, XORing a 0 with
FFh gives you FFh... the null's gone.

Also, you DON'T overwrite your code if ESP has a lower address than you
code..... because when you push
values on the stack, ESP is decreased.... (I know you already know that..
just trying to be clear).

Generally I preffer to code a proof-o-concept this way (when possible):

[AAAAAAAAAAAAAA][EBP][EIP][SHELLCODE]

not this way:

[SHELLCODE][AAAAA][EBP][EIP]

The first case, provides a great advantage, ESP points to where the
shellcode begins... you can do
a jmp esp (or call esp) and you'd be executing the code that way, also you
can use ESP to address variables...
no need to "call dumb...pop esi..., etc". Of course, there're are different
scenarios... debbug! use a debugger.


I'll be posting something i developed, like this, that finds automatically
the addresses of the functions (no hard
coded values to call GetProcAddress, etc.), some anti IDS stuff
(polymorphism) and some other trickery.

BTW, there are excellent papers written by virii coders out there, you can
learn some tricks there (crypto, addressing, asm32,
polymorphism, etc.).
Also check out CDC's paper about w32 bof's.



Good Luck.

Enrique A. Compañ Gzz.
Virtek Labs

----- Original Message -----
From: "Franklin DeMatto" <franklin.lists () qDefense com>
To: <vuln-dev () securityfocus com>
Sent: Tuesday, September 04, 2001 7:47 PM
Subject: asm shellcode techniques (especially relevant for win32)


I am working on a x86/win32 shellcode, using intel mneumonics and nasm,
and
have some basic questions:


1) If I want to do a far call, I normally call a pointer to the func.
example:
call FUNC
FUNC: dd 0x74348712

However, I think it can be done directly using a far call to an immediate
offset, something like 9a ?? ?? 12 87 34 74
I think the ?? ?? has to do with something called AR byte.

But I can't find, or figure out, exactly how to do this.  NASM keeps on
telling me something like "far calls aren't reloctable" and refuses to
assemble it.  Is there a way to get NASM to do it anyway?  If not, I can
enter the opcodes by hand - what should they be?

2) If I have a string, and I need to append a null afterwards, what is the
best way?
eg:
ebx is 0
ebp points to beginning of string
string is 26h bytes long
I would normally do:
mov     [ebp+27h], ebx
this yields opcode:
89 9D 27 00 00 00, which is obviously not good
I could do:
add ebp 0xffffffd8
mov [ebp], ebx
sub ebp 0xffffffd8
but this is kind of long
is there a shorter way to do it, especially since I only need to move one
byte?  ( I don't even need to move it, just make a 0,
so I could use not or xor or something...)

3) many times, I need to add or subtract by less than 0x7f.  I would
normally just use add/sub byte xx, but this won't carry, right?
in other words, if eax == 0xffffff01, and I try sub byte 3, I'll get
eax==0xfffffffe, which is not what I want
so I am forced to use sub/add dword, which is much longer.
likewise, sometimes I want to mov location, byte.  But since location is
specified by dword, I need to do mov location, dword,
even if I only need a byte.
my question is: is there a shorter way to do all this, or am I forced to
use dwords, even though I'm only using bytes??

also, since I push paramters to the win32 calls, I normally sub from esp
so
as to not overwrite the code itself.  However, if I understood correctly,
the excellent lsd-pl paper said that this is not neccessary.  Is that
correct?  How is this?  Any elaboration would be appreciated.

Thanks,
Franklin


Franklin DeMatto
Senior Security Analyst, qDefense Penetration Testing
http://qDefense.com
qDefense: Making Security Accessible





Current thread: