2020 GKCTF

 

Misc

Pokémon

有点脑洞题,flag就在103国道那

 

flag{PokEmon_14_CutE}

 

Crypto

小学生的密码学

e(x)=11x+6(mod26)

密文:welcylk

仿射密码,a=11,b=6

2020 GKCTF_第1张图片

再base64就行

 

flag{c29yY2VyeQ==}

 

babycrypto

2019强网杯challenge 2原题,RSA解密,给了p高128位

import gmpy2
from Crypto.Util.number import long_to_bytes

n = 0xb119849bc4523e49c6c038a509a74cda628d4ca0e4d0f28e677d57f3c3c7d0d876ef07d7581fe05a060546fedd7d061d3bc70d679b6c5dd9bc66c5bdad8f2ef898b1e785496c4989daf716a1c89d5c174da494eee7061bcb6d52cafa337fc2a7bba42c918bbd3104dff62ecc9d3704a455a6ce282de0d8129e26c840734ffd302bec5f0a66e0e6d00b5c50fa57c546cff9d7e6a978db77997082b4cb927df9847dfffef55138cb946c62c9f09b968033745b5b6868338c64819a8e92a827265f9abd409359a9471d8c3a2631b80e5b462ba42336717700998ff38536c2436e24ac19228cd2d7a909ead1a8494ff6c3a7151e888e115b68cc6a7a8c6cf8a6c005
e = 65537
p = 0xe4e4b390c1d201dae2c00a4669c0865cc5767bc444f5d310f3cfc75872d96feb89e556972c99ae20753e3314240a52df5dccd076a47c6b5d11b531b92d901b2b512aeb0b263bbfd624fe3d52e5e238beeb581ebe012b2f176a4ffd1e0d2aa8c4d3a2656573b727d4d3136513a931428b92826225b6d0e735440b613a8336ffa3
enc = 1422566584480199878714663051468143513667934216213366733442059106529451931078271460363335887054199577950679102659270179475911101747625120544429262334214483688332111552004535828182425152965223599160129610990036911146029170033592055768983427904835395850414634659565092191460875900237711597421272312032796440948509724492027247376113218678183443222364531669985128032971256792532015051829041230203814090194611041172775368357197854451201260927117792277559690205342515437625417792867692280849139537687763919269337822899746924269847694138899165820004160319118749298031065800530869562704671435709578921901495688124042302500361
q = n // p
phin = (p - 1) * (q - 1)
d = gmpy2.invert(e, phin)
flag = pow(enc, d, n)
flag = long_to_bytes(flag)
print(flag)

 

flag{3d0914a1-1e97-4822-a745-c7e20c5179b9}

 

Reverse

Check_1n

首先让输入开机密码,定位到密码错误处

2020 GKCTF_第2张图片

2020 GKCTF_第3张图片

上面aHelloworld就是开机密码,HelloWorld。开机之后打开打砖块,打开之后,上面不用做,后面弹出flag

2020 GKCTF_第4张图片

 

flag{f5dfd0f5-0343-4642-8f28-9adbb74c4ede}

 

Chelly's identity

代码分析

2020 GKCTF_第5张图片

程序可以分为四个部分

输入复制

通过动态调试可以知道,代码第61~68行在进行赋值操作,将输入的值复制到m中

2020 GKCTF_第6张图片

 

长度检测

sub_BD11BD函数,检测输入字符串长度是否为16

2020 GKCTF_第7张图片

 

加密函数

sub_BD1721函数为加密函数

2020 GKCTF_第8张图片

进入sub_BD16E0函数

2020 GKCTF_第9张图片

这个函数可以静态分析,也可以动态调试出结果,这里是产生2~128的质数,存储在v10中

2020 GKCTF_第10张图片

 

下面的while循环,使用v9遍历整个输入字符串,for循环累加小于v9的质数到v7,最后将v9与v7异或。这就是整个的加密过程。

 

判定函数

打开sub_491852函数,这里也是动态调试,了解到就是将加密后的m与已知字符数组比较

 

2020 GKCTF_第11张图片

 

脚本

# -*- coding:utf-8 -*-

def create_num():
    num = []
    for i in range(2, 129):
        flag = False
        for j in range(2, i):
            if i % j == 0:
                flag = True
                break
        if not flag:
            num.append(i)
    return num


def add_num(n, num):
    sum = 0
    for i in num:
        if i >= n:
            break
        sum += i
    return sum


a = [438, 1176, 1086, 377, 377, 1600, 924, 377, 1610, 924, 637, 639, 376, 566, 836, 830]
num = create_num()
flag = ''
for x in a:
    for n in range(256):
        sum = add_num(n, num)
        if n ^ sum == x:
            flag += chr(n)
            break
print ('flag{' + flag + '}')

 

get flag!

