Windows下如何进行进程注入

上学期学了有关 Windows 程序底层方面的知识,学习到病毒的基本工作原理。好记性不如烂笔头,学完之余还是写点东西出来吧~ 不过我也只是抛砖引玉,详细知识还是得自己多多钻研~

# 首先打开进程

首先使用 Win 系统的OpenProcess (opens new window)API 打开所要注入的进程。 使用参数是进程的 PID,可以使用任务管理器查看进程的 PID,打开成功之后返回程序的句柄。

# 开辟内存空间

Win 系统也提供了开辟内存空间的VirtualAllocEx (opens new window)API。 传入的参数包括进程句柄,开辟起始地址,开辟空间的大小,分配的数据类型,分配空间的权限。例如: pRemoteCode = (PBYTE) VirtualAllocEx(hProcess, 0, dwSizeOfCode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

# 写入恶意代码

使用 Win 系统的WriteProcessMemory (opens new window)API 向新开辟的内存空间写入数据。注意这里写入的是二进制数据,要考虑到各种 API 函数的寻址问题。

# 执行注入的代码

微软照样还是提供了相关的CreateRemoteThread (opens new window)API,我们注意最后一个参数是输出而不是输入。

# 获取执行的结果

如果要获取执行的结果,首先我们得等待线程的执行完成,使用WaitForSingleObject (opens new window)API.例: WaitForSingleObject(hThread, INFINITE); 然后再使用GetExitCodeThread (opens new window)API,得到返回的结果。

# 释放开辟的空间

干了坏事得不留痕迹才行,回收自己开辟的空间,使用VirtualFreeEx (opens new window)API.

# 关闭打开的进程

打开的进程也得关闭,使用CloseHandle (opens new window)API.

代码示例:

hProcess = OpenProcess(PROCESS_CREATE_THREAD
    | PROCESS_QUERY_INFORMATION
    | PROCESS_VM_OPERATION
    | PROCESS_VM_WRITE
    | PROCESS_VM_READ,
    FALSE, PID);

if (hProcess == NULL) {
    printf("failed.\n");
    return -1;
}
printf("ok.\n");

printf("[I]: Allocating remote memory with size of 0x%08x ......",
    dwSizeOfCode);

pCodeRemote = (PBYTE) VirtualAllocEx(hProcess,
        0,
        dwSizeOfCode,
        MEM_COMMIT,
        PAGE_EXECUTE_READWRITE);
if (pCodeRemote == NULL) {
    printf("failed.\n");
    CloseHandle(hProcess);
    return -1;
}
printf("ok at 0x%08x.\n", pCodeRemote);

do_link_before_inj(pCodeRemote);

printf("[I]: Writing code ......");
if (WriteProcessMemory(hProcess,
        pCodeRemote,
        pCode,
        dwSizeOfCode,
        &dwNumBytesXferred) == 0) {
    printf("failed.\n");
    VirtualFreeEx(hProcess, pCodeRemote,
            dwSizeOfCode, MEM_RELEASE);
    CloseHandle(hProcess);
    return -1;
};
printf("ok (%d bytes were written).\n", dwNumBytesXferred);

printf("[I]: Creating a remote thread ......");
hThread = CreateRemoteThread(hProcess, NULL, 0,
        (LPTHREAD_START_ROUTINE) pCodeRemote,
        pCodeRemote, 0 , &dwThreadId);
if (hThread == 0) {
    printf("failed.\n");
    if ( pCodeRemote != 0 )
        VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
    if ( hThread != 0 )
        CloseHandle(hThread);
    return -1;
}
printf("ok.\n");

printf("[I]: Waiting the remote thread ......");
WaitForSingleObject(hThread, INFINITE);
GetExitCodeThread(hThread, (PDWORD) &exitcode);
printf("exited with 0x%08X\n", exitcode);

VirtualFreeEx(hProcess, pCodeRemote, 0, MEM_RELEASE);
CloseHandle(hProcess);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

使用Aria2下载百度网盘和115的资源

虽然我已经开发了两款专门为 Aria2 用的下载插件,但是我发现还是有同学不会用 Aria2c 这么好的东西呢~ 于是还是写一篇文章来好好的介绍下吧~

# 安装 Aria2

Aria2 官网 (opens new window),通过官网应该能找到各个系统的下载包啦~ Linux 用户可以直接通过包管理器进行下载安装,OSX 我就没有经验了...Win 用户直接下载对应的 ZIP 包就可以了

# 配置 Aria2

Aria2 有两种下载模式,一种是命令行下载模式,一种是 RPC Server 模式.前者不建议使用,后者的使用方式很方便. RPC 模式就是启动之后什么也不做,等着通过 RPC 接口接受下载请求.下载完也不会退出,一直等待. 使用命令行加参数的方式配置 Aria2 非常不推荐,建议使用配置文件的方式,下面贴出我的配置文件.

#用户名
#rpc-user=user
#密码
#rpc-passwd=passwd
#上面的认证方式不建议使用,建议使用下面的token方式
#设置加密的密钥
#rpc-secret=token
#允许rpc
enable-rpc=true
#允许所有来源, web界面跨域权限需要
rpc-allow-origin-all=true
#允许外部访问,false的话只监听本地端口
rpc-listen-all=true
#RPC端口, 仅当默认端口被占用时修改
#rpc-listen-port=6800
#最大同时下载数(任务数), 路由建议值: 3
max-concurrent-downloads=5
#断点续传
continue=true
#同服务器连接数
max-connection-per-server=5
#最小文件分片大小, 下载线程数上限取决于能分出多少片, 对于小文件重要
min-split-size=10M
#单文件最大线程数, 路由建议值: 5
split=10
#下载速度限制
max-overall-download-limit=0
#单文件速度限制
max-download-limit=0
#上传速度限制
max-overall-upload-limit=0
#单文件速度限制
max-upload-limit=0
#断开速度过慢的连接
#lowest-speed-limit=0
#验证用,需要1.16.1之后的release版本
#referer=*
#文件保存路径, 默认为当前启动位置
dir=/home/acgotaku/Downloads
#文件缓存, 使用内置的文件缓存, 如果你不相信Linux内核文件缓存和磁盘内置缓存时使用, 需要1.16及以上版本
#disk-cache=0
#另一种Linux文件缓存方式, 使用前确保您使用的内核支持此选项, 需要1.15及以上版本(?)
#enable-mmap=true
#文件预分配, 能有效降低文件碎片, 提高磁盘性能. 缺点是预分配时间较长
#所需时间 none < falloc ? trunc << prealloc, falloc和trunc需要文件系统和内核支持
file-allocation=prealloc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

小白用户可以直接 copy 我的配置文件保存成 aria2.conf 进行使用.
然后在终端里面输入 aria2c --conf-path=<PATH> 注意 PATH 必须是绝对路径.
例如: D:\aria2\aria2.conf 可以使用 -D 参数使 Aria2 在后台运行,即使关闭终端也不会停止运行. Win 下可以把这个命令行保存成 bat 文件进行运行.注意路径不需要使用引号括起来.

接下来是如何管理 Aria2 的下载任务了,推荐使用 binux 菊苣的YAAW (opens new window),超级好用,下载打开即用.
懒得下载的话可以使用在线版 (opens new window),只需在设置里面修改下 RPC PATH 为 http://localhost:6800/jsonrpc

# 百度网盘插件

我开发的百度网盘插件已经发布到Web Store (opens new window)了,无法翻墙的同学可以去Github (opens new window)下载安装包进行安装.安装之后打开百度网盘 (opens new window)会发现在我的设备按钮的 右侧多了一个导出下载按钮,如果你使用的是默认配置的话那么选中要下载的文件之后点击ARIA2 RPC即可导出到 Aria2 进行下载,前提是你已经开启了 Aria2 的 RPC 模式.

# 115 网盘插件

115 网盘插件 (opens new window)刚刚发布功能还不完善,可能还有未知的 BUG,我后续会进行优化和开发的.安装之后打开115 网盘 (opens new window), 会发现多了一个 设置导出按钮 的按钮.点击这个按钮之后会提示设置成功的,然后把鼠标移动到要下载的文件上会出现 导出下载 的按钮, 点击即可导出到 Aria2 下载.

参考: Aria2 下载示例 (opens new window)

如果有不懂的可以在Github (opens new window)Google+ (opens new window)上联系我~

使用Postfix,Dovecot和Mysql配置邮件服务器

由于学习的需要,我要配置个本地邮件服务器.虽然找到了一篇很详细的资料,但是在配置过程中还是遇到了这样那样的问题. 写篇文章记下来自己的学习过程,毕竟好记性不如烂笔头嘛.

# 详细教程

Google 一下便找到了一个十分详细的教程,分享给大家:How To Configure a Mail Server Using Postfix, Dovecot, MySQL, and SpamAssasin (opens new window) 教程虽然很详细,但难免有不理解和差错的地方.下面就讲下我遇到的问题:

# Dovecot 证书问题

教程上设置的证书位置是:

ssl_cert = </etc/ssl/certs/dovecot.pem
ssl_key = </etc/ssl/private/dovecot.pem
1
2

但实际上是空的 需要手动 copy 过去,默认存储的位置是:

ssl_cert = /etc/dovecot/dovecot.pem
ssl_key = /etc/dovecot/private/dovecot.pem
1
2

# 查看日志发现读取配置出错

出错信息如下:

dovecot: lmtp(11504): Fatal: Error reading configuration: Invalid settings: postmaster_address setting not given
1

查到相关资料Invalid settings: postmaster_address setting not given (opens new window) 简单来说就是在/etc/dovecot/dovecot.conf文件内添加一行 postmaster_address=postmaster at DOMAIN 即可

# 重启 Dovecot

当我们执行 service dovecot restart 时,发现根本没有这个 service.
其实 dovecot 已经在运行了,我们只需执行 dovecot reload 即可

# 邮件无法发送

日志输出如下:

B0E4F26077E: to=<root@example.jp>, orig_to=<root>, relay=none, delay=6780, delays=6780/0/0.09/0, dsn=5.4.4, status=bounced (Host or domain name not found. Name service error for name=example.jp type=AAAA: Host not found)
1

这个问题是因为 Postfix 默认启用了 IPv6 并且优先级比 IPv4 要高,所以需要在配置文件 /etc/postfix/main.cf里面设置 inet_protocols = ipv4 这样就关闭 IPv6 了.即可解决问题.

大概就是遇到这么多问题了,最后祝愿大家圣诞节快乐~