【问题标题】:Pass binary data to stdin of a program based on its stdout根据程序的标准输出将二进制数据传递给程序的标准输入
【发布时间】:2019-03-11 12:25:57
【问题描述】:

我有一个程序 A,它打印一些文本数据,然后从标准输入执行 gets() 读取。 我想创建一个程序/脚本,它将读取 A(文本数据)的标准输出并基于输出将数据(二进制)传递到其标准输入。

该程序是一个简单的漏洞利用演示(格式化字符串漏洞转储堆栈,然后基于转储值制作利用有效载荷,然后通过gets传递以触发缓冲区溢出并执行制作的shellcode)。

int main(int argc, char** argv)
{
    char buffer[20];
    BOOL(__stdcall *getName)(LPSTR lpBuffer, LPDWORD nSize) = GetComputerNameA;

    printf("The argument is: ");
    printf(argv[1]);
    printf("\r\n");

    printf("Enter a message: ");
    gets(buffer);
    printf("Your message is: %s", buffer);

    TCHAR name[20];
    DWORD len = 19;
    getName(name, &len);
    printf("Your computer is called %s", name);
    printf("\r\n");
}

我曾尝试在 python 中通过 target.stdout.readline() 和 target.stdin.write() 执行此操作,但 readline 挂起并且永远不会返回。 我还通过 OutputDataReceived 事件在 C# 中进行了尝试,但如果我没有传递任何输入,我只能读取输出。一旦我重定向了标准输入,我就无法阅读任何内容。也发生了挂起。

我的问题是如何实现这一目标?

编辑: 执行程序的python代码示例

from subprocess import Popen, PIPE, STDOUT
x = Popen(['test.exe', '"%08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x %08x"', 'start'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)

out = x.stdout.readline()
print(out)
input("{press enter}")

data = bytearray(...payload...)
payload = buffer(data)
x.stdin.write(payload)
input("{press enter}")

【问题讨论】:

  • char buffer[20]; 对于gets() 看起来很小。最好移动到更大的缓冲区和fgets()
  • 缓冲区大小故意这么小。它意味着溢出。

标签: c windows security stdout stdin


【解决方案1】:

在 C 中 printf 使用缓冲输出。当 stdout 到终端时,缓冲区在每个"\n" 之后被刷新,但在这种情况下,输出到管道,因此它被缓冲到几 k 字节的数据。缓冲区永远不会刷新,也不会写入管道。

为避免python永远等待缓冲的数据,您可以在每个printfdisable buffering altogether之后添加fflush(stdout)

【讨论】:

    猜你喜欢
    • 2015-01-06
    • 1970-01-01
    • 2010-12-01
    • 2011-09-02
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多