RE WP November 11, 2019

三叶草syc ctf

Words count 6.8k Reading time 6 mins. Read count 1000000

jiang’s fan

放入ida中,shift+f12查看字符串,就可以看到flag

secret

放入ida当中,查看主函数,看到base函数,函数中是对你输入的字符串进行base16加密,base16你可以理解为将字符串转换为16进制数字。main函数最后,将你输入的字符加密后和字符串比较,如果相同则输出正确。输入的字符为flag。可以用网上的base16进行解密,我当时做的时候用的爆破(主要是当时不知道base16。 解密代码先咕咕掉吧。等我会了在补上去

冰菓

放入detectit

.net文件,直接用dnspy来反编译
开始调试,设置中断在入口点,发现进入了bingo类里面,bingo类里面有个mainwindow,猜测是主函数可以进去看看。

里面有个encryptstr看上去像是加密类,先进去看看。

下面给了两个数组,然后进行了异或和相加的操作,直接写解密代码就可以了。
code = [119,77,103,79,21,115,133,97,115,87,22,115,103,89,88,93,22,89,119,81]

str = ''

for i in range(len(code)):

    str += chr((encode[i] - 13) ^ 0x39

print(str)

dll reverse

dll文件不想多讲,百度都有。对于这道题来说直接把dll文件放进去分析就可以了。
很容易找到加密函数

大概看一下,应该是base64再加上了一个异或的操作,结果也给了,直接逆向代码就可以得出要输入的代码了。还有一点要说的是base64中的对照表有一部分换了
下面是解密代码
import base64

list = bytes([69, 106, 67, 52, 86, 59, 79, 103, 71, 67, 25, 35, 67,117, 108, 103, 59, 101, 84, 70, 66, 55, 1, 80, 85, 96, 73, 36, 24, 74, 39, 31, 9, 29, 74, 0])

list_1 = bytes([34, 89, 50, 94, 56, 11, 66, 86, 38, 112, 77, 69, 19, 34, 45, 29, 91, 55, 112, 3, 18, 96, 124, 54, 7, 83, 3, 83, 79,120, 86, 38, 0, 0, 0, 0])

list_2 = []

flag = ''
for i in range(32):
    if (i % 2 == 0):
        list_2.append((list_1[i] - 3) ^ list[i])
    else:
        list_2.append((list_1[i] ^ list[i]))

for i in range(len(list_2)):
    flag += chr(list_2[i])

table1 = "ABCDEFGHIJKLMNOPQSVXZRWYTUeadbcfghijklmnopqrstuvwxyz0123456789+/"

table2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print(base64.b64decode(flag.translate(flag.maketrans(table1,table2))))

EASY VB

当知道这是一个vb后,我尝试用vb decompiler pro来解决这道题,但发现这道题放进去后还是汇编函数,没办法反汇编。只能继续用ida pro进去读汇编。
shift + f12查找字符串,进去查找看看能有什么收获。

这四句看起来比较关键,尤其是前面两句应该和flag有关,我们围绕这两句展开调查。

rtcMidCharVar,这是VB中⽤于截取字符串中字符的函数,⽽在下⼀个字符串赋值函数前,出现了jmp回到了rtcMidCharVar函数的上⽅,可知这是⼀个循环取字符的过程。

同理,在上方也可以发现有个rtcMidCharVar的函数和jmp的过程,猜测应该是对你输入的进行一一取值。

有一个将字符串转为ascii的函数,然后将eax和edx进行异或操作。得到的结果再和bKPObQ@goYBGRXjtVKVSn^@kFQh[V_]O进行比较。

这样就可以写出解密代码:
import numpy as np

a = 'bKPObQ@goYBGRXjtVKVSn^@kFQh[V_]O'

b = '12345a789012345678g012345a789012'

a1 = np.fromstring(a,dtype=np.uint8)
b1 = np.fromstring(b,dtype=np.uint8)
flag = ''
for i in xrange(len(a1)):
    flag += chr(a1[i] ^ b1[i])
print(flag)

re_py

re_py源代码:

print "This is a maze."
print "Python is so easy."
print 'Plz Input The Shortest Way:'
maze="###########S#@@@@@@##@#@####@##@#@@@@#@##@####@#@##@@@@@@#@#########@##E######@##@@@@@@@@###########"
way = raw_input()
len = len(way)
p=11
for i in way:
    if i=="&":
        p-=10
    if i=="$":
        p+=10
    if i=="6":
        p-=1
    if i=="3":
        p+=1
    if maze[p]=="#":
        print "Your way is wrong"
        exit(0)
        break
    if maze[p]=="@":
        continue
    if maze[p]=="E":
    print "You do it,your flag is Syc\{+Your Input+\}."
    exit(0)
print "May be something wrong."

从这里看来是一道迷宫题,十个字符为一行,&是向上,$是向下,6是向左,3是向右
‘# # # # # # # # # #
‘# S # @ @ @ @ @ @ #
’# @ # @ # # # # @ #
‘# @ # @ @ @ @ # @ #
’# @ # # # # @ # @ #
‘# @ @ @ @ @ @ # @ #
’# # # # # # # # @ #
‘# E # # # # # # @ #
’# @ @ @ @ @ @ @ @ #
‘# # # # # # # # # #
根据图写出flag即可

python1

把文件放到python在线反编译当中,直接可以看到源代码

源代码
import struct
import time
def b(a):
    return a & 0xFFFFFFFFFFFFFFFF
def c(str):
    return struct.unpack('<Q', str)[0]
def d(a):
    for i in range(64):
        a = a * 2
        if a > 0xFFFFFFFFFFFFFFFF:
            a = b(a)
            a = b(a ^ 0xB0004B7679FA26B3)
            continue
    return a
if __name__ == '__main__':
    cmp_data = [
        0x6E8DD76D3B876F95,
        0xE206DA09DAF4BED6,
        0x77559D346E134BF1,
        0x61CE39CAC5EAF891,
        0x656C3C155520E36F]
    input = input('plz input your flag:')
    if len(input) % 8 != 0:
        for i in range(8 - len(input) % 8):
            input += '\x00'        
    arr = []
    for i in range(len(input) // 8):
        value = d(c(input[i * 8:i * 8 + 8]))
        arr.append(value)

    for i in range(5):
        if arr[i] != cmp_data[i]:
            print('fail')
            time.sleep(5)
            exit()
            continue
    print ('success')
    time.sleep(5)
    exit()

做题前⾸先熟悉python的使⽤,如struct.pack和struct.unpack,python和pyc⽂件反编译⽅⾯不多
提,Life is short, you need python。
题⽬的难点主要在于对d函数的逆向,会有64次乘⼆,每次乘2后还会进⾏判断,如果⼤于
0xffffffffffffffff,会&0xffffffffffffffff再^ 0xB0004B7679FA26B3。
我们在些逆向脚本时候同样要进⾏64次的除以⼆,但是有个问题就是如何处理&0xffffffffffffffff再^
0xB0004B7679FA26B3呢?
其实能看出来的话这道题就很简单了,⼊⼿点就是奇偶。
每次乘⼆后这⼀次循环得到的是偶数,每次&0xffffffffffffffff再^ 0xB0004B7679FA26B3这⼀次循环得
到的都是奇数。我们写脚本进⾏64次循环除以⼆时候,先进⾏判断,如果是偶数就直接除以⼆,如果是
奇数就先^ 0xB0004B7679FA26B3,再+0xffffffffffffffff+1,再除以⼆即可。

脚本:
import struct
def decode(a):
    for i in range(64):
        if(a%2 == 0):
            a /= 2
        else:
            a ^=  0xB0004B7679FA26B3
            a = a + 0xffffffffffffffff + 1
            a /= 2
    return a
if __name__ == '__main__':
    cmp_data = [
        0x6E8DD76D3B876F95,
        0xE206DA09DAF4BED6,
        0x77559D346E134BF1,
        0x61CE39CAC5EAF891,
        0x656C3C155520E36F]
    flag = ''
    for i in range(5):
        flag += struct.pack(">Q",decode(cmp_data[i]))[::-1].strip()
        print(flag)
0%