在本文中,我们将使用
pwntools库分析多级任务的解决方案。
组织信息特别是对于那些想要学习新知识并在信息和计算机安全性的任何领域中发展的人们,我将撰写和讨论以下类别:
- PWN;
- 密码学(加密);
- 网络技术(网络);
- 反向(反向工程);
- 隐写术(Stegano);
- 搜索和利用Web漏洞。
除此之外,我将分享我在计算机取证,恶意软件和固件分析,对无线网络和局域网的攻击,进行笔测试和编写漏洞利用程序方面的经验。
为了使您可以查找有关新文章,软件和其他信息的信息,我
在Telegram中创建了一个
频道,并创建了一个
小组来讨论 ICD领域中的
所有问题 。 另外,我会亲自考虑您的个人要求,问题,建议和建议,
并会回答所有人 。
提供所有信息仅出于教育目的。 对于由于使用本文档而获得的知识和方法对某人造成的任何损害,本文档的作者不承担任何责任。
输入作业解决方案
我们单击带有签名输入的图标,并被告知需要通过SSH与密码guest连接。

连接后,我们会看到相应的横幅。

让我们找出服务器上有哪些文件,以及我们拥有的权限。
ls -l

这样,我们就可以读取程序的源代码,因为每个人都有读取的权利,并以所有者的权利(置位置位)执行输入程序。 让我们看看代码的结果。
源代码input.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> int main(int argc, char* argv[], char* envp[]){ printf("Welcome to pwnable.kr\n"); printf("Let's see if you know how to give input to program\n"); printf("Just give me correct inputs then you will get the flag :)\n"); // argv if(argc != 100) return 0; if(strcmp(argv['A'],"\x00")) return 0; if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0; printf("Stage 1 clear!\n"); // stdio char buf[4]; read(0, buf, 4); if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0; read(2, buf, 4); if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0; printf("Stage 2 clear!\n"); // env if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0; printf("Stage 3 clear!\n"); // file FILE* fp = fopen("\x0a", "r"); if(!fp) return 0; if( fread(buf, 4, 1, fp)!=1 ) return 0; if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0; fclose(fp); printf("Stage 4 clear!\n"); // network int sd, cd; struct sockaddr_in saddr, caddr; sd = socket(AF_INET, SOCK_STREAM, 0); if(sd == -1){ printf("socket error, tell admin\n"); return 0; } saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; saddr.sin_port = htons( atoi(argv['C']) ); if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){ printf("bind error, use another port\n"); return 1; } listen(sd, 1); int c = sizeof(struct sockaddr_in); cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c); if(cd < 0){ printf("accept error, tell admin\n"); return 0; } if( recv(cd, buf, 4, 0) != 4 ) return 0; if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0; printf("Stage 5 clear!\n"); // here's your flag system("/bin/cat flag"); return 0; }
从代码中可以看出,我们需要经历五个层次。 我们将轮流使用它们。

在第一级,检查程序参数的数量为100。在这种情况下,第65个元素应为字符串“ \ x00”,而第66个元素应为“ \ x20 \ x0a \ x0d”。 在目录/ tmp /中创建您自己的目录,然后在其中创建Python脚本。

为了解决第一层问题,我们将创建一个包含一百行“ A”的数组。 并将必要的参数分配给所需的值。 我们可以使用以下参数启动该过程,如下所示:
from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' ex = process(argv=a) ex.interactive()

我们通过了第一级。 看看第二个。

在此级别上,将读取两行,其中一行是标准输入stdin,另一行是stderr。 我们需要创建两个包含这些行的文件。

打开流到这些文件的流,并将一个文件流的描述符指定为描述符stdin,将另一个文件指定为描述符stderr。
from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' fin = open('/tmp/ex/in.txt', 'r') ferr = open('/tmp/ex/err.txt', 'r') ex = process(argv=a, stdin=fin, stderr=ferr) fin.close() ferr.close() ex.interactive()

我们继续进行第三级的决定。

getenv()函数返回环境变量的值,该值应等于参考值。 因此,您需要创建一个具有特定值的环境变量。
from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' fin = open('/tmp/ex/in.txt', 'r') ferr = open('/tmp/ex/err.txt', 'r') e={'\xde\xad\xbe\xef':'\xca\xfe\xba\xbe'} ex = process(argv=a, stdin=fin, stderr=ferr, env=e) fin.close() ferr.close() ex.interactive()

我们管理了环境变量,现在让我们从第四级开始。

根据代码,我们可以说该程序打开一个名为“ \ x0a”的文件,并从中读取4个字符,然后将它们与字节“ \ x00”进行比较。 由于字符本身和文件名均由不可打印的字符组成,因此我们使用python。


最后一级仍然存在。 让我们开始吧。

程序在第66个参数中指定的端口上打开套接字。 然后,它通过网络接收4个字节,并将其与参考字符串进行比较。 我们需要在程序中添加另一个参数-端口号,建立连接并发送必要的4个字节。
from pwn import * a = ['A']*100 a[0] = '/home/input2/input' a[ord('A')] = '\x00' a[ord('B')] = '\x20\x0a\x0d' a[ord('C')] = '1234' fin = open('/tmp/ex/in.txt', 'r') ferr = open('/tmp/ex/err.txt', 'r') e={'\xde\xad\xbe\xef':'\xca\xfe\xba\xbe'} ex = process(argv=a, stdin=fin, stderr=ferr, env=e) fin.close() ferr.close() ex.interactive()


仅此而已,请表达您的观点。

在以下文章中见!
我们在电报频道中:
Telegram中的
频道 。