MISC
stream
下载得到一个docx文件,打不开。
由于docx文件格式和zip文件相同,可以说docx文件实际就是一个zip文件,因此可以将docx文件后缀改为zip解压。
这里解压得到如上,其中right.rar明显不是docx文件该有的东西,解压它,
得到一个fake_flag,很明显,不是真的flag。
在其他文件里找了找,也没有发现flag。
这时回头看题目,stream,文件隐藏,直接上百度搜stream隐写。
百度搜索结果中有很多NTFS 交换数据流隐写,即ADS隐写,进一步了解一下。
大概意思是NTFS文件系统中每个文件都存在多个数据流,非主数据流无法直接看到,则可以将一个文件寄宿在另一个文件上,起到了隐藏文件的目的。
而检测ADS可以使用lads和Ntfs Streams Editor这两个工具。
去下载一个Ntfs Streams Editor,检测题目的文件夹,检测到一个数据流文件,导出后则可得到flag。
解密
下载得到一个rar文件,没有后缀名,先用UE打开看下16进制内容,发现是一个rar压缩包,改后缀为rar后解压。
得到一个流量文件,用wireshark打开,看下内容。
发现一个POST数据,应该是一个图片,右键追踪TCP流,发现一堆jsfuck编码,原来之前那些tcp包发的就是这个。
把jsfuck全部复制出来,拿去解码。
一般jsfuck直接在浏览器控制台就可以运行,不过这里似乎会卡住。
找在线工具解码:http://ctf.ssleye.com/jsfuck.html
得到base64内容:c2xqZGFsLWpza2RqLWphc2tkag=
用notepad++自带的base64解码,得到:sljdal-jskdj-jaskdj
提交GUETCTF{sljdal-jskdj-jaskdj},不对,提交GUET{sljdal-jskdj-jaskdj},正确。
图片里的宝藏
下载得到7z,看下16进制内容,发现是7z压缩包,改后缀后打开。
提示说照片所在地埋了宝藏,照片打不开,用UE看16进制,jpg文件头损坏,头两字节改为FF D8后保存,就可以打开了。
照片是学校后街,发现图片有Exif信息,可以看到GPS坐标
这时再去看看还有一个压缩包,treasure.zip,意思是宝藏,解压发现有密码,16进制查看一下,不是伪加密。
照片所在地埋了宝藏,那密码一定和照片所在地有关。
查看照片的GPS定位信息,直接用windows照片可以看到的位置是“灵川县“。
尝试“灵川县“解密,不对,可能定位不够精确。
拿着GPS信息去网上找GPS定位工具,
先将度分秒格式转换为度数格式 http://www.minigps.net/fc.html:
25.324947999847897
110.42223499986865
GPS坐标查询 http://www.toolzl.com/tools/getGpsArea.html
得到:桂林电子科技大学男生宿舍B区
输入解密,成功,得到一个dat文件,用文本编辑器打开,得到flag
简单流量分析
下载解压后得到pcapng文件,用wireshark打开。
由于题目提示是sql注入,则直接看http流量,可以看到sql注入语句,以及返回结果。
Sql注入结果一定在返回结果中,先随便选一个返回结果,追踪http流,得到返回的html源码,复制下来打开如下,并没有flag信息,再找其他几个包都是这样。
这时候注意到html页面标题:Less-8 Blind- Boolian- Single Quotes- String
去百度搜索一下,发现是一个sql盲注页面,当返回有You are in的时候就说明查询成功。没有的话则查询失败。
返回到wireshark,再过滤一下,看所有http返回结果,这里可以发现相应包长度为741时是有You are in的页面,长度为744时是没有You are in的页面。则当长度为741时,sql查询成功,744时查询失败。
再看每个响应包的请求URL
URL解码后是:
http://172.16.164.129/product/?id=1’ and ascii(substr((select password from users where username=‘admin’),1,1))>48–+
substr函数用来截取字符串中的一部分,第一个参数是目标字符串,第二个参数是开始位置,第三个参数是长度。
此处就是从select返回结果中取得第一位字符,判断它是否大于48。
而流量中48这个判断值一直递增,第一个包请求48,第二个包请求49,当查询成功时就一直递增。当查询失败时,即响应包长度为744时,则说明当前查询的目标字符不大于这个判断值,又由于之前的都是大于,那么当前查询字符就是这个判断值。
以此类推,得到每一位字符。
比如这里第一位的字符就是84,第二位字符是111
这样分析,可以得到密码的所有字符,
即flag为 GUETCTF{ToQZ7bN3Rc468fZfh5mP1Mv3YyEhI9mh}
签到
打开是unicode字符串
直接使用python就可以解码
Crypto
13
thrgpgs{jrypbzr_gb_thrgpgs}
很明显是rot13,用工具解码就得。
已知高位攻击
RSA,给了公钥e,给了p,n,密文c。
其中p是先右移64位,再左移64位的结果,因此p后面会有64位的0。
很明显,本题考的是Coppersmith定理攻击,即通过Coppersmith定理,可以在已知p的前面一部分和n时,得到完整的p。
Sage脚本如下:
n = 0xae34827f2e39a18ff62b9255273892413e5acdc7cd783e464b6f7ea387c08249eda01aa1cee09e303f305f0dc3020da10515b1e528c7732b693ed70ccdd216828a241e32e5eb74b34de23240fea2640e5384a924f71fbb25437e418995a1e11180e026729869ca3be292033246447a35d137a72abb623745aa7f6e12aa6f4171
p = 0xe423aee9231589ba18d32c0344881d5084c487d38551aa53ff51d98d02ab958a8d359b9a0743d7b2289a51bc3ebd0a3060b3ffdef08fceb20000000000000000
pbits = 512 #p总共有512位,即是128位十六进制
kbits = pbits-448 #已知前448位,即后64位未知
pbar = p & (2**pbits-2**kbits) #将p的前448bit保留,后面64bit置为0
PR.<x> = PolynomialRing(Zmod(n)) #建立模为n的多项式环,x是多项式环中的参数
f = x + pbar #定义求解的函数
x0 = f.small_roots(X=2**kbits, beta=0.4)[0] # find root < 2^kbits with factor >= n^0.4
p = x0 + pbar
print(hex(p))
得到结果:
0xe423aee9231589ba18d32c0344881d5084c487d38551aa53ff51d98d02ab958a8d359b9a0743d7b2289a51bc3ebd0a3060b3ffdef08fceb223974d4f046d9297
得到p后,由n/p得q,fn=(p-1)*(q-1),私钥d是e关于fn的乘法逆元,再通过私钥解密
Python脚本如下:
import gmpy2
import binascii
p = 0xe423aee9231589ba18d32c0344881d5084c487d38551aa53ff51d98d02ab958a8d359b9a0743d7b2289a51bc3ebd0a3060b3ffdef08fceb223974d4f046d9297
n = 0xae34827f2e39a18ff62b9255273892413e5acdc7cd783e464b6f7ea387c08249eda01aa1cee09e303f305f0dc3020da10515b1e528c7732b693ed70ccdd216828a241e32e5eb74b34de23240fea2640e5384a924f71fbb25437e418995a1e11180e026729869ca3be292033246447a35d137a72abb623745aa7f6e12aa6f4171
q = n//p
e = 65537
c = 0x1c2674b22bd09381d30326490d0349165e5d0690579329c654732fc7325f768c87422c449940460173d14960df812bcb6d5f0e3c19e976fefe4a25bb79e3cf05883728ae98fd55f224d19645488c7b8acb55f001086d9f2f1a497f36dcc69f24dcf3a3bd064299b23e07a39c4bd57b71e8478b667618a94d533b63a3958a9d5e
fn = (p-1)*(q-1)
d = gmpy2.invert(e, fn)
m = pow(c, d, n)
print(m)
b_m = binascii.a2b_hex(str(hex(m))[2:])
print(b_m)
得到结果:GUETCTF{92a3704e7d190a7becd2914d05f499f5}
simple_ecc
ECC椭圆曲线加密,已经给了椭圆曲线T,基点g,私钥k,密文c1,c2,则直接计算就好了。
明文点m = c1- k*c2,椭圆曲线的计算是一个问题,不过使用sage可以直接计算。
Sage脚本:
p = 520175694996894336551855254801109133456102894612986723725313
a = 7313143
b = 5531089
k = 96001
E = EllipticCurve(Zmod(p),[a,b])
g = E(383309911918352312476143108415504173014998255339380791655106,365034016619404037733940422396977249819924073858533741027266)
c1 = E(275328202076376982432998412218634590201409281320409664354613,306788491131773297978053428046155889246272231846539250098801)
c2 = E(1891926812756877524097501331809701805385200065380476227411,193437784701176304697433324351915651693965844595205136900226)
m = m = c1-k*c2
print(m)
得到m点
(241330684417215700597612930059577361280847040371713971023550 : 301180098343646945961237431316562958402801995883635720461075 : 1)
则flag为m点的x和y坐标之和:
GUETCTF{542510782760862646558850361376140319683649036255349691484625}
Pwn
nc
得到一个nc文件,使用ida打开看源码
逻辑很简单,就是输入一个字符串,存到buf中,然后将buf和“hello”比较,若相同则给shell。
python脚本:
from pwn import *
conn = remote('172.16.68.1','10001')
payload = 'hello'
conn.send(payload)
conn.interactive()
得到shell后,在目录下找flag
web
web签到
浏览器F12直接看html源码,得到flag
post送分题
使用hackbar post数据,password=thisissongfenti
得到falg
xxf
ip禁止访问,典型的X-Forwarded-For,在请求包中添加http头
X-Forwarded-For: 127.0.0.1
得到flag
sha1
php代码审计,需要get传参name和username,post传参password,
当username和password经过sha1后相同,且name为” guetctf!@#guetctf”的url加密时,就给flag。
这题考的是php的sha1漏洞,当两个数组sha1后相同。
因此get传参:name=guetctf!%40%23guetctf&username[]=1
Post传参:password[]=2
得到flag
file.jpg
url为http://172.16.68.1:58001/index.php?file=file.jpg,明显是任意文件读取漏洞。
直接让它读flag.php
http://172.16.68.1:58001/index.php?file=file.jpg
得到一个损坏的图片,右键查看源码,发现有一串base64。
解码后得到flag
ssti
ssti,服务器模板注入,有自动化工具tplmap。
右键查看源码,发现可以传参name
用tplmap跑一下,
发现可以注入,使用shell,cat flag
Reverse
猜
用ida看源码,可以看到是把a和b两个数组比较,要是相同就给flag。
而在缓存区里b数组就在a数组后面,a的长度是12,b的长度是8,这个exe又用的是不安全的scanf(),那输入a的时候输上20个相同的字母就能让两个相等了
直接连按20个a,出flag
re_flag2
这题使用字符串参数形式输入一个13字符长度的字符串,如果这13个字符和A字符数组的后13个字符相同,则出flag。
A字符数组用od可以直接看到
不过在比较之前,运行了__ff()函数,为A数组重新赋值
用ida动态调试可以看到重新赋值后的A数组,则输入shininghopper就可以得到flag
而且flag就是GUET{shininghopper}
re_flag1
ida看源码,本题输入字符串到数组b中,首先要满足F()条件
F()函数判断条件如下,a数组可以直接看到,即为”GUET”
则b数组应为IloveCTF,然后会执行f(),将b数组每位加3,赋给flag数组
则得到flag数组为LoryhFWI,flag为GUET{ LoryhFWI}