1 - Introduction to RE&PE

6 minute read

How’s it going everyone. So this tutorial series is for those who want to learn the basics of a few topics:

  1. Reverse Engineering
  2. Penetration Testing
  3. Network Security

I may decide to add more to the list, but we are going to start with these three. I don’t want to label this as a “how to hack” tutorial set. I won’t be teaching modern hacking techniques, but rather fundamental lessons in order to understand higher levels of security engineering.

I will be starting with reverse engineering, and this introductory post is for environment set up and to refresh your memory of C programming.

Vagrant

Vagrant is a development environment software. Similar to docker, we can make VM’s for all sorts of operating systems. Download Vagrant for your machine:

Vagrant Downloads

It is also important to download VirtualBox, which will act as the “VM Provider” for our development machines:

Virtual Box Downloads

Once these are both downloaded, open up a terminal and create a folder “Vagrant”, this is where your going to keep your vagrant machines.

Enter this directory and let’s create our first machine. We are going to start with Ubuntu (Xenial64 Edition):

$ vagrant init ubuntu/xenial64

That command will create a Vagrantfile for you. Vagrant files have configuration details for your “box”. We are going to mess around with these configurations later on, but for now let’s boot up our box:

$ vagrant up

This will begin the creation process of our new VM. You will see some items for the SSH address and username. Host names can be changed in the Vagrantfile.

To make sure our vagrant machine is up to date:

$ vagrant box update

Now that we have created and updated our vagrant machine, let’s enter the machine:

$ vagrant ssh

You should now be in the vagrant machine, which is a mini ubuntu box. To exit out:

ubuntu@ubuntu-xenial:~$ exit

Changing some configurations

Let’s change some configurations in the Vagrant file. You can edit the file using any text editor.

There are a couple lines that are commented out via “#” in the vagrant file. We want to un-comment or change some of these lines. Be sure to un-comment and change the following:

Line 40: config.vm.synced_folder "../data", "/vagrant_data"

Line 46 - 52: un-comment loop and change line 51: vb.memory = "2048"

Add the following line (pick a hostname): config.vm.hostname = <whatever>

Save and reload the vagrant machine:

$ vagrant reload

Notice: If you are having issues with the following error during vagrant up:

The guest additions on this VM do not match the install version of
VirtualBox! This may cause things such as forwarded ports, shared
folders, and more to not work properly. If any of those things fail on
this machine, please update the guest additions and repackage the
box.

We can fix that by installing a plugin with vagrant plugin:

$ vagrant plugin install vagrant-vbguest

This will allow vagrant up to check and install the correct guest additions module on boot.

Tool Installation

We will be using some tools for our beginning RE exercises.

Enter your vagrant machine and download the following packages:

$ vagrant ssh
# now in vm
$ sudo apt-get update
$ sudo apt-get upgrae
$ sudo apt-get install lsb-core libc6-i386 libc6-dev-i386 build-essential

Lots of dependencies will be downloaded. Let’s move on to installing radare:

$ git clone https://github.com/radare/radare2
$ cd radare2
$ sys/install.sh

Radare is a portable reversing framework that can do a number of cool functions, such as disassembling different architectures and aid in software exploitation. Now that we have radare installed, we should be able to use the r2 command.

C Refresher

So before we get into some more complicated reverse engineering topics, we are going to refresh ourselves with C. The following are a few simple programs with their assembly code output. I’ll format them as tasks in case you want to have a crack at it before scrolling down to see the answer.

Task 1

Write a program that takes two command line arugments and prints the sum of these two integers. For example:

$ ./lab1-3a 4 8
12

Answer:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if(argc<2){
        printf("usage: %s [number] [number]\n", argv[0]);
    }
    else {
        printf("%d\n",atoi(argv[1]) + atoi(argv[2]));
    }

    return 0;
}

You can compile this program via the following command:

# 32 bit version 
$ gcc -m32 -o <output-filename> <input-file>
# here's how to compile while also spitting out the assembly
$ gcc -m32 -S <input-file>
# So in order to compile our file task1.c:
$ gcc -m32 -S -o task1-32 task1.c 
# Now we can call our outputted binary
$ ./task1-32
usage: ./task1-32 [number] [number]