flag{Ch11y_1s_EG0IST}

 

BabyDriver

2020 GKCTF_第12张图片

这道题实际就是迷宫问题,但是他的键码对应方向是难点。对应代码在

2020 GKCTF_第13张图片

找出了四个判断方向的键值:23,37,36,38,根据if条件下对v5进行加减16,加减1,判断出分别代表上下左右

这实际就是当初学汇编时的键盘扫描码:https://www.plantation-productions.com/Webster/www.artofasm.com/DOS/ch20/CH20-1.html

分别对应 I,K,J,L

接着就手动解迷宫:LKKKLLKLKKKLLLKKKLLLLLL

md5加密后:403950a6f64f7fc4b655dea696997851

 

flag{403950a6f64f7fc4b655dea696997851}

 

EzMachine

这是一道伪虚拟机题目,比起网鼎杯那道就难了...

VM分析

动态调试,找到主要的代码段

2020 GKCTF_第14张图片

再到IDA中找到对应的代码处

2020 GKCTF_第15张图片

这里加了混淆,我们首先需要去混淆:401594h处change bytes,改变首位为nop(90),再将下面全部代码转换为data,最后强制分析成代码,得到

2020 GKCTF_第16张图片

off_4448F4中存放着opcode对应操作的函数

2020 GKCTF_第17张图片

