문제: 우리는 항상 실수를 한다. 시작해보자.
(여기서 해킹 스킬은 필요없다. 진지하게 생각하지 말자.)
#include <stdio.h>
#include <fcntl.h>
#define PW_LEN 10
#define XORKEY 1
void xor(char* s, int len){
int i;
for(i=0; i<len; i++){
s[i] ^= XORKEY;
}
}
int main(int argc, char* argv[])
{
int fd;
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)
{
printf("can't open password %d\n", fd);
return 0;
}
printf("do not bruteforce...\n");
sleep(time(0)%20);
char pw_buf[PW_LEN+1];
int len;
if(!(len=read(fd,pw_buf,PW_LEN) > 0))
{
printf("read error\n");
close(fd);
return 0;
}
char pw_buf2[PW_LEN+1];
printf("input password : ");
scanf("%10s", pw_buf2);
// xor your input
xor(pw_buf2, 10);
if(!strncmp(pw_buf, pw_buf2, PW_LEN))
{
printf("Password OK\n");
system("/bin/cat flag\n");
}
else
{
printf("Wrong Password\n");
}
close(fd);
return 0;
}
위 코드는 문제에서 주어진 코드이다. 해당 코드의 취약점은 힌트에서 주어진대로 연산자의 우선순위에 있다.
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)
다음 코드에서 = 보다 < 연산자가 우선순위가 빠르므로 password 파일 디스크립터와 0을 비교하게 되는데 파일 디스크립터는 최소 3이므로 0보다 크다. 따라서 우변의 식은 False가 되고 False는 int 로 0을 나타낸다. 따라서 fd에는 0이 저장된다.
if(!(len=read(fd,pw_buf,PW_LEN) > 0))
위 코드에서도 >연산자를 잘못 사용하였다. fd가 0이므로 read 함수는 pw_buf에 입력한 문자열 갯수를 반환하는데 0보다 클것이므로 참이고 앞에 !가 붙어서 거짓이된다.
scanf("%10s", pw_buf2);
위 코드는 pw_buf2에 입력을 받는다.
xor(pw_buf2, 10);
다음 함수는 10만큼 xor 연산을 한다.
if(!strncmp(pw_buf, pw_buf2, PW_LEN))
마지막으로 pw_buf와 pw_buf2를 10만큼 비교하는데 두 문자열 모두 원하는 값을 입력할 수 있다. 예를 들어 pw_buf에 "A"를 10개 넣는다면 "A"는 int 형으로 97을 나타내고 xor을 하면 96이 된다. 96을 나타내는 아스키코드는 @이다. 따라서 pw_buf에 "AAAAAAAAAA" pw_buf2에 "@@@@@@@@@@"을 대입하면 플래그가 출력된다.
'시스템 해킹 > pwnable.kr' 카테고리의 다른 글
[Pwnable.kr] passcode (0) | 2021.07.27 |
---|---|
[Pwnable.kr] cmd1 (0) | 2021.04.21 |
[Pwnable.kr] flag (0) | 2021.04.19 |
[Pwnable.kr] collision (0) | 2021.04.19 |
[Pwnable.kr] bof (0) | 2021.03.24 |
댓글