$ ./task1-32 3 5
8

Also we have the task.s file

If we look at some assembly without any knowledge it looks scary as hell:

	.file	"task1.c"
	.section	.rodata
.LC0:
	.string	"usage: %s [number] [number]\n"
.LC1:
	.string	"%d\n"
	.text
	.globl	main
	.type	main, @function
main:
.LFB2:
	.cfi_startproc
	leal	4(%esp), %ecx
	.cfi_def_cfa 1, 0
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	.cfi_escape 0x10,0x5,0x2,0x75,0
	movl	%esp, %ebp
	pushl	%esi
	pushl	%ebx
	pushl	%ecx
	.cfi_escape 0xf,0x3,0x75,0x74,0x6
	.cfi_escape 0x10,0x6,0x2,0x75,0x7c
	.cfi_escape 0x10,0x3,0x2,0x75,0x78
	subl	$12, %esp
	movl	%ecx, %ebx
	cmpl	$1, (%ebx)
	jg	.L2
	movl	4(%ebx), %eax
	movl	(%eax), %eax
	subl	$8, %esp
	pushl	%eax
	pushl	$.LC0
	call	printf
	addl	$16, %esp
	jmp	.L3
.L2:
	movl	4(%ebx), %eax
	addl	$4, %eax
	movl	(%eax), %eax
	subl	$12, %esp
	pushl	%eax
	call	atoi
	addl	$16, %esp
	movl	%eax, %esi
	movl	4(%ebx), %eax
	addl	$8, %eax
	movl	(%eax), %eax
	subl	$12, %esp
	pushl	%eax
	call	atoi
	addl	$16, %esp
	addl	%esi, %eax
	subl	$8, %esp
	pushl	%eax
	pushl	$.LC1
	call	printf
	addl	$16, %esp
.L3:
	movl	$0, %eax
	leal	-12(%ebp), %esp
	popl	%ecx
	.cfi_restore 1
	.cfi_def_cfa 1, 0
	popl	%ebx
	.cfi_restore 3
	popl	%esi
	.cfi_restore 6
	popl	%ebp
	.cfi_restore 5
	leal	-4(%ecx), %esp
	.cfi_def_cfa 4, 4
	ret
	.cfi_endproc
.LFE2:
	.size	main, .-main
	.ident	"GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609"
	.section	.note.GNU-stack,"",@progbits

Don’t worry, we will go into what this gibberish means and why it is significant.

Here’s the command to output the assembly in intel syntax:

gcc -m32 -S -masm=intel task1.c

Intel is less overwhelming than AT&T so we will mainly be looking at Intel format.

Task 2: Pointer Refresher Write a program that does the following:

  1. Assign a value to variable x
  2. Assign a pointer y to variable x
  3. Print the value of x, y, and the address of x and y
  4. Print out the value that y is pointing at

Answer:

#include <stdio.h>

int main(int argc, char* argv[])
{
    int x = 8;
    int *y = &x;
    printf("The Value of x is %d\n", x);
    printf("The Value of y is %x\n", y);
    printf("The Address of x is %x\n", &x);
    printf("The Address of y is %x\n", &y);
    printf("The Value pointed at by y is %d\n", *y);

    return 0;
}

If we compile this we get the following output:

The Value of x is 8
The Value of y is ff874534
The Address of x is ff874534
The Address of y is ff874538
The Value pointed at by y is 8

Things might be coming back to ya now ;). If not thats ok. Pointers can be tricky, but try to think of it as simply as they literally point to another spot of memory. An asterisk specifies a pointer (*) and an ampersand represents “the address of”.

  1. We create a variable x that has a value of 8. The actual spot of memory where this 8 variable exists is at &x.
  2. We create a pointer y to reference the address of x. This means that the value of y will be the same as the address of x.
  3. The address of y will be unique in itself. It may sound silly, but pointers need their spot in memory too, but in this can it is not far, only a byte off.
  4. Since y is a pointer, we can get the value that it references to by adding an asterisk in front *y

That’s it for today. We have set up our vagrant machine along with our RE dependencies. Next time we mess with Vagrant we will try some manual de-compilation. Until next time my friends.

Updated: