mistake
source code
#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; }
- 看起來是開啟檔案,若開啟失敗,fd為-1,而印出無法開啟檔案,但由於operator priority的關係,
<
執行優先權大於=
,所以open會因為開啟成功而等於3,3 < 0
不成立,所以是false (0),最後fd被assign為0,變成stdinif(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ printf("can't open password %d\n", fd); return 0; }
- 這個
fd
是file descriptor- 0代表stdin
- 1代表stdout
- 2代表stderr
- 3代表第一次調用open打開文件
- 4代表再調用open打開文件
- 這個
- 看起來是開啟檔案,若開啟失敗,fd為-1,而印出無法開啟檔案,但由於operator priority的關係,
因此可以利用此漏洞,當執行到read()時,就會變成透過stdin,也就是輸入的10 bytes字元,讀取成為password
if(!(len=read(fd,pw_buf,PW_LEN) > 0)){ printf("read error\n"); close(fd); return 0; }
最後password會與使用者輸入的密碼(與1做XOR)做比較,例如透過stdin輸入password為
0000000000
,而使用者輸入的密碼為1111111111
,1111111111
與1111111111
做XOR後即等於0000000000
// 與1做XOR,會得到相反的結果,例如: 11100010會變成00011101 void xor(char* s, int len){ int i; for(i=0; i<len; i++){ s[i] ^= XORKEY; } }
xor(pw_buf2, 10); if(!strncmp(pw_buf, pw_buf2, PW_LEN)){ printf("Password OK\n"); system("/bin/cat flag\n"); }
mistake@ubuntu:~$ ./mistake
do not bruteforce...
0000000000
input password : 1111111111
Password OK
Mommy, the operator priority always confuses me :(