이번문제는 참 운빨로 푼 거 같다..
문제의 소스코드는 아래와 같다.
#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <unistd.h>void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
char *heap_buf = (char *)malloc(0x80);
char stack_buf[0x90] = {};
initialize();
read(0, heap_buf, 0x80);
sprintf(stack_buf, heap_buf);
printf("ECHO : %s\\n", stack_buf);
return 0;
}
여기서 주의깊게 본 부분은 여기다.

바로 srpintf 부분이다...
이 부분 때문에 삽질을 정말 많이 했다.
printf 와 srpintf 의 차이점이라고 하면 srprintf는 받는 인자를 문자열..?로 저장해 준다고 한다.
즉 int 0123 을 받으면 문자열 0123 을 저장해 출력해준다는 소리였다.
먼저 offset은 정말 쉽게 구했다.
IDA Pro를 통해 파일을 먼저 뜯어봤다.
(Pattern 만들어서 시도하다 실패해서 IDA 썻다...)

IDA main 함수 decompile...
선언되는 char s 와 void * buf 를 보면 ebp에서 얼마나 멀어져 있는지 알아낼 수 있다.
여기서 char s는 사용자에게 입력받는 buf 를 문자열로 srpintf 함수를 통해 저장하는 문자열 값을 의미한다.
ebp-98h 의 거리를 계산하면 152가 된다.
여기에 SFP 가 있을 가능성을 우려하여 4바이트를 넣고 시도해 보거나 152바이트 그대로 시도 둘다 해봤다.
하지만 안됬었다.. 이유로는 sprintf 부분과 read 함수라 페이로드 p.send로 보내야했다.
sprintf 함수의 취약점을 검색하면 됬었거늘... 나는 바보 같이 sprintf 함수의 역할을 먼저 이해하고 이거의 우회(?) 할 방법을 찾고 있었다.