转换得到伪代码:(代码来自:https://apeng.fun/2020/05/24/2020GKCTF/#more)

code = [0x01, 0x03, 0x03, 0x05, 0x00, 0x00, 0x11, 0x00, 0x00, 0x01, 0x01, 0x11, 0x0C, 0x00, 0x01, 0x0D, 0x0A, 0x00, 0x01, 0x03, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, 0x00, 0x11, 0x0C, 0x00, 0x02, 0x0D, 0x2B, 0x00, 0x14, 0x00, 0x02, 0x01, 0x01, 0x61, 0x0C, 0x00, 0x01, 0x10, 0x1A, 0x00, 0x01, 0x01, 0x7A, 0x0C, 0x00, 0x01, 0x0F, 0x1A, 0x00, 0x01, 0x01, 0x47, 0x0A, 0x00, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x01, 0x0B, 0x24, 0x00, 0x01, 0x01, 0x41, 0x0C, 0x00, 0x01, 0x10, 0x24, 0x00, 0x01, 0x01, 0x5A, 0x0C, 0x00, 0x01, 0x0F, 0x24, 0x00, 0x01, 0x01, 0x4B, 0x0A, 0x00, 0x01, 0x01, 0x01, 0x01, 0x07, 0x00, 0x01, 0x01, 0x01, 0x10, 0x09, 0x00, 0x01, 0x03, 0x01, 0x00, 0x03, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x02, 0x01, 0x0B, 0x0B, 0x00, 0x02, 0x07, 0x00, 0x02, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x02, 0x05, 0x00, 0x02, 0x01, 0x00, 0x02, 0x0C, 0x00, 0x02, 0x01, 0x00, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x0D, 0x00, 0x02, 0x05, 0x00, 0x02, 0x0F, 0x00, 0x02, 0x00, 0x00, 0x02, 0x09, 0x00, 0x02, 0x05, 0x00, 0x02, 0x0F, 0x00, 0x02, 0x03, 0x00, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x05, 0x00, 0x02, 0x03, 0x00, 0x02, 0x03, 0x00, 0x02, 0x01, 0x00, 0x02, 0x07, 0x00, 0x02, 0x07, 0x00, 0x02, 0x0B, 0x00, 0x02, 0x02, 0x00, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00, 0x02, 0x07, 0x00, 0x02, 0x02, 0x00, 0x02, 0x0C, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x00, 0x01, 0x02, 0x01, 0x13, 0x01, 0x02, 0x04, 0x00, 0x00, 0x0C, 0x00, 0x01, 0x0E, 0x5B, 0x00, 0x01, 0x01, 0x22, 0x0C, 0x02, 0x01, 0x0D, 0x59, 0x00, 0x01, 0x01, 0x01, 0x06, 0x02, 0x01, 0x0B, 0x4E, 0x00, 0x01, 0x03, 0x00, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x03, 0x01, 0x05, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00]
ip = 0
sp = 0
bp = 0
stack = [0 for i in range(256)]
R = [0 for i in range(8)]

while ip < len(code):
    op = code[ip]
    if op == 0:
        ip+=1
    elif op == 1:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[oprnd1] = oprnd2
        print("%3d: "%(ip-3),"mov R%d, %d"%(oprnd1, oprnd2))
    elif op == 2:
        oprnd1 = code[ip+1]
        sp+=1
        ip+=3
        stack[sp] = oprnd1
        print("%3d: "%(ip-3),"push %d"%oprnd1)
    elif op == 3:
        oprnd1 = code[ip+1]
        sp+=1
        ip+=3
        stack[sp] = R[oprnd1]
        print("%3d: "%(ip-3),"push R%d"%oprnd1)
    elif op == 4:
        oprnd1 = code[ip+1]
        
        ip+=3
        R[oprnd1] = stack[sp]
        sp-=1
        print("%3d: "%(ip-3),"pop R%d"%oprnd1)
    elif op == 5:
        
        ip+=3
        print("%3d: "%(ip-3),"puts something")
    elif op == 6:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[oprnd1] += R[oprnd2]
        print("%3d: "%(ip-3),"add R%d, R%d"%(oprnd1, oprnd2))
    elif op == 7:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[oprnd1] -= R[oprnd2]
        print("%3d: "%(ip-3),"sum R%d, R%d"%(oprnd1, oprnd2))
    elif op == 8:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[oprnd1] *= R[oprnd2]
        print("%3d: "%(ip-3),"mul R%d, R%d"%(oprnd1, oprnd2))
    elif op == 9:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[0] = R[oprnd1] // R[oprnd2]
        R[1] = R[oprnd1] % R[oprnd2]
        print("%3d: "%(ip-3),"div R%d, R%d"%(oprnd1, oprnd2))
    elif op == 10:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[oprnd1] ^= R[oprnd2]
        print("%3d: "%(ip-3),"xor R%d, R%d"%(oprnd1, oprnd2))
    elif op == 11:
        ip = 3*code[ip+1]-3
        print("%3d: "%(ip-3),"jmp %d"%oprnd1)
    elif op == 12:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        ip+=3
        R[3] = R[oprnd1] - R[oprnd2]
        print("%3d: "%(ip-3),"cmp R%d, R%d"%(oprnd1, oprnd2), R[oprnd1], R[oprnd2])
    elif op == 13:
        oprnd1 = code[ip+1]
        print("%3d: "%ip,"jz %d"%(3*oprnd1-3))
        if R[3]:
            ip += 3
        else:
            ip = 3*code[ip+1]-3
        
    elif op == 14:
        
        oprnd1 = code[ip+1]
        print("%3d: "%ip,"jnz %d"%(3*oprnd1-3))
        if R[3]:
            ip = 3*code[ip+1]-3
        else:
            ip += 3
    elif op == 15:
        
        oprnd1 = code[ip+1]
        print("%3d: "%ip,"jg %d"%(3*oprnd1-3))
        if R[3]<=0:
            ip += 3
        else:
            ip = 3*code[ip+1]-3
    elif op == 16:
        
        oprnd1 = code[ip+1]
        print("%3d: "%ip,"jb %d"%(3*oprnd1-3))
        if R[3]>=0:
            ip += 3
        else:
            ip = 3*code[ip+1]-3
    elif op == 17:
        # input
        buf = [0 for i in range(17)]
        buf = list(b"?lag{1234567890a}")
        R[0] = len(buf)
        ip+=3
        print("%3d: "%(ip-3),"input")
    elif op == 18:
        length = code[ip+2] - code[ip+1]
        buf[code[ip+1]:code[ip+2]] = [0 for i in range(length)]
        ip=3
        print("%3d: "%(ip-3),"memset")
    elif op == 19:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        R[oprnd1] = stack[bp+R[oprnd2]]
        ip+=3
        print("%3d: "%(ip-3),"mov R%d, [bp+R%d]"%(oprnd1, oprnd2))
    elif op == 20:
        oprnd1 = code[ip+1]
        oprnd2 = code[ip+2]
        R[oprnd1] = buf[R[oprnd2]]
        ip+=3
        print("%3d: "%(ip-3),"mov R%d, buf[R%d]"%(oprnd1, oprnd2))
    elif op == 0xff:
        print("%3d: "%(ip-3),"death")
        exit(0)

 

脚本

model = [2, 2, 12, 2, 7, 2, 1, 2, 11, 7, 7, 1, 3, 3, 5, 2, 0, 3, 15, 5, 9, 0, 15, 5, 13, 0, 0, 1, 12, 1, 5, 0, 13, 7]
enc = [(model[2 * i + 1] * 16 + model[2 * i]) for i in range(17)]
flag = [0]*17
print(enc)
for i in range(len(enc)):
    tmp1 = (enc[i] - 1) ^ 71
    tmp2 = (enc[i] + 1) ^ 75
    if ord('a') <= tmp1 <= ord('z'):
        flag.append(tmp1)
    elif ord('A') <= tmp2 <= ord('Z'):
        flag.append(tmp2)
    else:
        flag.append(enc[i])
print(''.join([chr(x) for x in flag]))

 

get flag!

flag{Such_A_EZVM}

你可能感兴趣的:(2020 GKCTF)