Mở đầu

Giải này diễn ra trong thời gian lúc đang ôn thi nên cũng không tập trung được nhiều lắm. Cơ mà mình vẫn dành thời gian để note lại cái bài duy nhất mình làm được. Nó là một bài pwn nên mình vẫn thấy khá hài lòng với kết quả hiện tại . Trong thời gian tới sẽ cố cày pwn thêm. Cảm giác cày pwn não to ra vl luôn.

Description

Các bạn có thể tìm source và solve tại đây
Ngoài ra thì chả có description nào khác ngoài tên bài ra cả.Nghe tên là đã biết sử dụng lỗi overflow rồi.

Phân tích binary

Trong binary thì chỉ có một hàm mà chúng ta cần lưu ý : hinh1

Hàm này cho phép chúng ta nhập vào một số thực và lưu giá trị dưới dạng float vào mảng s . Lưu ý là mảng s này nằm ở trong stack của hàm main chứ không phải trong hàm chartcourse .
Tới đây có thể nhận ra rõ ràng là ta có thể viết một số lượng tùy ý lên biến s mà không bị giới hạn . Tức là ta có một lỗi tràn.
Kiểm tra lại bài này không có canary nên ta có thể tràn thoải mái mà không sợ gì.
Có một điểm lưu ý nhỏ là nó lưu giá trị kiểu số thực chứ không phải số nguyên .Nên cần hàm để chuyển đổi

def int_to_float(num):
    bit = bin(num)
    return struct.unpack('!f',struct.pack('!I', int(bit, 2)))[0]

Thêm nữa, bài này là 64 bit mà mỗi lần chỉ ghi 32 bit nên chúng ta cũng cần cẩn thận khi tràn địa chỉ , tránh nhầm lẫn .Do vậy để thuận tiện nên mình có viết một hàm riêng để tràn số cũng như set địa chỉ cần thiết.

def set_float(num) :
    print sh.recvuntil("]: ")
    float_ = int_to_float(num)
    sh.sendline(str(float_))

def set_addr(addr) :
    addr_ = str(hex(addr))[2:].zfill(16)
    addr_l = int(addr_[8:],16)
    addr_h = int(addr_[:8],16)
    set_float(addr_l)
    set_float(addr_h)

Kết

Chúng ta đã có tất cả công cụ cần thiết để thực hiện việc tràn số. Việc còn lại chỉ là ROP và gọi những hàm cần thiết thôi . Lưu ý là call convention trong 64 bit là lưu các tham số trong các thanh ghi theo thứ tự : rdi,rsi,rdx,rcx,r8,r9 .
Các bạn có thể tham khảo thêm code solve mình viết tại đây.