2017-02-12 46 views
-1

我在linux中很新(只知道基本的東西)。我正試圖在Linux虛擬機中完成Capture-the-flag(CTF)風格挑戰。所以基本上我有一個C程序文件和一個標誌。我無權訪問國旗。我可以讀取程序文件並運行它。這個C代碼:Linux捕獲標誌編程難題

#include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 

    void check() { 

    int invalid; 
    if (invalid) { 
    printf ("Password invalid!\n"); 

    } 

    else{ 
    printf ("Password accepted!\n"); 
    system ("/bin/cat flag3"); 
    } 
    } 
    void password() { 

    char password [200]; 
    printf ("Enter the password: "); 
    scanf ("%s" , password); 
    } 

    int main() { 
    password(); 
    check(); 
    return 0; 
    } 

我試圖調試它,並觀察彙編內容,但我不明白如何才能知道標誌內容捕獲密碼。我試圖破解密碼從這個鏈接獲取幫助,http://eliteinformatiker.de/2012/11/16/howto-crack-a-small-c-program-with-assembler但我不知道如果我可以編輯C程序的二進制文件或不是因爲在給定的權限的C文件,我只能讀它不寫在它。所以我認爲如果我不能修改一個c文件,我該如何修改它的二進制文件(也許我錯了)。在這一點上,我有點卡住,我試圖調試它,查看程序集內容,但我不知道我是否可以編輯二進制或不。我不知道採取什麼方法來捕獲國旗?

+1

在哪裏/如何設置無效?我看到它被用在'check'函數中,我看不到它是如何設置的。 – thurizas

+0

我不確定。其實我也對這一點感到困惑。我沒有寫這個代碼。我得到了這個代碼。當我運行它時,它要求輸入密碼才能訪問標誌內容。我不知道密碼,所以現在我必須找到一些利用/後門來猜測密碼才能訪問標誌。我似乎無法找到任何利用。 – sar

+0

如果你可以調試程序,你應該可以修改比較。例如,invalid是一個局部變量,因此存儲在堆棧中。在測試之前,你應該能夠改變它的價值。 – thurizas

回答

-1

看起來像這需要緩衝區溢出腐敗。輸入超過200個字符的密碼,它會從其默認的零值中破壞無效?

+0

我已經試過了。如果密碼長度超過200個字符,則會導致分段錯誤。 – sar

+0

這是一條評論,而不是答案。 – Olaf

+0

Scant不安全,因爲它將字符存儲在變量中的空字符之前。你可以使用'\ 0'做任何有趣的事情嗎? – GandhiGandhi

0

免責聲明:我使用Ubuntu-12.04和gcc-4.8.-2和gdb-7.7.1調試器。

我在調試器下執行程序,直到我輸入了check並單步到了if。然後我拆解的代碼,並期待在大會:

(gdb) disass 
Dump of assembler code for function check: 
    0x000000000040062d <+0>: push %rbp 
    0x000000000040062e <+1>: mov %rsp,%rbp 
    0x0000000000400631 <+4>: sub $0x10,%rsp 
=> 0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp) 
    0x0000000000400639 <+12>: je  0x400647 <check+26> 
    0x000000000040063b <+14>: mov $0x400754,%edi 
    0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]> 
    0x0000000000400645 <+24>: jmp 0x400651 <check+36> 
    0x0000000000400647 <+26>: mov $0x400766,%edi 
    0x000000000040064c <+31>: callq 0x4004e0 <[email protected]> 
    0x0000000000400651 <+36>: leaveq 

而且我看了一下我的寄存器(只顯示了重要的)值:

(gdb) info reg 
    rbp   0x7fffffffdf00 0x7fffffffdf00 
    rsp   0x7fffffffdef0 0x7fffffffdef0 
    rip   0x400635 0x400635 <check+8> 
    eflags   0x206 [ PF IF ] 

接下來,我單論指令(gdb) ni踩反覆拆卸和獲得的eflags值:

(gdb) disass 
Dump of assembler code for function check: 
    0x000000000040062d <+0>: push %rbp 
    0x000000000040062e <+1>: mov %rsp,%rbp 
    0x0000000000400631 <+4>: sub $0x10,%rsp 
    0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp) 
=> 0x0000000000400639 <+12>: je  0x400647 <check+26> 
    0x000000000040063b <+14>: mov $0x400754,%edi 
    0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]> 
    0x0000000000400645 <+24>: jmp 0x400651 <check+36> 
    0x0000000000400647 <+26>: mov $0x400766,%edi 
    0x000000000040064c <+31>: callq 0x4004e0 <[email protected]> 
    0x0000000000400651 <+36>: leaveq 
    0x0000000000400652 <+37>: retq 
End of assembler dump. 
(gdb) info reg 
eflags   0x206 [ PF IF ] 

回想一下,cmp的工作方式是SIMU根據需要設置相應的減法,這就是je然後使用的。所以這段代碼將執行從0減去-0x4(%rpb)(設置零標誌爲approprate)。如果數字相同,jz將跳轉。

所以我改性用命令序列標誌寄存器:

(gdb) set $ZF = 6 
(gdb) set $eflags |= (1 << $ZF) 
(gdb) print $eflags 
$1 = [ PF ZF IF ] 

注意,零標誌現在設置。單指令集(ni),並採取看看拆解:

(gdb) ni 
(gdb) disass 
Dump of assembler code for function check: 
    0x000000000040062d <+0>: push %rbp 
    0x000000000040062e <+1>: mov %rsp,%rbp 
    0x0000000000400631 <+4>: sub $0x10,%rsp 
    0x0000000000400635 <+8>: cmpl $0x0,-0x4(%rbp) 
    0x0000000000400639 <+12>: je  0x400647 <check+26> 
    0x000000000040063b <+14>: mov $0x400754,%edi 
    0x0000000000400640 <+19>: callq 0x4004e0 <[email protected]> 
    0x0000000000400645 <+24>: jmp 0x400651 <check+36> 
=> 0x0000000000400647 <+26>: mov $0x400766,%edi 
    0x000000000040064c <+31>: callq 0x4004e0 <[email protected]> 
    0x0000000000400651 <+36>: leaveq 
    0x0000000000400652 <+37>: retq 
End of assembler dump. 

這是在別的塊,你應該得到顯示的標誌。 (請注意在我的測試程序中,我註釋掉了該標誌)。

+0

我明白你的邏輯,我試過這個。但是不顯示標誌,它仍然顯示該標誌不能打開,並且拒絕許可。 – sar

+0

設置零標誌後,它跳轉到else,但是當涉及到調用標誌內容的指令時,它顯示我無法打開該標誌。我認爲,因爲沒有root訪問權限,所以我仍然無法打開標誌。爲了獲得國旗,我必須找到其他一些利用。 – sar

+0

@sar drat ...看看這個程序,'system'命令讓我相信這個標誌位於程序所在的目錄中(注意'system/bin/cat flag3'是一個相對路徑,而不是絕對路徑)。我很想知道您是否可以導航到找到flag3的目錄,以及它的權限是什麼。我不得不懷疑,如果我們正在推翻這一點,並且如果你去到旗子所在的文件夾,並且運行'cat flag3',結果會是什麼。 (可能被拒絕,但你永遠不知道)。 – thurizas