Saturday, November 27, 2010

Reversing Scratch Book




Introduction


This post will be a scratch book to support my learning of the roots of computers: machine code, assembler, exploits, etc.
It will be quite messy as it's going to be based on mistakes I commit and things I find interesting to have in mind but maybe you can find anything that suits for you.

Things to note



SIZES


IA32 architechture:
Element
Size
Sample
Description

Address
4 bytes
0xffffe000
Memory address that in this case corresponds to the linux-gate.so static shared module

Opcode
1-2 bytes
FFE4
In this case it corresponds to JMP *%ESP instruction used to circumvent random address stack

RET
4 bytes
0xddccbbaa
As RET is the address of the returning function it is an address as well so it takes 4 bytes

EBP
4 bytes
0xddccbbaa
Stack frame pointer, as again its an address it occupies 4 bytes

AH
1 byte
N/A
Register's high part of memory

AL
1 byte
N/A
Register's low part of memory

AX
2 bytes
N/A
16 bit space formed by AH+AL

EAX
4 bytes
N/A
Extended AX register able to hold an address


GCC


  • Compile so that you can see the source code when debugging (gdb is most effective when it is debugging a program that has debugging symbols linked in to it. With g++, this is accomplished using the -g command line argument. For even more information, the -ggdb switch can be used which includes debugging symbols which are specific to gdb. The makefile for this tutorial uses the -ggdb switch. )
gcc -ggdb -o tesoro tesoro.c

GDB


  • List code (if possible)
l

  • Examine
x/FMT ADDRESS
x/x <address> #examine address position and display hex content
x/c <address> #examines address position and display the byte stored in that position translated to ascii

  • Show functions of a binary
info functions

  • show variables, print the names and data types of all variables that are declared outside of functions (i.e. excluding local variables).
info variables

* specify running arguments
set args

  • Set breakpoint
break <function>
brak *<line_num>

  • Diverting output to file
Change the name of the current logfile. The default logfile is gdb.txt.
set logging file FILE

  • Patching a program
By default, GDB opens the file containing your program's executable code (or the corefile) read-only. This prevents accidental alterations to machine code; but it also prevents you from intentionally patching your program's binary.
If you'd like to be able to patch the binary, you can specify that explicitly with the set write command. For example, you might want to turn on internal debugging flags, or even to make emergency repairs.
set write on
set write off

  • If you specify set write on', GDB opens executable and core files for both reading and writing; if you specify set write off' (the default), GDB opens them read-only. If you have already loaded a file, you must load it again (using the exec-file or core-file command) after changing set write, for your new setting to take effect.
show write

Display whether executable files and core files are opened for writing as well as reading.

Differences between Intel & AT&T Syntax


Intel and AT&T syntax Assembly language are very different from each other in appearance, and this will lead to confusion when one first comes across AT&T syntax after having learnt Intel syntax first, or vice versa. So lets start with the basics.
  • In Intel syntax there are no register prefixes or immed prefixes. In AT&T however registers are prefixed with a '%' and immed's are prefixed with a '$'. Intel syntax hexadecimal or binary immed data are suffixed with 'h' and 'b' respectively. Also if the first hexadecimal digit is a letter then the value is prefixed by a '0'.
Example:
Intex Syntax
mov     eax,1
mov     ebx,0ffh
int     80h

AT&T Syntax
movl    $1,%eax
movl    $0xff,%ebx
int     $0x80

As you may have noticed, the AT&T syntax mnemonics have a suffix. The significance of this suffix is that of operand size. 'l' is for long, 'w' is for word, and 'b' is for byte. Intel syntax has similar directives for use with memory operands, i.e. byte ptr, word ptr, dword ptr. "dword" of course corresponding to "long". This is similar to type casting in C but it doesnt seem to be necessary since the size of registers used is the assumed datatype.

Moving data to registers


when coding something like:
mov ax,4

its possible that the high part of eax is polluted from previous actions and you don't get the results you wanted, thus better use:
mov eax,4

or
xor eax,eax
mov ax,4


Compiling,liking..executing (linux)


ASM code -> machine code
nasm -f elf <program.s>

machine code -(linker)-> executable binary
gcc <program.o> -o <program>

executing
./<program>


Standard input, output...


  • stdout=screen=1
  • stdin=keyboard=0

Syscalls


They are invoked by an interruption and require some parameters that are provided in the registers (eax,ebx,etc).
SYSCALL #
action

4
write

5
read

For reference, system call numbers can be found in /usr/include/asm/unistd.h.

Compare numbers sample


Read two numbers and say which one is bigger

Stack address randomization


Ways to check whether it is enabled or not (Debian like)
#cat /proc/sys/kernel/randomize_va_space
/* or  */
#sysctl kernel.randomize_va_space

To disable it
echo 0 > /proc/sys/kernel/randomize_va_space
/*  or   */
sysctl -w kernel.randomize_va_space=0


Stack execution prevention


Stack execution prevention deactivates the stack addresses as executable. Thus EIP cannot point to an address considered as stack space. It is disabled at compilation time with
$ gcc -fno-stack-protector -z execstack vulnerable.c

-fno-stack-protector disables SSP (stack guard) -z execstack marks the stack as executable

Filling the stack


The genuine-oldskool:
./victim `perl -e "print 'a'x256"`
Segmentation fault

or
./victim $(printf "%0512x")
Segmentation fault

from inside gdb
(gdb) run `perl -e 'print "a"x516,"\xa8\xf5\xff\xbf"'`


I (L) Coredumps


#ulimit -c unlimited
# ./victim $(printf "%0512x")
Segmentation fault (core dumped)
#gdb -c core


Understanding GDB errors


After inserting a seemingly correct breakpoint you get this error when starting your debugged program
Cannot insert Breakpoint N.
Error accessing memory address XXXXXX: input/output error.

This will be probably caused because the address you specified as breakpoint does not match with the beginning of an instruction.


No comments:

Post a Comment