# Some more shellcode

# Abstract
*In this series of articles, I am analysing the pieces of shellcode written by Odzhan on the page [Shellcode: Mac OSX amd64](https://modexp.wordpress.com/2017/01/21/shellcode-osx/). 
*

*In the last article, [Come taste some shellcode...](https://blog.reveng3.org/come-taste-some-shellcode), we introduced some basic binary analysis and we learned how to call a syscall with no arguments. In this article, we will analyse how to work with more complex arguments.
*

*I will also introduce the hopper disassembler ([https://www.hopperapp.com/](https://www.hopperapp.com/)), one of the tools I use the most.*

# Execute a command

We start with the code:

```
; 43 bytes execute command
;
bits    64

global _main
_main:
    push    59
    pop     rax         ; eax = sys_execve
    cdq                 ; edx = 0
    bts     eax, 25     ; eax = 0x0200003B
    mov     rbx, '/bin//sh'
    push    rdx         ; 0
    push    rbx         ; "/bin//sh"
    push    rsp
    pop     rdi         ; rdi="/bin//sh", 0
    ; ---------
    push    rdx         ; 0
    push    word '-c'
    push    rsp
    pop     rbx         ; rbx="-c", 0
    push    rdx         ; argv[3]=NULL
    jmp     l_cmd64

r_cmd64:                ; argv[2]=cmd
    push    rbx         ; argv[1]="-c"
    push    rdi         ; argv[0]="/bin//sh"
    push    rsp
    pop     rsi         ; rsi=argv
    syscall

l_cmd64:
    call    r_cmd64
    ; put your command here followed by null terminator
    db      'cat /etc/passwd',0

```

We compile and link it:
```
gbiondo@tripleX Odzhan % nasm -f macho64 cmdRun.asm
gbiondo@tripleX Odzhan % ld -L /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib -lSystem -o cmdRun cmdRun.o
```
and we can obviously run it. I will not - why should I disclose the users in my machine, anyway? - however, it runs perfectly on my MacOS Monterey.

## A bit of static analysis
If you read this blog, the following commands should not be new to you. If not, you may want to read previous articles :) or do some ```man``` around. 
### Getting information about the executable
```
gbiondo@tripleX Odzhan % file cmdRun
cmdRun: Mach-O 64-bit executable x86_64
```
No surprises here. Just compare the above with how we compiled the file.
### Looking for C strings
There is none. in fact:
```
gbiondo@tripleX Odzhan % strings cmdRun
gbiondo@tripleX Odzhan % 
```
### Getting information about the sections
This is a very simple program, after all:
```
gbiondo@tripleX Odzhan % objdump -m --section-headers cmdRun

Sections:
Idx Name          Size     VMA              Type
  0 __text        0000003b 0000000100003f7d TEXT
  1 __unwind_info 00000048 0000000100003fb8 DATA
```
### Getting the symbol table
No big hint is given by the symbol table:
```
gbiondo@tripleX Odzhan % objdump -m --syms cmdRun           
cmdRun:

SYMBOL TABLE:
0000000100003f9d l     F __TEXT,__text r_cmd64
0000000100000000 g       *ABS* __mh_execute_header
0000000100003f7d g     F __TEXT,__text _main
```
## Dynamic Analysis
Time for some debugging. This time we are using Hopper. This is not supposed to be a tutorial for hopper (which can be found here: [https://www.hopperapp.com/tutorial.html](https://www.hopperapp.com/tutorial.html) or under the menu **Help** of the application).

Let's remember what an ```execve```-based shellcode must do:

* first parameter must be stored in ```RDI```. It is a pointer to a string, holding the path of the executable.
* second parameter must be stored in ```RSI```. It is a pointer to a null-terminated array of strings, containing the parameters to the command.
* third parameter must be stored in ```RDX```. It is a pointer to a null-terminated array of strings, containing the environment variables.

I am choosing **Select Debugger** from the **Debug** menu, and I opt for the local debugger. I am then presented with this window:


![Screenshot 2022-04-07 at 15.05.17.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649340325090/34T5PnLIr.png)

Observe the "Controls" box. There are 10 buttons. From left to right, these are:
* Continue execution
* Pause execution
* Step into
* Step out
* Step over
* Continue until current position
* Continue until basic block end
* Trace procedure
* Stop execution
* Toggle breakpoint

Below, a Tab View controller can be seen. It contains four main areas we are interested into:
* General purpose registers (GPR)
* Memory
* Debugger Console
* Application Output

I also set a breakpoint at the beginning of the ```main``` routine:

![Screenshot 2022-04-07 at 15.05.57.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649340393139/4pgaH5jpQ.png)

It's worthwhile to set some breakpoints around. At the beginning, we'll stop at each single instruction.

If we set a breakpoint to the very next instruction and we hit Continue execution twice, we'll notice how the contents of the RAX register changes (59 has been pushed to the stack and then popped to RAX).

Before:

![Screenshot 2022-04-07 at 15.21.10.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649341303978/SU5Me2iAC.png)

After:

![Screenshot 2022-04-07 at 15.21.25.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649341320714/A2tdqM1xq.png)

If we continue, there's the CDQ instruction. It sets RDX=0, since EAX is signed positive at the current point (see below). 

![Screenshot 2022-04-07 at 15.28.13.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649341723590/Ky14KKuZr.png)

Then the 25th bit is set to 1 - this technique should already be familiar to the reader, we won't illustrate it.

With the next instruction we can see something I love about Hopper. The instruction is illustrated below:

![Screenshot 2022-04-07 at 15.32.01.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649342079890/d2lo3soRq.png)
or, in plain text
```
movabs     rbx, 0x68732f2f6e69622f
```
If we right click on the ```0x68732f2f6e69622f``` operand and select "Characters", we convert it into something more human readable (in this case, ```/bin//sh```). Good job, Hopper!

![Screenshot 2022-04-07 at 15.32.55.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649342216083/dthK-8H7r.png)

and RBX will be updated accordingly.

We hit continue, and first the contents of RDX (a zeroed register) and the contents of RBX (```0x68732F2F6E69622F```, the string ```/bin//sh```) are pushed to the stack. After this, we obtain a null-terminated string containing ```/bin//sh```. 

In fact, before running the instructions, ```RSP```, the stack pointer, points to ```00007FF7BFEFFA68```. The contents of the memory can be seen in the third line of the memory dump of the image below:

![Screenshot 2022-04-08 at 09.57.59.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649408798620/vC-Be_eYV.png)

Then ```RDX``` is pushed and ```RSP``` updated accordingly, so ```RSP``` becomes ```00007FF7BFEFFA60```. The stack is updated, see second line of the memory pane: 

![Screenshot 2022-04-08 at 10.01.23.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649408815523/rLBYW9PhI.png)

Finally ```RBX``` is pushed and we have:
* ```RSP```: contains ```00007FF7BFEFFA58```
* ```RBX```: contains ```68732F2F6E69622F```
* and the stack is represented below

![Screenshot 2022-04-08 at 10.04.53.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649408835685/LpV1R5NiZ.png)

The contents of the stack are then popped in ```RDI```. Let's have a look at what we have after the instruction ```pop rdi``` is executed:

![Screenshot 2022-04-11 at 08.58.15.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649663915045/I_hM4ab8j.png)

Now the contents of ```RDX``` are pushed in the stack, and then we push also the constant ```0x632d```, which is the string ```-c```. See below:

![Screenshot 2022-04-11 at 09.05.29.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649664353997/opLNsy5Cq.png)

The stack looks as follows:

![Screenshot 2022-04-11 at 09.06.33.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649664437809/zszcBxvoN.png)

The next instruction pushes the contents of ```rsp``` in the stack, then the value is popped  in ```rbx```:

![Screenshot 2022-04-11 at 09.13.33.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649664821879/56JLKXv5m.png)

Finally, the value of ```rdx```, which is null, is pushed into the stack. Now there's a noticeable difference between the original code, with two labels (```r_cmd64``` and ```l_cmd64```), and the code that's been first assembled and linked, then disassembled. Only ```r_cmd64``` is present, and the instruction ```jmp r_cmd64+6``` is used instead. When hit 'continue', the jump sends the control flow to ```0x0000000100003FA3``` which contains ```call r_cmd64```.  Why jumping back and forth? The reason is that this way we place the pointer to the command string in the stack. Below there's the 'before'... 

![Screenshot 2022-04-11 at 09.33.41.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649666154304/R27dOl8UJ.png)

...and the 'after':

![Screenshot 2022-04-11 at 09.35.01.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649666168169/YRtYfi0Yx.png)

Now it's possible pushing ```rsp``` and popping the value into ```rsi```:

![Screenshot 2022-04-11 at 09.38.48.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649666359273/gOsnOIw0f.png)

and

![Screenshot 2022-04-11 at 09.39.09.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1649666374922/c2-N8NmLM.png)

Finally the syscall is invoked, and the execution of the shellcode terminates.

## Conclusions
As strange as it may seem, I find easier working with ```lldb``` - but I am an old guy :) 
Hopper has powerful features anyway - I am using it for many other purposes (like changing memory contents on the fly).

We have shown how to approach some static and dinamic binary analysis for this kind of programs. 

Finally: we start to _understand_ assembly, but always having no talent and being proud of having none!








