分类 BaseCTF 下的文章

[Week1] Ez Xor

这里是加密后的东西,由于是局部变量,直接变成一坨了,我们把它弄出来就行,或者直接动态调试,从hex-view里面找,也是很方便的。
2024-09-22T12:16:13.png

from regadgets import *

# data
enc = qword2byte([0x1D0B2D2625050901, 0x673D491E20317A24, 0x34056E2E2508504D])
enc += b"\"@;%"
assert len(enc) == 28

# keystream
k = b'Xor'
keyStream = bytes([i ^ k[i % len(k)] for i in range(len(enc))])

# xor
print(bxor(enc, keyStream[::-1]))
# b'BaseCTF{X0R_I5_345Y_F0r_y0U}'

[Week1] You are good at IDA

2024-09-22T12:22:51.png
Y0u_4Re_
2024-09-22T12:23:41.png
900d_47_
2024-09-22T12:24:18.png
id4
BaseCTF{Y0u_4Re_900d_47_id4}

[Week1] BasePlus

2024-09-22T12:26:23.png
Encode 里面经过分析是一个Base64 encode
Secret是/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC
也就是一个换表Base64,不过base64里面偷偷给你异或了一个0xE,这个要注意

from regadgets import *
enc = b'lvfzBiZiOw7<lhF8dDOfEbmI]i@bdcZfEc^z>aD!'
k = 0xe
dec = decode_b64(bxor(enc, [k for _ in range(len(enc))]).decode(),
                  '/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC')

print(dec)
# b'BaseCTF{BA5e_DEcoD1N6_sEcr3t}\x00'

[Week1] UPX mini

UPX 解压
2024-09-22T12:31:39.png
2024-09-22T12:32:02.png
base64_encode,名字没有清理掉,而且进去是标准base64

from regadgets import *
enc = 'QmFzZUNURntIYXYzX0BfZzBvZF90MW0zISEhfQ=='
dec = decode_b64(enc)
print(dec)
# b'BaseCTF{Hav3_@_g0od_t1m3!!!}'

[Week1] ez_maze

2024-09-22T12:35:53.png
进去之后分析一下,把一些字符还原了,wasd,这几个分别是上左下右,看起来是没问题的
显然迷宫是用一个数组进行存储,pos % 15 == 14可以知道迷宫行宽15(因为pos从0开始), pos > 209可知道迷宫总共210个数,也就是15*14的迷宫
2024-09-22T12:38:29.png
然后如果是y就是终点,如果是$就是invalid(墙壁,不能走)。
我们提取出来,看一看

>>> a = "x$$$$$$$$$$$$$$&&&&&&$$$$$$$$$&$&$$&$$&&&&&$$&$&$$$&&$$$$&$$&$$$&&&$$$$$&$$&$$$&$&&$&$$$$$&$$$&$&$$&&&$$$&&&&&$&&&&$&$$$$$$$$$&&&&&&$$$$$$$$$&$$$$$$$$$$$&&&&$$&&&$$$$$$&&&&&&&$$$$$$$$$$$$$$&$$&$$$$$$$$$$$&$&$$$$$$$$$&&&&&&&&y"
>>>
>>> for i in range(0, len(a), 15):
...     print(a[i:i+15])
...
x$$$$$$$$$$$$$$
&&&&&&$$$$$$$$$
&$&$$&$$&&&&&$$
&$&$$$&&$$$$&$$
&$$$&&&$$$$$&$$
&$$$&$&&$&$$$$$
&$$$&$&$$&&&$$$
&&&&&$&&&&$&$$$
$$$$$$&&&&&&$$$
$$$$$$&$$$$$$$$
$$$&&&&$$&&&$$$
$$$&&&&&&&$$$$$
$$$$$$$$$&$$&$$
$$$$$$$$$&$&$$$
$$$$$$&&&&&&&&y
>>>

然后使用notepad++进行标记,手动走一下
2024-09-22T12:40:40.png
sssssssddddwwwddsssssssdddsssddddd
然后程序提示,flag是BaseCTF{md5(path)}
所以

