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,變成stdin
      if(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打開文件
  • 因此可以利用此漏洞,當執行到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,而使用者輸入的密碼為111111111111111111111111111111做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 :(

results matching ""

    No results matching ""