<font face="微软雅黑">

第十二届全国大学生信息安全竞赛创新实践能力赛——writeup

misc

saleae

Description

题目是一个.logicdata文件

Analyze

用saleae logic打开后发现波纹为八个为一格的文件,用同伙的方法八个一格地记录下来

01100110
01101100
01100001
01100111
01111011
00110001
00110010
00110000
00110111
00110001
00110011
00111001
00110111
00101101
00110001
00111001
01100100
00110001
00101101
00110100
00111000
01100101
00110110
00101101
01100010
01100101
00111000
01100011
00101101
00110111
00111000
00110100
01100010
00111000
00111001
01100001
00111001
00110101
01100101
00110000
00110111
01111101

容易看出是二进制转化

Solve

通过上面的记录编写了个脚本

flag = ''
with open('1.txt') as p:
    data = p.readlines()
    for i in range(len(data)):
        data[i] = data[i][:8]
        data[i] = int(data[i],2)
        flag += chr(data[i])
    print(flag)

Flag

flag{12071397-19d1-48e6-be8c-784b89a95e07}

deep learning

做到最后因为imagenet维护没有找到‘503’匹配的wings,然后一直自己尝试也出不来就写写大概思路吧

Description

题目有一个image和一个py文件,py文件为

from PIL import Image
import sys
import os
import numpy as np
import random
import time
import base64
import inception
import string
import hashlib
SALT_LEN = 10
HEX_LEN = 4


std_image_name="/home/ctf/images/image.jpg"
input_image_name=''
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'

def base_str():
    return "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"   

def random_string(length):
    string = [random.choice(base_str()) for i in range(length)]
    return ("".join(string))

def tofile(data):
    try:
        data=base64.b64decode(data)
    except:
        return ""
    filename="/backup/"+str(time.time())+".jpg"
    fd=open(filename,"wb")
    fd.write(data)
    fd.close()
    filename="/home/ctf/images/"+str(time.time())+".jpg"
    fd=open(filename,"wb")
    fd.write(data)
    fd.close()
    return filename

def check():
    global input_image_name
    try:
        input_image=Image.open(input_image_name)
        std_image=Image.open(std_image_name)
    except:
        print("[-]give me a real image!!")
        sys.stdout.flush()
        return False
    input_image_np=np.array(input_image)
    std_image_np=np.array(std_image)
    input_x=len(input_image_np)
    input_y=len(input_image_np[0])
    input_z=len(input_image_np[0][0])
    std_x=len(std_image_np)
    std_y=len(std_image_np[0])
    std_z=len(std_image_np[0][0])
    if std_x!=input_x or std_y!=input_y or std_z!=input_z:
        return False
    diff=0
    for i in range(input_x):
        for j in range(input_y):
            for k in range(input_z):
                if input_image_np[i][j][k]>std_image_np[i][j][k]:
                    diff+=input_image_np[i][j][k]-std_image_np[i][j][k]
                else:
                    diff+=std_image_np[i][j][k]-input_image_np[i][j][k]
    diff=diff/(input_x*input_y*input_z) 
    if diff>0.8:
        return False
    return True

def classify(image_path):
    model = inception.Inception()
    pred = model.classify(image_path=image_path)
    return (pred.argmax(),model.name_lookup.cls_to_name(pred.argmax(),only_first_name=True))
def getflag():
    fd=open("/home/ctf/flag")
    flag=fd.readline()
    fd.close()
    return flag
def main():
    salt=random_string(SALT_LEN)
    tmpvalue=random_string(20)+salt
    md5=hashlib.md5()
    md5.update(tmpvalue.encode("utf-8"))
    submd5=md5.hexdigest()[:4]
    print ("[*]Proof of work:")
    print ("\tMD5(key+\"%s\")[:4]==%s"%(salt,submd5))
    print ("[+]Give me the key:")
    sys.stdout.flush()
    value=sys.stdin.readline()[:-1]
    value=value+salt
    md5=hashlib.md5()
    md5.update(value.encode("utf-8"))
    md5value=md5.hexdigest()
    if(md5value[:HEX_LEN]!=submd5):
        print ("[-]Access Failed")
        return;
    print ("[*]I am the world smartest CV system!")
    print ("[+]Give me a wing to fly?")
    sys.stdout.flush()
    global input_image_name
    image=sys.stdin.readline()[:-1]
    if(len(image)>200000):
        print("[-]input too long!")
        return;
    input_image_name=tofile(image)
    if input_image_name=="":
        print ("[-]base64 please!")
        sys.stdout.flush()
        return
    if not check():
        print ("[-]You cannot fool me!")
        sys.stdout.flush()
        return
    (input_image_class,input_image_classname)=classify(input_image_name)
    (std_image_class,std_image_classname)=classify(std_image_name)
    if input_image_class!=std_image_class and input_image_class==503:
        print("[*]Wow I get the wing")
        print("[*]Give you the flag")

        print(getflag())
        sys.stdout.flush()
        return
    else:
        print("[*]Give me the wing!")
        sys.stdout.flush()
        return
    
main()

Analyze

第一步是一个加盐的md5碰撞,这里用一个暴力破解脚本破解

Solve

import multiprocessing
import hashlib
import random
import string
import sys
CHARS = string.letters + string.digits
def cmp_md5(salt ,substr, start=0, size=20):
    global CHARS
    while True:
        str_len = len(substr)
        rnds = ''.join(random.choice(CHARS) for _ in range(size)) + ""
        md5 = hashlib.md5(rnds + salt)
        if md5.hexdigest()[start: start+str_len] == substr:
            return rnds
            
print(cmp_md5("GwoEzpgvOM", "daca"))

Analyze

第二步是上传图片的base64加密信息,这里分成了两部,一个是图像base64加密,另一个是上传。

Solve

#base64加密图片
#!/usr/bin/env python
# coding=utf-8
import sys
import base64
import time
from PIL import Image
def tofile(data):
    try:
        data=base64.b64decode(data)
    except:
        return ""
    filename=str(time.time())+".jpg"
    fd=open(filename,"wb")
    fd.write(data)
    fd.close()
    filename=str(time.time())+".jpg"
    fd=open(filename,"wb")
    fd.write(data)
    fd.close()
    return filename

image = base64.b64encode(open("12.jpg","rb").read())
data = image
miss = 4-len(data)%4
if miss:
    data += b'='*miss
a = open("12.txt",'w')
a.write(data)
#上传图片信息
# coding=utf-8
from pwn import *
from md5 import cmp_md5

import time
debug=0
if debug:
    p=process('./ez_shellcode')
    context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
    context.log_level = 'debug'

    gdb.attach(p,'b *0x08048663\nc')
else:
    p=remote('39.97.228.196',20001)
    context.log_level = 'debug'
    #p.sendline("zmbcen")
    
p.recvuntil("+")
salt=p.recvuntil(")")[1:-2]
print "salt="+str(salt)
p.recvuntil("==")
substr=p.recv(4)
print "substr="+str(substr)

answer=cmp_md5(salt,substr)
p.recvuntil("Give me the key:")
p.sendline(answer)

with open("./12.txt","r") as f:
    data=f.read()
p.recv()
p.recvuntil("?")
p.sendline(data)

p.interactive()

Analyze

最后一步基本看了看后得知这个深度学习是两图像素点之差再求和除以总像素点个数得小于0.8,然后用了PS来修改使原图片像素值和修改后图像达到要求,因为找不到对应图像库'503'号元素是什么,就一直在试wings。。。然后一直得不到正确结果。