C語言又再度讓我驚豔!
題目給的提示是關於運算元的優先等級,還說這題不要太認真,不需要高深的技巧XD。
連入解題主機後有這些檔案:
1 2
| mistake@ubuntu:~$ ls flag mistake mistake.c password
|
mistake.c
的原始碼:
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 46 47 48 49 50
| #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(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; }
|
既然題目已經說跟運算元有關,馬上把焦點放在第17行fd=open("/home/mistake/password",O_RDONLY,0400) < 0
,這滿有趣的,仔細思考一下,先是進行了開檔的動作,若檔案存在成功開檔,會回傳1
,再來因為<
的優先等級比=
高,所以會先進行比較,最終fd
會得到1 < 0
的比較結果是0
。
下一個焦點放在第27行,經過剛才開檔的動作以後,此時fd = 0
,根據read()
函式的定義,fd
值為0
時,會從標準輸入(stdin)讀入資料,可以讓我們輸入pw_buf
的值,不過根據後面真正讀入pw_buf2
密碼的第35行,密碼長度應該有10位數,而且pw_buf2
會進行XOR
運算,根據這些條件我們便可以輸入0000000000
給pw_buf
,1111111111
給pw_buf2
來滿足第40行的密碼判斷便可以拿到flag。
1 2 3 4 5 6
| mistake@ubuntu:~$ ./mistake do not bruteforce... 0000000000 input password : 1111111111 Password OK Mommy, the operator priority always confuses me :(
|
真的是一題有趣的題目,的確是平常在寫程式時可能會忽略的小細節,造就了不一樣的結果。