tmxklab
[pwnable.kr] otp 본문
1. 문제 확인
otp@pwnable:~$ ls -l
total 20
-r--r----- 1 otp_pwn root 65 Jun 14 2014 flag
-r-sr-x--- 1 otp_pwn otp 9052 Jun 14 2014 otp
-rw-r--r-- 1 root root 820 Jun 14 2014 otp.c
1) mitigation 확인
2) 문제 확인
3) 코드 흐름 확인
3-1) otp.c
#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;
}
- 로직은 생각보다 간단하다.
- 난수 값(/dev/urandom)16byte 가져와 /tmp/"난수값" 파일을 생성한다.
- 그리고 거기다가 난수 값의 상위 8byte를 저장하고 ptr변수에 값을 가져온다.
- 마지막으로 argv[1]과 난수 값 8byte를 비교한다.
딱히, 취약점이라고 보일만한 것은 보이질 않는다.
2. 접근 방법
위에서 코드를 보면 굉장히 쓸데없이 긴 것을 알 수 있다. 걍 랜덤 값 가져와서 비교하면 될 것을 /tmp/에 난수 값 파일을 만들고 난수 값 저장하고 난수 값을 가져오고....
중요한 부분은 파일이 만들어지고 fwrite()를 통해 해당 파일에 난수 값을 쓰는 것인데 여기서 ulimit라는 명령어를 사용하면 최대 파일 사이즈 크기를 지정할 수 있다는 것이다.
미리 ulimit로 파일 사이즈를 0으로 제한을 두고 otp프로그램이 실행되고 fwrite()를 통해 난수 값을 쓸 때 파일 사이즈가 제한되었기 때문에 프로세스가 종료하게 된다. (ulimit : 프로세스의 자원 한도를 설정하는 명령어)
3. 문제 풀이
ulimit로 파일 사이즈 제한을 0으로 걸어두고 otp를 실행시킬 때 널 값을 넣는다.
'War Game > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] ascii_easy (0) | 2021.06.07 |
---|---|
[pwnable.kr] simple login (0) | 2021.06.07 |
[pwnable.kr] md5 calculator (0) | 2021.01.15 |
[pwnable.kr] brain fuck (0) | 2021.01.14 |
[pwnable.kr] horcruxes (0) | 2020.12.02 |
Comments