听说hxp 2019要和C3CTF合办了,就看看2018hxp的题目
资源
We try to archive our CTFs as well as possible.
For all our past CTFs we offer you virtual machines which allow you to play the CTFs whenever you want!
See this post for more information.
下载 https://ctf.link/hxp_ctf_2018.ova,然后virtualbox运行,访问http://127.0.0.1:82 就看到题目平台了
平台Troll
这个类型可以翻译成:菜鸟
cat flag
nc 127.0.0.1 13370
我一开始认为这是一道bash jail的题目,因为提供了shell环境嘛,都忽略了flag文件的权限是可读。思维陷入定式了。最后用cat -A flag
把前面ansi编码的部分显示出来了。
Web
题目数量较少
time for h4x0rpsch0rr?
源代码有一段可疑的部分:
<a href="admin.php">Admin Access</a>
<script src="mqtt.min.js"></script>
<script>
var client = mqtt.connect('ws://' + location.hostname + ':60805')
client.subscribe('hxp.io/temperature/Munich')
client.on('message', function (topic, payload) {
var temp = parseFloat(payload)
var result = 'NO'
/* secret formular, please no steal*/
if (-273.15 <= temp && temp < Infinity) {
result = 'YES'
}
document.getElementById('beer').innerText = result
})
</script>
网络层有101状态码的请求,是个MQTT服务
MQTT访问http://127.0.0.1:8001/admin.php
下载MQTT-SPY工具https://github.com/eclipse/paho.mqtt-spy
操作方法是https://blog.csdn.net/sinat_28771747/article/details/99057034
注意配置Server URI
要选择websockets
在这篇关于MQTT的博客中讲到,可以利用#
通配
MQTT利用通配符获取订阅所有Topic
MQTT 主题(Topic) 支持’+’, ‘#’的通配符,’+’通配一个层级,’#’通配多个层级(必须在末尾)。
也就是说 如果我们有两个Topic分别为CMD/123/456
CMD/789/666
那么我们可以订阅CMD
来获取其CMD下的全部消息
然而返回的只有一堆13.37。。。
翻了下官方文档https://github.com/mqtt/mqtt.github.io/wiki/SYS-Topics
这篇文章https://www.jianshu.com/p/0b0788c799fc (原文地址为https://morphuslabs.com/hacking-the-iot-with-mqtt-8edaf0d07b9b)提到通过SYS Topics订阅所有主题可能会泄露信息,并给出了调试方法:使用$SYS/#
出现了一个webcam(网络摄像头),订阅该话题,发现一张图片,导出之
export获得账号
webcam尝试登录吧!(OTP[one time password]具有时效性,手速要快)
User | Password | OTP |
---|---|---|
iot_fag | I<3SecurID | 图上6位数字的信息 |
即可获得flag。
wor,这就是道IoT的题目,为啥放在web里了
参考:
https://ctftime.org/writeup/12533
Crypto
daring
考点:RSA padding+小公钥
源码对flag部分右侧进行了"\0"的padding,这里扩展一下
左边的 padding 不用管
>>>a="a\x00\x00\x00"
>>>b'\x00\x00a\x00\x00\x00'
>>>bytes_to_long(a)
1627389952L
>>>bytes_to_long(b)
>>>1627389952L
右边的padding想象成bit-shift,每一位都是*256(末尾添加16进制的00),因为
我们有了 通过逆元把 x 除下去,再配合 e=3的低加密指数攻击,即可
exp:
#!/usr/bin/env python3
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto.Util import Counter
from Crypto.PublicKey import RSA
from Crypto.Util.number import *
import gmpy2
n = RSA.importKey(open("pubkey.txt",'r').read()).n
c=int.from_bytes(open("rsa.enc","rb").read(), 'big')
n = 131439155143175043265322066353951646221438306790938190998522265782952062884373948320963990364387806423377384374007937468177671276323489634193305141101111897782540226757793029784559400156340831524038843044706502635279773784856499312207447550053071060656400930280068219967242645499076062394053507154455753332851
e = 3
c = 101289393626607127554187202298707999567698627700625294597228051901600521870872558312539860683380184719944341606093685609696440268292221391526643817365119976661650070266220933422021322751640444938685602977931512982716940247950481943615907166261417571982743004278833526863190964577524016799705809805830751851372
flag_size = len(open("aes.enc", 'rb').read())
new_ct = c * pow(inverse(256, n) ** (128-flag_size), e, n)
new_ct %= n
for i in range(10000):
potential_pt, is_cube = gmpy2.iroot(new_ct + (n * i), e)
if is_cube:
print(i, long_to_bytes(potential_pt))
break
# (23, 'hxp{DARINGPADS_1s_4n_4n4gr4m_0f_RSAPADDING}')
给AES的目的是把flag的长度算出来。但其实可以通过循环遍历flag_size(128)最终肯定能找到对应的那组
对应的exp:
#!/usr/bin/env python3
from Crypto.Cipher import AES
from Crypto.Hash import SHA256
from Crypto.Util import Counter
from Crypto.PublicKey import RSA
from Crypto.Util.number import *
import gmpy2
n = RSA.importKey(open("pubkey.txt",'r').read()).n
c=int.from_bytes(open("rsa.enc","rb").read(), 'big')
n = 131439155143175043265322066353951646221438306790938190998522265782952062884373948320963990364387806423377384374007937468177671276323489634193305141101111897782540226757793029784559400156340831524038843044706502635279773784856499312207447550053071060656400930280068219967242645499076062394053507154455753332851
e = 3
c = 101289393626607127554187202298707999567698627700625294597228051901600521870872558312539860683380184719944341606093685609696440268292221391526643817365119976661650070266220933422021322751640444938685602977931512982716940247950481943615907166261417571982743004278833526863190964577524016799705809805830751851372
for k in range(128):
new_ct = c * pow(inverse(256, n) ** (128-k), e, n)
new_ct %= n
for i in range(10000):
potential_pt, is_cube = gmpy2.iroot(new_ct + (n * i), e)
if is_cube:
print(i, long_to_bytes(potential_pt))
break
网友评论