Skip to content

lab12 32bits -> 64bits #129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 58 additions & 58 deletions labs/lab-12/README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
---
nav_order: 12
parent: Labs
has_children: true
---

# Lab 12 - CTF

## Getting the Latest Changes

Before starting this lab, ensure you have the latest changes.
If you have no local changes, you can simply run `git pull` and you are ready to go:

```console
student@hsi:~$ cd hardware-software-interface
student@hsi:~/hardware-software-interface$ git status # Check if you have unstaged changes
On branch main
nothing to commit, working tree clean

# "working tree clean" means that you have no changes
student@hsi:~/hardware-software-interface$ git checkout main # Change branch to main
student@hsi:~/hardware-software-interface$ git pull --rebase
```

If the `git status` output differs, follow the [instructions to save your progress](#save-progress-and-prepare-next-lab).

## Save Progress and Prepare Next Lab

1. Check if you have unstaged changes that might be lost:

```console
student@hsi:~$ cd hardware-software-interface
student@hsi:~/hardware-software-interface$ git status
On branch <not-important>
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: main.c
```

If `git status` states "work tree clean", you should follow the [instructions to pull latest changes](#getting-the-latest-changes) instead.

1. Create a commit to store your changes:

```console
student@hsi:~/hardware-software-interface$ git add .
student@hsi:~/hardware-software-interface$ git commit -m "Store progress for lab-11"
student@hsi:~/hardware-software-interface$ git status # double check that everything was committed
On branch <not-important>
nothing to commit, working tree clean
```

1. Create a new branch for lab-12:

```console
student@hsi:~/hardware-software-interface$ git checkout -b lab-12 main # Replace lab-12 with lab number
student@hsi:~/hardware-software-interface$ git pull origin main # Get latest changes from origin/main
```
---

Check failure on line 1 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
nav_order: 12

Check failure on line 2 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
parent: Labs

Check failure on line 3 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
has_children: true

Check failure on line 4 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
---

Check failure on line 5 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings

Check failure on line 6 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
# Lab 12 - CTF

Check failure on line 7 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings

Check failure on line 8 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
## Getting the Latest Changes

Check failure on line 9 in labs/lab-12/README.md

View workflow job for this annotation

GitHub Actions / Checkpatch

ERROR:DOS_LINE_ENDINGS: DOS line endings
Before starting this lab, ensure you have the latest changes.
If you have no local changes, you can simply run `git pull` and you are ready to go:
```console
student@hsi:~$ cd hardware-software-interface
student@hsi:~/hardware-software-interface$ git status # Check if you have unstaged changes
On branch main
nothing to commit, working tree clean
# "working tree clean" means that you have no changes
student@hsi:~/hardware-software-interface$ git checkout main # Change branch to main
student@hsi:~/hardware-software-interface$ git pull --rebase
```
If the `git status` output differs, follow the [instructions to save your progress](#save-progress-and-prepare-next-lab).
## Save Progress and Prepare Next Lab
1. Check if you have unstaged changes that might be lost:
```console
student@hsi:~$ cd hardware-software-interface
student@hsi:~/hardware-software-interface$ git status
On branch <not-important>
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: main.c
```
If `git status` states "work tree clean", you should follow the [instructions to pull latest changes](#getting-the-latest-changes) instead.
1. Create a commit to store your changes:
```console
student@hsi:~/hardware-software-interface$ git add .
student@hsi:~/hardware-software-interface$ git commit -m "Store progress for lab-11"
student@hsi:~/hardware-software-interface$ git status # double check that everything was committed
On branch <not-important>
nothing to commit, working tree clean
```
1. Create a new branch for lab-12:
```console
student@hsi:~/hardware-software-interface$ git checkout -b lab-12 main # Replace lab-12 with lab number
student@hsi:~/hardware-software-interface$ git pull origin main # Get latest changes from origin/main
```
6 changes: 3 additions & 3 deletions labs/lab-12/media/rop-anatomy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 53 additions & 53 deletions labs/lab-12/reading/rop.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
---
nav_order: 9
parent: Lab 12 - CTF
has_children: true
---

# Reading: CTF

In this laboratory, you will have to apply most of the concepts presented throughout this course under the format of `Capture-The-Flag` tasks.
These tasks will test your understanding and mastery of specific static and dynamic analysis methods and tools, the compilation process, assembly language - syntax, registers, memory handling, functions, - as well as your ability to identify and exploit simple buffer overflow vulnerabilities.

## Return Oriented Programming

For the bonus exercise, you will have to use Return Oriented Programming (ROP).
This is a technique in which, if we have the ability to overwrite the return address, we execute `gadgets`.
These `gadgets` are simply portions of the existing code that end with a `ret` instruction.

Examples of gadgets include:

```asm
pop rdi ; mov rdx, rax ; mov r12, rax ; jmp 0xd178
pop rdi ; pop rbp ; ret
pop rdi ; ret
pop rsi ; pop rdi ; jmp 0xbd5f
```

Notice that each gadget must end in a control-flow instruction, such as a `ret` or a `jmp`.
The reason is so that they can be chained together.
We usually write payloads that contain the addresses of these snippets.
Then we trigger the ROP attack by placing this payload to overwrite a code pointer with the first address in the payload (such as overwriting the return address with this address).

Follow the example below to get a better picture:

![ROP Anatomy](../media/rop-anatomy.svg)

The image above aims to execute `pop rdx; pop rbx; ret`.
Let's assume a function's return address is overwritten with that of the gadget, `gadget_addr`.
The following things are going to happen:

1. The function's `ret` will be executed and the `rip` will move to the first instruction of the gadget: `pop rdx`;
the `rsp` will move towards the number 3 on the stack.

1. `pop rdx` is executed, so the number pointed by `rsp` is popped into `rdx`, which is 3;
`rsp` increases and now points to 4.

1. Similarly, `pop rbx` will pop the number 4 into `rbx`;
now `rsp` points to the new return address.

1. The gadget's `ret` is executed, thus allowing us to execute new code:
either a separate function, or a new gadget.

To determine the address of a gadget in a binary, there is the tool [ROPgadget](https://github.com/JonathanSalwan/ROPgadget).
Alternatively, in `pwndbg`, you can use a command like `rop --grep "pop rsi"`.
---
nav_order: 9
parent: Lab 12 - CTF
has_children: true
---
# Reading: CTF
In this laboratory, you will have to apply most of the concepts presented throughout this course under the format of `Capture-The-Flag` tasks.
These tasks will test your understanding and mastery of specific static and dynamic analysis methods and tools, the compilation process, assembly language - syntax, registers, memory handling, functions, - as well as your ability to identify and exploit simple buffer overflow vulnerabilities.
## Return Oriented Programming
For the bonus exercise, you will have to use Return Oriented Programming (ROP).
This is a technique in which, if we have the ability to overwrite the return address, we execute `gadgets`.
These `gadgets` are simply portions of the existing code that end with a `ret` instruction.
Examples of gadgets include:
```asm
pop rdi ; mov rdx, rax ; mov r12, rax ; jmp 0xd178
pop rdi ; pop rbp ; ret
pop rdi ; ret
pop rsi ; pop rdi ; jmp 0xbd5f
```
Notice that each gadget must end in a control-flow instruction, such as a `ret` or a `jmp`.
The reason is so that they can be chained together.
We usually write payloads that contain the addresses of these snippets.
Then we trigger the ROP attack by placing this payload to overwrite a code pointer with the first address in the payload (such as overwriting the return address with this address).
Follow the example below to get a better picture:
![ROP Anatomy](../media/rop-anatomy.svg)
The image above aims to execute `pop rdx; pop rbx; ret`.
Let's assume a function's return address is overwritten with that of the gadget, `gadget_addr`.
The following things are going to happen:
1. The function's `ret` will be executed and the `rip` will move to the first instruction of the gadget: `pop rdx`;
the `rsp` will move towards the number 3 on the stack.
1. `pop rdx` is executed, so the number pointed by `rsp` is popped into `rdx`, which is 3;
`rsp` increases and now points to 4.
1. Similarly, `pop rbx` will pop the number 4 into `rbx`;
now `rsp` points to the new return address.
1. The gadget's `ret` is executed, thus allowing us to execute new code:
either a separate function, or a new gadget.
To determine the address of a gadget in a binary, there is the tool [ROPgadget](https://github.com/JonathanSalwan/ROPgadget).
Alternatively, in `pwndbg`, you can use a command like `rop --grep "pop rsi"`.
Empty file modified labs/lab-12/tasks/feeling-chained/solution/exploit.sh
100755 → 100644
Empty file.
Empty file modified labs/lab-12/tasks/feeling-chained/support/exploit.sh
100755 → 100644
Empty file.
Empty file modified labs/lab-12/tasks/feeling-chained/tests/graded_test.inc.sh
100755 → 100644
Empty file.
Empty file modified labs/lab-12/tasks/feeling-chained/tests/run_all_tests.sh
100755 → 100644
Empty file.
Empty file modified labs/lab-12/tasks/feeling-chained/tests/tests.sh
100755 → 100644
Empty file.
26 changes: 13 additions & 13 deletions labs/lab-12/tasks/hidden-in-plain-sight-1/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
nav_order: 1
parent: Lab 12 - CTF
has_children: true
---

# Task: Hidden in Plain Sight

The `hidden-in-plain-sight-1/support/link` binary provides everything you need.
Find a way to use it.
> **TIP:** If you want a main function to be done right, you gotta do it yourself.

If you are having trouble solving this exercise, check [this](https://stackoverflow.com/questions/15441877/how-do-i-link-object-files-in-c-fails-with-undefined-symbols-for-architecture).
---
nav_order: 1
parent: Lab 12 - CTF
has_children: true
---
# Task: Hidden in Plain Sight
The `hidden-in-plain-sight-1/support/link` binary provides everything you need.
Find a way to use it.
> **TIP:** If you want a main function to be done right, you gotta do it yourself.
If you are having trouble solving this exercise, check [this](https://stackoverflow.com/questions/15441877/how-do-i-link-object-files-in-c-fails-with-undefined-symbols-for-architecture).
50 changes: 25 additions & 25 deletions labs/lab-12/tasks/hidden-in-plain-sight-1/solution/Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
CC = gcc
CFLAGS = -g -m32 -z execstack -fno-PIC -fno-stack-protector
LDFLAGS = -no-pie -m32
SRC_DIR = .
TARGET = main

all: $(TARGET)

obfuscator: $(SRC_DIR)/obfuscator.c
$(CC) -o $@ $< -m32 -fno-stack-protector -z execstack -no-pie -Wall

deobfuscator: $(SRC_DIR)/deobfuscator.c
$(CC) -o $@ $< -m32 -fno-stack-protector -z execstack -no-pie -Wall

link: $(SRC_DIR)/link.c
$(CC) $(CFLAGS) -c -o $@ $<

$(TARGET): link main.o
$(CC) $(LDFLAGS) link main.o -o $(TARGET)

main.o: $(SRC_DIR)/main.c
$(CC) $(CFLAGS) -c -o main.o $(SRC_DIR)/main.c

clean:
rm -rf link main.o $(TARGET) obfuscator deobfuscator
CC = gcc
CFLAGS = -g -m64 -z execstack -fno-PIC -fno-stack-protector
LDFLAGS = -no-pie -m64
SRC_DIR = .
TARGET = main
all: $(TARGET)
obfuscator: $(SRC_DIR)/obfuscator.c
$(CC) -o $@ $< -m64 -fno-stack-protector -z execstack -no-pie -Wall
deobfuscator: $(SRC_DIR)/deobfuscator.c
$(CC) -o $@ $< -m64 -fno-stack-protector -z execstack -no-pie -Wall
link: $(SRC_DIR)/link.c
$(CC) $(CFLAGS) -c -o $@ $<
$(TARGET): link main.o
$(CC) $(LDFLAGS) link main.o -o $(TARGET)
main.o: $(SRC_DIR)/main.c
$(CC) $(CFLAGS) -c -o main.o $(SRC_DIR)/main.c
clean:
rm -rf link main.o $(TARGET) obfuscator deobfuscator
42 changes: 26 additions & 16 deletions labs/lab-12/tasks/hidden-in-plain-sight-1/solution/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
---
nav_order: 1
parent: 'Task: Hidden in Plain Sight'
---

# Solution

Looking at the disassembly of the `link` binary, it is noticeable that there is no `main()` function.
This is a clear indicator that we have to find a way to call it ourselves.

We define a `get_flag()` function prototype as void (you may be able to skip this step, but there will be an implicit declaration error during compilation) and we call it in our main function.
We then compile and assemble the file:
`gcc -g -m32 -fno-PIC -c main.c`

We then link it to the `link` binary:
`gcc -no-pie -m32 link main.o -o a.out`
---
nav_order: 1
parent: 'Task: Hidden in Plain Sight'
---

# Solution

Looking at the disassembly of the `link` binary, it is noticeable that there is no `main()` function.
This is a clear indicator that we have to find a way to call it ourselves.

We define a `get_flag()` function prototype as void (you may be able to skip this step, but there will be an implicit declaration error during compilation) and we call it in our main function.
We then compile and assemble the file:
`gcc -g -m64 -fno-PIC -c main.c`

This command compiles `main.c` into an object file `main.o` without position-independent code (PIC): -fno-PIC.
The `-g` flag is used to include debugging information, and `-m64` specifies that we are compiling for a 64-bit architecture.
The `-c` flag tells the compiler to compile the source file into an object file without linking it.

We then link it to the `link` binary:
`gcc -no-pie -m64 link main.o -o a.out`

This command links the `link` binary with our object file `main.o` to create an executable named `a.out`.
The `-no-pie` flag is used to disable position-independent executables, and `-m64` specifies that we are linking for a 64-bit architecture.

Finally, we run the executable:
`./a.out`
Loading
Loading