RicknMorty
整个看下来逻辑就是,随机出现两个数,找到他们的最小公因数,然后+3求阶乘。(在30s内算完所有即可)
(当时没有用脚本,直接计算器走一波就出来了)
附上脚本:
from pwn import *
from LibcSearcher import *
from struct import pack
context.os='linux'
context.arch='amd64'
context.log_level='debug'
sd=lambda x:io.send(x)
sl=lambda x:io.sendline(x)
ru=lambda x:io.recvuntil(x)
rl=lambda :io.recvline()
ra=lambda :io.recv()
rn=lambda x:io.recv(x)
sla=lambda x,y:io.sendlineafter(x,y)
#求最小公因数
def fun1(a,b):
r=0
i=1
while True:
if a<i or b<i:
break
if not(a%i) and not(b%i):
r=i
i=i+1
return r
#递归求阶乘
def fun2(a):
if a!=0:
return a*fun2(a-1)
else:
return 1
io=remote('chall.csivit.com',30827)
while True:
t=ru(' ')[:-1]
if t=='fun()':
break
a=int(t)
b=int(rl()[:-1])
sl(str(fun2(fun1(a,b)+3)))
io.interactive()
Blaise
这题也蛮简单的,可能是因为太后放出了?做的人好少...(此处简述一下逻辑,当时做的时候忘记截图了,也懒得复现了QAQ)
逻辑就是随机给出一个数k,然后输入C(n,m)排列组合(m为上标,n为下标),n为给出的随机数k,m为从0~k(前后其实是对称的),输入正确直接get flag...
从这里开始就都是赛后复现啦:
Vietnam
打开找到主函数:
函数逻辑很简单,就是让str = "HELLO" 就可以了,然后就发现没有办法去直接改变str的值,所以问题的关键还是在于JUMPOUT函数上。
由于地址这样看起来不清晰,所以跑一个python脚本处理一下
这里可以看一下PatchDword函数的意思
然后看回ida的dword_402020,现在就变成这样啦:
看一下对应地址的偏移量,+33为输入的字符,反过来也可以理解为程序将输入的字符减去33然后当作下标索引,跳转到对应地址。
算一下偏移:
地址 偏移量 输入字符(偏移量+33)
0x4012a9 0 !(33)
0x40120c 3 $(36)
0x40122d 10 +(43)
0x4012e6 11 ,(44)
0x40126b 12 -(45)
0x4012fb 13 .(46)
0x40131e 58 [(91)
0x401369 60 ](93)
看一下汇编,就会发现每个地址的作用:
重要的就两个地址:0x4012e6和0x4012fb——第一个是将输入字符放在sa中,第二个是依次把sa的字符放在str中。
结合上面我们就可以知道,输入“,”是将字符放在sa中,输入“ . "就可以把它存在str中,因为要让”HELLO“赋值给str,所以我们需要输入六个字符(包括"\n"):
在终端输入:
, . , . , . , . , . , . (键盘输入)
HELLO (键盘输入)
HELLO (系统输出)csictf{xxxxxxxxxxxxxxxxxxxxxxxxx}(系统输出)
get flag!