from hashlib import md5
print(f"BaseCTF{{{md5(b'sssssssddddwwwddsssssssdddsssddddd').hexdigest()}}}")
# BaseCTF{131b7d6e60e8a34cb01801ae8de07efe}

[Week2] Ezpy

┌──(Administrator💀NullCafe)-[ base]-[~/Desktop/BaseCTF2024/Reverse/[Week2] Ezpy]                               0ms  
└─#  python .\pyinstxtractor.py .\Ezpy.exe
[+] Processing .\Ezpy.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.9
[+] Length of package: 5835441 bytes
[+] Found 59 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: Ezpy.pyc
[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python 3.9 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction
[+] Found 81 files in PYZ archive
[+] Successfully extracted pyinstaller archive: .\Ezpy.exe

注意到

[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python 3.9 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction

这个其实是因为你python版本不对导致的,我们可以修改pyinstxtractor.py让它不跳过一些pyc的提取,也可以换python版本,我们这里为了反编译更完美,选择更换python版本。
我是用conda进行多版本python环境共存。
2024-09-22T12:49:30.png
可以注意到,是python3.9.7,所以我们安装
conda create -n py397 python=3.9.7
然后切换
conda activate py397

┌──(Administrator💀NullCafe)-[ py397]-[~/Desktop/BaseCTF2024/Reverse/[Week2] Ezpy]                             37ms  
└─#  python .\pyinstxtractor.py .\Ezpy.exe
[+] Processing .\Ezpy.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.9
[+] Length of package: 5835441 bytes
[+] Found 59 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: Ezpy.pyc
[+] Found 81 files in PYZ archive
[+] Successfully extracted pyinstaller archive: .\Ezpy.exe

You can now use a python decompiler on the pyc files within the extracted directory

这下就完美了,我们使用pycdc来反编译
2024-09-22T12:51:53.png

# Source Generated with Decompyle++
# File: Ezpy.pyc (Python 3.9)

import Key
import sys

def init_Sbox(seed):
    k_b = (lambda .0 = None: [ ord(seed[i % len(seed)]) for i in .0 ])(range(256))
    s = list(range(256))
    j = 0
    for i in range(256):
        j = (j + s[i] + k_b[i]) % 256
        s[i] = s[j]
        s[j] = s[i]
    return s


def KeyStream(text, Sbox):
    s = Sbox.copy()
    (i, j) = (0, 0)
    k = [
        0] * len(text)
    for r in range(len(text)):
        i = (i + 1) % 256
        j = (j + s[i]) % 256
        s[i] = s[j]
        s[j] = s[i]
        t = (s[i] + s[j]) % 256
        k[r] = s[t] ^ Key.keykey[r % len(Key.keykey)]
    return k


def Encrypt(text, seed):
    Sbox = init_Sbox(seed)
    key = KeyStream(text, Sbox)
    enc = (lambda .0 = None: [ text[i] ^ key[i] for i in .0 ])(range(len(text)))
    return bytes(enc)

enc = b'\xe6\xaeC~F\xf2\xe3\xbb\xac\x9a-\x02U\x85p\xeb\x19\xd1\xe4\xc93sG\xb0\xeb1\xb5\x05\x05\xc3\xd7\x00\x18+D\xbc\x0cO\x9em\xf1\xbd'
flag = input('Please input Your flag:')
flag = (lambda .0: [ ord(i) for i in .0 ])(flag)
flag = Encrypt(flag, Key.key)
if flag != enc:
    print("It's not flag!")
    continue
print('You are right!')
sys.exit(1)
continue

可以注意到,init_Sbox是RC4的init,KeyStream是在获取RC4的密钥流。
不过我们还需要知道Key.key,keykey这俩是什么
我们在子目录下找到Key.pyc,进行反编译

└─# C:\Users\Administrator\Desktop\Reverse\Python\pycdc\pycdc.exe .\Key.pyc
# Source Generated with Decompyle++
# File: Key.pyc (Python 3.9)

key = 'yOU_f1nd_m3'
keykey = [
    66,
    97,
    115,
    101]

exp

from regadgets import *
key = 'yOU_f1nd_m3'
keykey = [
    66,
    97,
    115,
    101]
enc = b'\xe6\xaeC~F\xf2\xe3\xbb\xac\x9a-\x02U\x85p\xeb\x19\xd1\xe4\xc93sG\xb0\xeb1\xb5\x05\x05\xc3\xd7\x00\x18+D\xbc\x0cO\x9em\xf1\xbd'

s = rc4_init(key.encode())
keystream = list(rc4_keystream(s, len(enc)))
keystream = bxor_cycle(keystream, keykey)
print(bxor(keystream, enc))
# b'BaseCTF{Y0u_kn0W_d3C0Mp1l4710N_PY_4ND_rC4}'

不过这里我推荐使用黑手办法
我们使用hypno进行注入

>>> from hypno import *
>>> code = """
... Sbox = init_Sbox(Key.key)
... keys = KeyStream("a"*len(enc), Sbox)
... print(keys)
... """
>>>
>>> inject_py(9024, code)

2024-09-22T13:14:58.png
然后就能得到KeyStream,注入原理是,attach到Python39.dll然后

void run_python_code() {
    if (PYTHON_CODE[0]) {
        int saved_errno = errno;
        PyGILState_STATE gstate = PyGILState_Ensure();
        PyRun_SimpleString(PYTHON_CODE);
        PyGILState_Release(gstate);
        errno = saved_errno;
    }
}

通过调用PyRun_SimpleString就可以执行代码注入。
然后我们继续
exp

from regadgets import *
enc = b'\xe6\xaeC~F\xf2\xe3\xbb\xac\x9a-\x02U\x85p\xeb\x19\xd1\xe4\xc93sG\xb0\xeb1\xb5\x05\x05\xc3\xd7\x00\x18+D\xbc\x0cO\x9em\xf1\xbd'
box = [164, 207, 48, 27, 5, 166, 165, 192, 245, 170, 88, 93, 62, 235, 64, 188, 70, 181, 215, 138, 3, 62, 55, 129, 135, 5, 130, 52, 53, 141, 136, 80, 65, 116, 112, 242, 72, 16, 236, 46, 197, 192]
print(bxor(enc, box))
# b'BaseCTF{Y0u_kn0W_d3C0Mp1l4710N_PY_4ND_rC4}'

注入应该是解决这种类型题目的最优雅的办法。

[Week2] RivestCipher

题目名字明示是rc4,但是我们还是看一看
2024-09-22T13:45:17.png
main_main,是go编译的产物
由于ida对go的字符串支持不太行(因为go的字符串和rust的一样,都是连着的而不是x00截断)
我们直接看流程图
2024-09-22T13:46:35.png
可以看到这里,mov ecx, 7代表后面的字符串长度7
所以字符串是BaseCTF
2024-09-22T13:48:44.png
下面直接进rc4加密函数了,所以大概率是key
2024-09-22T13:51:09.png
很清晰,所以我就直接写wp了(enc是后面的hex字符串 可以直接找到)

from regadgets import *
enc = bytes.fromhex('0ebb0c573dd548f3d2b2525f02895cd5275b6f6e5776538982ea41246dae8517')
s = rc4_init(b'BaseCTF')
print(rc4_crypt(s, enc))
# b'BaseCTF{go1@ng_!S_RuNNin9_RC4}\r\n'

[Week2] UPX

x64dbg 零帧起手,找到个

$rg7_dhd~Alidg+zeyhz`vnz_d,7sy0=

这时候我就已经猜到是魔改base64了,但是还是继续看看
2024-09-22T14:07:37.png
果然找到base64表(& 0x3f)
2024-09-22T14:08:47.png

A,.1fgvw#`/2ehux$~"3dity%_;4cjsz^+{5bkrA&=}6alqB*-[70mpC()]89noX
from regadgets import *
print(decode_b64('$rg7_dhd~Alidg+zeyhz`vnz_d,7sy0=', 'A,.1fgvw#`/2ehux$~"3dity%_;4cjsz^+{5bkrA&=}6alqB*-[70mpC()]89noX'))
# b'BaseCTF{UPX_1s_$o_e@sy}'

好吧,已经解出来了wmmm

[Week2] lk

z3基础题,直接搬运官方wp了(bushi

from z3 import *

a = [Int('a[%d]' % i) for i in range(21)]
s = Solver()
s.add(948 * a[20]
     + 887 * a[19]
     + 410 * a[18]
     + 978 * a[17]
     + 417 * a[16]
     + 908 * a[15]
     + 965 * a[14]
     + 987 * a[13]
     + 141 * a[12]
     + 257 * a[11]
     + 323 * a[10]
     + 931 * a[9]
     + 773 * a[8]
     + 851 * a[7]
     + 758 * a[6]
     + 891 * a[5]
     + 575 * a[4]
     + 616 * a[3]
     + 860 * a[2]
     + 283 * a[1] == 913686)
s.add( 938 * a[20]
     + 490 * a[19]
     + 920 * a[18]
     + 50 * a[17]
     + 568 * a[16]
     + 68 * a[15]
     + 35 * a[14]
     + 708 * a[13]
     + 938 * a[12]
     + 718 * a[11]
     + 589 * a[10]
     + 954 * a[9]
     + 974 * a[8]
     + 62 * a[7]
     + 580 * a[6]
     + 80 * a[5]
     + 111 * a[4]
     + 151 * a[3]
     + 421 * a[2]
     + 148 * a[1] == 630335)
s.add( 908 * a[20]
     + 590 * a[19]
     + 668 * a[18]
     + 222 * a[17]
     + 489 * a[16]
     + 335 * a[15]
     + 778 * a[14]
     + 622 * a[13]
     + 95 * a[12]
     + 920 * a[11]
     + 932 * a[10]
     + 892 * a[9]
     + 409 * a[8]
     + 392 * a[7]
     + 11 * a[6]
     + 113 * a[5]
     + 948 * a[4]
     + 674 * a[3]
     + 506 * a[2]
     + 182 * a[1] == 707525)
s.add( 479 * a[20]
     + 859 * a[19]
     + 410 * a[18]
     + 399 * a[17]
     + 891 * a[16]
     + 266 * a[15]
     + 773 * a[14]
     + 624 * a[13]
     + 34 * a[12]
     + 479 * a[11]
     + 465 * a[10]
     + 728 * a[9]
     + 447 * a[8]
     + 427 * a[7]
     + 890 * a[6]
     + 570 * a[5]
     + 716 * a[4]
     + 180 * a[3]
     + 571 * a[2]
     + 707 * a[1] == 724203)
s.add( 556 * a[20]
     + 798 * a[19]
     + 380 * a[18]
     + 716 * a[17]
     + 71 * a[16]
     + 901 * a[15]
     + 949 * a[14]
     + 304 * a[13]
     + 142 * a[12]
     + 679 * a[11]
     + 459 * a[10]
     + 814 * a[9]
     + 282 * a[8]
     + 49 * a[7]
     + 873 * a[6]
     + 169 * a[5]
     + 437 * a[4]
     + 199 * a[3]
     + 771 * a[2]
     + 807 * a[1] == 688899)
s.add( 465 * a[20]
     + 898 * a[19]
     + 979 * a[18]
     + 198 * a[17]
     + 156 * a[16]
     + 831 * a[15]
     + 856 * a[14]
     + 322 * a[13]
     + 25 * a[12]
     + 35 * a[11]
     + 369 * a[10]
     + 917 * a[9]
     + 522 * a[8]
     + 654 * a[7]
     + 235 * a[6]
     + 385 * a[5]
     + 469 * a[4]
     + 231 * a[3]
     + 496 * a[2]
     + 83 * a[1] == 604784)
s.add( 305 * a[20]
     + 928 * a[19]
     + 260 * a[18]
     + 793 * a[17]
     + 787 * a[16]
     + 708 * a[15]
     + 758 * a[14]
     + 236 * a[13]
     + 688 * a[12]
     + 747 * a[11]
     + 711 * a[10]
     + 195 * a[9]
     + 50 * a[8]
     + 648 * a[7]
     + 787 * a[6]
     + 376 * a[5]
     + 220 * a[4]
     + 33 * a[3]
     + 194 * a[2]
     + 585 * a[1] == 665485)
s.add( 767 * a[20]
     + 573 * a[19]
     + 22 * a[18]
     + 909 * a[17]
     + 598 * a[16]
     + 588 * a[15]
     + 136 * a[14]
     + 848 * a[12]
     + 964 * a[11]
     + 311 * a[10]
     + 701 * a[9]
     + 653 * a[8]
     + 541 * a[7]
     + 443 * a[6]
     + 7 * a[5]
     + 976 * a[4]
     + 803 * a[3]
     + 273 * a[2]
     + 859 * a[1] == 727664)
s.add( 776 * a[20]
     + 59 * a[19]
     + 507 * a[18]
     + 164 * a[17]
     + 397 * a[16]
     + 744 * a[15]
     + 377 * a[14]
     + 768 * a[13]
     + 456 * a[12]
     + 799 * a[11]
     + 9 * a[10]
     + 215 * a[9]
     + 365 * a[8]
     + 181 * a[7]
     + 634 * a[6]
     + 818 * a[5]
     + 81 * a[4]
     + 236 * a[3]
     + 883 * a[2]
     + 95 * a[1] == 572015)
s.add( 873 * a[20]
     + 234 * a[19]
     + 381 * a[18]
     + 423 * a[17]
     + 960 * a[16]
     + 689 * a[15]
     + 617 * a[14]
     + 240 * a[13]
     + 933 * a[12]
     + 300 * a[11]
     + 998 * a[10]
     + 773 * a[9]
     + 484 * a[8]
     + 905 * a[7]
     + 806 * a[6]
     + 792 * a[5]
     + 606 * a[4]
     + 942 * a[3]
     + 422 * a[2]
     + 789 * a[1] == 875498)
s.add( 766 * a[20]
     + 7 * a[19]
     + 283 * a[18]
     + 900 * a[17]
     + 211 * a[16]
     + 305 * a[15]
     + 343 * a[14]
     + 696 * a[13]
     + 590 * a[12]
     + 736 * a[11]
     + 817 * a[10]
     + 603 * a[9]
     + 414 * a[8]
     + 828 * a[7]
     + 114 * a[6]
     + 845 * a[5]
     + 175 * a[4]
     + 212 * a[3]
     + 898 * a[2]
     + 988 * a[1] == 714759)
s.add( 220 * a[20]
     + 30 * a[19]
     + 788 * a[18]
     + 106 * a[17]
     + 574 * a[16]
     + 501 * a[15]
     + 366 * a[14]
     + 952 * a[13]
     + 121 * a[12]
     + 996 * a[11]
     + 735 * a[10]
     + 689 * a[9]
     + 998 * a[8]
     + 689 * a[7]
     + 729 * a[6]
     + 886 * a[5]
     + 860 * a[4]
     + 70 * a[3]
     + 466 * a[2]
     + 961 * a[1] == 778853)
s.add( 313 * a[20]
     + 748 * a[19]
     + 522 * a[18]
     + 864 * a[17]
     + 156 * a[16]
     + 362 * a[15]
     + 283 * a[14]
     + 49 * a[13]
     + 316 * a[12]
     + 79 * a[11]
     + 136 * a[10]
     + 299 * a[9]
     + 271 * a[8]
     + 604 * a[7]
     + 907 * a[6]
     + 540 * a[5]
     + 141 * a[4]
     + 620 * a[3]
     + 701 * a[2]
     + 866 * a[1] == 584591)
s.add( 922 * a[20]
     + 399 * a[19]
     + 425 * a[18]
     + 26 * a[17]
     + 159 * a[16]
     + 224 * a[15]
     + 438 * a[14]
     + 770 * a[13]
     + 144 * a[12]
     + 406 * a[11]
     + 110 * a[10]
     + 991 * a[9]
     + 749 * a[8]
     + 701 * a[7]
     + 646 * a[6]
     + 147 * a[5]
     + 979 * a[4]
     + 674 * a[3]
     + 999 * a[2]
     + 913 * a[1] == 717586)
s.add( 13 * a[20]
     + 537 * a[19]
     + 225 * a[18]
     + 421 * a[17]
     + 153 * a[16]
     + 484 * a[15]
     + 654 * a[14]
     + 743 * a[13]
     + 779 * a[12]
     + 74 * a[11]
     + 325 * a[10]
     + 439 * a[9]
     + 797 * a[8]
     + 41 * a[7]
     + 784 * a[6]
     + 269 * a[5]
     + 454 * a[4]
     + 725 * a[2]
     + 164 * a[1] == 537823)
s.add( 591 * a[20]
     + 210 * a[19]
     + 874 * a[18]
     + 204 * a[17]
     + 485 * a[16]
     + 42 * a[15]
     + 433 * a[14]
     + 176 * a[13]
     + 436 * a[12]
     + 634 * a[11]
     + 82 * a[10]
     + 978 * a[9]
     + 818 * a[8]
     + 683 * a[7]
     + 404 * a[6]
     + 562 * a[5]
     + 41 * a[4]
     + 789 * a[3]
     + 200 * a[2]
     + 220 * a[1] == 587367)
s.add( 584 * a[20]
     + 597 * a[19]
     + 928 * a[18]
     + 532 * a[17]
     + 902 * a[16]
     + 858 * a[15]
     + 820 * a[14]
     + 240 * a[13]
     + 124 * a[12]
     + 899 * a[11]
     + 848 * a[10]
     + 822 * a[9]
     + 409 * a[8]
     + 491 * a[7]
     + 587 * a[6]
     + 715 * a[5]
     + 410 * a[4]
     + 268 * a[3]
     + 721 * a[2]
     + 915 * a[1] == 842245)
s.add( 421 * a[20]
     + 302 * a[19]
     + 327 * a[18]
     + 180 * a[17]
     + a[16] * 512
     + 160 * a[15]
     + 623 * a[14]
     + 28 * a[13]
     + 411 * a[12]
     + 53 * a[11]
     + 633 * a[10]
     + 560 * a[9]
     + 623 * a[8]
     + 477 * a[7]
     + 901 * a[6]
     + 287 * a[5]
     + 149 * a[4]
     + 726 * a[3]
     + 934 * a[2]
     + 875 * a[1] == 610801)
s.add( 838 * a[20]
     + 434 * a[19]
     + 792 * a[18]
     + 649 * a[17]
     + 462 * a[16]
     + 170 * a[15]
     + 980 * a[14]
     + 15 * a[13]
     + 295 * a[12]
     + 495 * a[11]
     + 666 * a[10]
     + 934 * a[9]
     + 17 * a[8]
     + 69 * a[7]
     + 367 * a[6]
     + 780 * a[5]
     + 291 * a[4]
     + 834 * a[3]
     + 587 * a[2]
     + 133 * a[1] == 653127)
s.add( 41 * a[20]
     + 422 * a[19]
     + 420 * a[18]
     + 224 * a[17]
     + 475 * a[16]
     + 854 * a[15]
     + 233 * a[14]
     + 179 * a[13]
     + 620 * a[12]
     + 69 * a[11]
     + 42 * a[10]
     + 684 * a[9]
     + 300 * a[8]
     + 745 * a[7]
     + 894 * a[6]
     + 554 * a[5]
     + 495 * a[4]
     + 66 * a[3]
     + 316 * a[2]
     + 391 * a[1] == 533470 )
if s.check() == sat:
    ans = s.model()
    for i in range(1,21):
        print(chr(ans[a[i]].as_long()), end="")
    #print(s.model())
        
 #CDBBDCAAABBDBCCBCCAC

[Week2] 最简单的编码

2024-09-22T14:16:32.png
动调一下,就能拿到变换后的table

CDABGHEFKLIJOPMNSTQRWXUVabYZefcdijghmnklqropuvstyzwx23016745+/89

然后这是魔改的base64
2024-09-22T14:20:01.png
我是用cpp写的,网上搬的,改了几个偏移,不过年久已丢,此处用官方的

from regadgets import *
table = "CDABGHEFKLIJOPMNSTQRWXUVabYZefcdijghmnklqropuvstyzwx23016745+/89"
enc = "TqK1YUSaQryEMHaLMnWhYU+Fe0WPenqhRXahfkV6WE2fa3iRW197Za62eEaD"
index = []
number = [1,2,3,4]
for i in range(len(enc)):
    tmp = table.index(enc[i]) - number[i % 4]
    if tmp >= 0:
        index.append(tmp)
    else:
        index.append(tmp + 64)
print(index)
for i in range(0,len(index),4):
    sum = index[i] << 18 | index[i + 1] << 12 | index[i + 2] << 6 | index[i + 3]
    for j in range(3):
        print(chr((sum >> ((2 - j) * 8)) & 0xff), end="")
# [16, 38, 5, 51, 25, 20, 13, 20, 17, 39, 45, 2, 13, 3, 21, 5, 13, 35, 17, 31, 25, 20, 57, 3, 27, 52, 17, 9, 27, 35, 37, 31, 18, 19, 21, 31, 28, 36, 20, 52, 19, 4, 49, 25, 23, 51, 29, 15, 19, 53, 60, 53, 26, 22, 53, 48, 27, 4, 21, 61]
# BaseCTF{B45E64_eNCoDIn9_I5_rE4LLY_7OO_5implE}

[Week2] 喝杯下午茶

找key, 找enc,找delta就可以了。

from regadgets import *
k = [0] * 4
k[0] = 287454020
k[1] = 1432778632
k[2] = -1716864052
k[3] = -571539695

v = [0] * 10
v[0] = -1800277529
v[1] = 567661394
v[2] = 1380415805
v[3] = 67968151
v[4] = -210862220
v[5] = -1672218865
v[6] = 1793773528
v[7] = 1872692980
v[8] = -352477650
v[9] = 850810359
v = pack_dword(v)
r = b''
for i in v:
    a, b = tea_decrypt(i, k, 1131796)
    r += l2b(a)[::-1] + l2b(b)[::-1]

print(r)
# b'BaseCTF{h3r3_4_cuP_0f_734_f0R_y0U!!!!!!}'   

[Week2] neuro爱数学

没做,搬一下官方的:
考点是简单的代码审计加代码逻辑仿写
2024-09-22T14:34:48.png
点开IDA发现需要输入9个数
2024-09-22T14:34:55.png
接下来简单分析逻辑
第一段进行了一个简单的运算操作
即计算: $$x_1*i^8+x_2*i^7+x_3*i^6+x_4*i^5+x_5*i^4+x_6*i^3+x_7*i^2+x_8*i^1+x_9*i^0$$
第二段计算(i-44)(i-58)(i-17)(i-6)(i-5)(i+4)(i+9)(i+37)
很多人看不懂,为什么不考虑一下本地模拟呢 or 动调
2024-09-22T14:35:07.png
接下来事情显而易见 将第二段展开,得到的式子和第一段对比即可得到x1-x9
这里用python脚本完成,有能力的同学可以手算。

from sympy import symbols, expand
x = symbols('x')
polynomial = (x - 44) * (x - 58) * (x - 5) * (x + 37) * (x - 17) * (x + 9) * (x - 6) * (x + 4)
expanded_polynomial = expand(polynomial)
standard_form = expanded_polynomial.as_poly()
coefficients = standard_form.all_coeffs()
print(coefficients[::-1])

2024-09-22T14:35:29.png
输入进程序即可得到flag
2024-09-22T14:35:35.png

[Week3] UPX PRO

Linux 的加了upx,而且魔改了一些东西,我们放gdb里面
2024-09-22T14:37:33.png
发现有反调试,我们考虑ptrace反调试
2024-09-22T14:38:01.png
catch syscall ptrace然后s一下(过syscall),再运行
2024-09-22T14:38:24.png
这样我们就能绕过ptrace反调试,然后
2024-09-22T14:38:57.png
就可以绕过反调试,其实在反调试的地方已经过了,我们直接
2024-09-22T14:40:27.png
得到coredump,然后拖入ida
2024-09-22T14:42:41.png
显然我们已经得到了解压后的
随便翻一下,找到个base58,表是
ABCDEFGHJKLMNPQRSTUVWXYZ123456789abcdefghijkmnopqrstuvwxyz
2024-09-22T14:43:37.png
2024-09-22T14:48:32.png

__int64 __fastcall sub_7FFFF7FF9518(__int64 a1, unsigned __int64 a2, __int64 a3, __int64 a4)
{
  _BYTE v5[139]; // [rsp+20h] [rbp-A0h] BYREF
  char v6; // [rsp+ABh] [rbp-15h]
  int v7; // [rsp+ACh] [rbp-14h]
  unsigned __int64 i; // [rsp+B0h] [rbp-10h]
  int v9; // [rsp+B8h] [rbp-8h]
  int v10; // [rsp+BCh] [rbp-4h]

  sub_7FFFF7FF9362(v5, a3, a4);
  v10 = 0;
  v9 = 0;
  v7 = 0;
  for ( i = 0LL; i < a2; ++i )
  {
    v10 = (v10 + 1) % 128;
    v9 = (v9 + (unsigned __int8)v5[v10]) % 128;
    v6 = v5[v10];
    v5[v10] = v5[v9];
    v5[v9] = v6;
    v7 = (v5[v10] + v5[v9]) & 0x7F;
    *(_BYTE *)(a1 + i) ^= v5[v7];
  }
  return 0LL;
}

还有个魔改rc4
稍微还原一下

__int64 __fastcall rc4_init(char *s_box, char *a2, unsigned __int64 len)
{
  char key_box[128]; // [rsp+18h] [rbp-90h] BYREF
  char v5; // [rsp+9Fh] [rbp-9h]
  int v6; // [rsp+A0h] [rbp-8h]
  int i; // [rsp+A4h] [rbp-4h]

  v6 = 0;
  memset(key_box, 0, sizeof(key_box));
  v5 = 0;
  for ( i = 0; i <= 127; ++i )
  {
    s_box[i] = i;
    key_box[i] = key_box[i % len];
  }
  for ( i = 0; i <= 127; ++i )
  {
    v6 = (key_box[i] + v6 + (unsigned __int8)s_box[i]) % 128;
    v5 = s_box[i];                              // swap
    s_box[i] = s_box[v6];
    s_box[v6] = v5;
  }
  return 0LL;
}
__int64 __fastcall rc4_crypt(char *a1, unsigned __int64 a2, char *key, unsigned __int64 key_len)
{
  unsigned __int8 s[128]; // [rsp+20h] [rbp-A0h] BYREF
  unsigned __int8 tmp; // [rsp+ABh] [rbp-15h]
  int v7; // [rsp+ACh] [rbp-14h]
  unsigned __int64 iter; // [rsp+B0h] [rbp-10h]
  int j; // [rsp+B8h] [rbp-8h]
  int i; // [rsp+BCh] [rbp-4h]

  rc4_init((char *)s, key, key_len);
  i = 0;
  j = 0;
  v7 = 0;
  for ( iter = 0LL; iter < a2; ++iter )
  {
    i = (i + 1) % 128;
    j = (j + s[i]) % 128;
    tmp = s[i];                                 // swap
    s[i] = s[j];
    s[j] = tmp;
    v7 = (s[i] + s[j]) & 0x7F;
    a1[iter] ^= s[v7];
  }
  return 0LL;
}

我们发现key根本没用上,rc4的key_box全是0,是空的,可能是出题的时候的一个漏洞。
思路已经很明显了,就是把rc4的sbox空间改成128,就行了。
EXP

from regadgets import *
enc = [0x364A65466C271216, 0x2447243568082139, 0x29323C0F5A1A7D60, 0x4D647C3C45531544, 0x74152339130F7024]
enc = qword2byte(enc)

print(rc4_crypt(rc4_init(b'', 128), enc, 128))
# b'BaseCTF{Rc4_1$_@_G0od_3nCrypt!on_MethOd}'

[Week3] Dont-debug-me

ScyllaHide

[Week4] BaseRE

TLS Callback 和Main里面有花指令
Change base64 table to : HElRNYGmBOMWnbDvUCgcpu1QdPqJIS+iTry39KXse4jLh/x26Ff5Z7Vokt8wzAa0
b64decode('UXY5PpbpCshkP1CrPcU7DlZZSGd5WcO6qRB/D1dfbyZFP3ToncKKd5rXDGCA', my_table);
BaseCTF{8edae458-4tf3-2ph2-9f26-1f8719ec8f8d}