<Homework>
1. mic_check 폴더 안에 있는 mic 바이너리를 실행하여 pwntools Master!!! 출력하기
<Environment>
Macbook Air 15, Apple M2, 16GB ram, 1TB storage
MAC Sequoia 15.1 Beta (24B5070e)
Parallels Desktop 18 for Mac (Ubuntu 22.04 ARM 64)
제공된 file은 mic.c source code와 해당 code를 compile 한 것으로 보이는 mic binary 파일로 총 2개가 들어있다.
우선 mic.c file을 열어보자.
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>
#include <time.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
int main() {
init();
int num1, num2, userInput, i;
fd_set readfds;
struct timeval tv;
srand(time(NULL));
for (i = 0; i < 20; i++) {
num1 = rand() % 10;
num2 = rand() % 10;
printf("%d: %d * %d : ", i + 1, num1, num2);
// select()를 이용하여 0.2초 동안 입력을 기다림
FD_ZERO(&readfds);
FD_SET(STDIN_FILENO, &readfds);
tv.tv_sec = 0;
tv.tv_usec = 200000; // 0.2초 = 200,000 마이크로초
int ret = select(STDIN_FILENO + 1, &readfds, NULL, NULL, &tv);
if (ret == -1) {
perror("select");
exit(EXIT_FAILURE);
} else if (ret == 0) {
printf("timeout\n");
exit(EXIT_FAILURE);
} else {
if (FD_ISSET(STDIN_FILENO, &readfds)) {
scanf("%d", &userInput);
if (userInput == num1 * num2) {
printf("correct!\n");
} else {
printf("wrong\n");
exit(EXIT_FAILURE);
}
}
}
}
printf("pwntools Master!!!\n");
return 0;
}
살펴보면, int형 variable인 num1, num2를 ramdom 하게 생성해 두 수를 multiplication 한 값을 입력받아 해당 값이 맞다면 corroct!\n라는 string을 맞지 않다면 wrong\n이라는 string을 출력하고 exit 하는 모습을 볼 수 있다. code의 맨 아래에 pwntools Master!!!\n을 print 하고 있는 것으로 보아 exit을 피해야 되는, 즉 정답을 맞혀야 되는 것을 확인할 있다. 해당 설명이 맞는지 확인하지 위해 Ubuntu에 설치된 qemu를 통해 실행해 보자(필자는 arm architecture인 m2 사용 중이라 x86-64 arch에서 complie 된 ELF 실행이 불가능하다).
*arm user가 ELF file을 execute 하는 불쌍한 상황을 방지하기 위해 qemu를 사용하는 방법은 이후 따로 post를 만들어 다뤄보도록 하겠다.
예상한 것과 같이 print 되는 것을 확인할 수 있다.
pwntools를 사용해 해당 문제를 solve 해보자. python code는 아래와 같다.
from pwn import *
p = process(['/usr/bin/qemu-x86_64', '-L', '/usr/x86_64-linux-gnu', './mic'])
for i in range(20):
p.recvuntil(b': ')
num1 = p.recvuntil(b' ')[:-3]
num2 = p.recvuntil(b' ')[0:1]
result = int(num1) * int(num2)
p.sendline(str(result).encode())
p.recvuntil(b'\n')
print(p.recvall())
위에서 살펴본 c code에서
for (i = 0; i < 20; i++)
해당 for문을 확인하면 20번 loop 함을 알 수 있으므로 20번 반복하도록 하였고, function recvuntil을 통해 받은 binary를 slicing 하여 int형으로 변환하여 multiplication 연산 후 다시 string으로 변환 및 function encode를 통해 bytes type로 변환하여 sendline 한다.
pwntools Master!!!\n이 잘 출력된 것을 확인할 수 있다.
'Pay1oad > Pwnable Study' 카테고리의 다른 글
[Pay1oad] Pwnable Study Week 3 - 3week_HW: r2c (0) | 2024.11.11 |
---|---|
[Pay1oad] Pwnable Study Week 2 - bof_basic (0) | 2024.11.10 |
[Pay1oad] Pwnable Study Week 1 - Pay1oad Welcome CTF Writeup (0) | 2024.10.01 |
[Pay1oad] Pwnable Study Week 1 - Handray (0) | 2024.09.28 |