[SHCTF 2023 校外赛道] reverse

news2024/11/18 19:43:49

week1

ez_asm

想不到第1题是个汇编,咱也不知道拿啥能弄成c,不过这题也不难,直接能看懂,关键部分。

取出异或0x1e然后保存,再取出-0xa再保存。

.text:0000000000401566                               loc_401566:                             ; CODE XREF: main+65↓j
.text:0000000000401566 8B 45 FC                      mov     eax, [rbp+var_4]         计数器 指针
.text:0000000000401569 48 98                         cdqe
.text:000000000040156B 48 8D 15 AE 1A 00 00          lea     rdx, flag                       
.text:0000000000401572 0F B6 04 10                   movzx   eax, byte ptr [rax+rdx]  取出1个
.text:0000000000401576 83 F0 1E                      xor     eax, 1Eh                 xor 1e
.text:0000000000401579 89 C1                         mov     ecx, eax
.text:000000000040157B 8B 45 FC                      mov     eax, [rbp+var_4]
.text:000000000040157E 48 98                         cdqe
.text:0000000000401580 48 8D 15 99 1A 00 00          lea     rdx, flag                      
.text:0000000000401587 88 0C 10                      mov     [rax+rdx], cl            保存
.text:000000000040158A 8B 45 FC                      mov     eax, [rbp+var_4]
.text:000000000040158D 48 98                         cdqe
.text:000000000040158F 48 8D 15 8A 1A 00 00          lea     rdx, flag                      
.text:0000000000401596 0F B6 04 10                   movzx   eax, byte ptr [rax+rdx]  再取出1个
.text:000000000040159A 83 E8 0A                      sub     eax, 0Ah                 -a 
.text:000000000040159D 89 C1                         mov     ecx, eax
.text:000000000040159F 8B 45 FC                      mov     eax, [rbp+var_4]
.text:00000000004015A2 48 98                         cdqe
.text:00000000004015A4 48 8D 15 75 1A 00 00          lea     rdx, flag                      
.text:00000000004015AB 88 0C 10                      mov     [rax+rdx], cl            保存
.text:00000000004015AE FF 45 FC                      inc     [rbp+var_4]
>>> a = 'nhuo[M`7mc7uhc$7midgbTf`7`$7%#ubf7 ci5Y'
>>> bytes([ (i+0xa)^0x1e for i in a.encode()])
b'flag{It_is_als0_impor@nt_t0_13arn_4sm!}'

easy_re

IDA打开,逻辑很简单,高低位互换

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char Str[52]; // [rsp+20h] [rbp-40h] BYREF
  int v5; // [rsp+54h] [rbp-Ch]
  int j; // [rsp+58h] [rbp-8h]
  int i; // [rsp+5Ch] [rbp-4h]

  _main();
  printf("Input your flag:");
  scanf("%s", Str);
  v5 = strlen(Str);
  for ( i = 0; i < v5; ++i )
    Str[i] = (Str[i] >> 4) | (16 * Str[i]);
  for ( j = 0; j < v5; ++j )
  {
    if ( Str[j] != des[j] )
    {
      printf("Wrong!");
      exit(0);
    }
  }
  printf("Right!");
  return 0;
}

>>> a = '66C61676B7452797F54703F53703C66733F5478656F52696E6162797F507270326C633D6D7'
>>> bytes([int(a[i:i+2][::-1],16) for i in range(0, len(a),2)])
b'flag{Try_t0_s0lv3_the_binary_pr0bl3m}'

 

seed

10字节随机数的key异或

  printf("Input your flag:");
  scanf("%s", v6);
  srand(seed);
  for ( i = 0; i <= 9; ++i )
  {
    v3 = rand() % 255;
    v5[i] = v3;
  }
  for ( j = 0; j <= 44; ++j )
    *((_BYTE *)v6 + j) ^= v5[j % 10];
  for ( k = 0; k <= 44; ++k )
  {
    if ( *((unsigned __int8 *)v6 + k) != des[k] )
    {
      printf("Wrong!");
      exit(0);
    }
  }
  printf("Right!");

用flag{头可以出来5个,后边的就只能一个个试,看着合适再试下一个

a = bytes.fromhex('402928E9C204A4ED9F535F753CD1CD2BA8C48969152116EFD72792DFCA535F2A3CD1CE03A3EFA578161A2DE1C4')
from pwn import xor

flag = b'flag{Give_'
key = xor(flag, a[:len(flag)])

for i in range(256):
    tkey = key + bytes([i])
    m = xor(tkey.ljust(10, b'\x00'),a)
    if all([0x20<=m[v]<=0x7e for v in range(len(flag),len(a),10)]):
        print(i, m)

#flag{Give_y0u_the_se3d_and_D0_you_w@nt_t0_do}

 

signin

这才是签到,跳过

ez_math

代码是公式,这种很常见,用z3

print("Please input flag:")
flag = input()
if len(flag)!=42:
	print("Check your length!")
	exit()

l=[]
for i in range(6):  #7字符1段,分6段
	s=""
	for j in flag[i*7:i*7+7]:
		s+=hex(ord(j))[2:]
	l.append(int(s,16))
if (
(593*l[0] + 997*l[1] + 811*l[2] + 258*l[3] + 829*l[4] + 532*l[5])== 0x5b8e0aef71d34ff43 and \
(605*l[0] + 686*l[1] + 328*l[2] + 602*l[3] + 695*l[4] + 576*l[5])== 0x551a262360964ef7f and \
(373*l[0] + 512*l[1] + 449*l[2] + 756*l[3] + 448*l[4] + 580*l[5])== 0x49d158a5657d6931c and \
(560*l[0] + 635*l[1] + 422*l[2] + 971*l[3] + 855*l[4] + 597*l[5])== 0x625568d5abbabf4f3 and \
(717*l[0] + 507*l[1] + 388*l[2] + 925*l[3] + 324*l[4] + 524*l[5])== 0x50ee0c025e70e3c23 and \
(312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x40e735f8aa2815f65):
	print("Good job!")
else:
	print("Wrong\nTry again!!!")
	exit()
from z3 import *

l = [Int(f'l_{i}') for i in range(6)]
s = Solver()
s.add((593*l[0] + 997*l[1] + 811*l[2] + 258*l[3] + 829*l[4] + 532*l[5])== 0x5b8e0aef71d34ff43)
s.add((605*l[0] + 686*l[1] + 328*l[2] + 602*l[3] + 695*l[4] + 576*l[5])== 0x551a262360964ef7f)
s.add((373*l[0] + 512*l[1] + 449*l[2] + 756*l[3] + 448*l[4] + 580*l[5])== 0x49d158a5657d6931c)
s.add((560*l[0] + 635*l[1] + 422*l[2] + 971*l[3] + 855*l[4] + 597*l[5])== 0x625568d5abbabf4f3)
s.add((717*l[0] + 507*l[1] + 388*l[2] + 925*l[3] + 324*l[4] + 524*l[5])== 0x50ee0c025e70e3c23)
s.add((312*l[0] + 368*l[1] + 884*l[2] + 518*l[3] + 495*l[4] + 414*l[5])== 0x40e735f8aa2815f65)

s.check()
d = s.model()

flag = b''
for i in l:
    flag+=long_to_bytes(d[i].as_long())

#flag{N0_One_kn0ws_m@th_B3tter_Th@n_me!!!!}

 

ez_apk

jadx打开是base58变表,密文和码表不在layout目录里,发现外部有多个dex文件,打开class3.dex找到码表和密文

从classes3.dex找到密文和码表,base58变表解密
enc ='5TAYhycAPT1aAd535TGdWYQ8CvfoRjErGEreqhDpqv1LydTqd3mxuK2hhUp9Pws3u9mq6eX'
code1 = '9LfnoVpi1HrzBSKxhNFeyY745R2g3QmqsTCZJuDvcMdkE8wPGbUXajtAW6'
#flag{Jue_1_ju3_Y0ung_and_G0at_1s_go0d_for_yOuR_body}

week2

签到题?

在堆数字128运算后XXX后边不详,先动调得到这些数据

可以看到右下角栈里的Arglist的数据,显然是可显示的字符,导出后得到,显示base64

ZmxhZ3thMTBlN2NjYy1iODAyLWUzZWItYzg1OWE3LTMwOTQwZTIyNmR9 

not gcc 未完成

pycode

给的python字节码,一点点手搓。看明白了再反一下就行

import base64 

flag = '....'
value = ''
output = ''

#24
for i in range(1000):
    w = 1024
    x = w%3
    y = w//9
    x = x*y
    w -= z     

#94
for i in range(10000):
    w = 20 
    x = w%6 
    y = w//3 
    z = x*y 
    w += z 

#166
for i in range(1000):
    w = 1024
    x = w%3 
    y = w//9 
    x = x*y 
    w -= z 

#238
for i in range(10000):
    w = 20 
    x = w%6 
    y = w//3 
    z = x*y
    w += z 

#310
for i in range(len(flag)):
    temp = flag[i]
    temp = chr(ord(temp)^8)    
    value += temp

for i in range(len(flag)):
    temp = value[i]
    temp = chr(ord(temp)+3)
    output += temp 

obfuscated_output = base64.b64encode(output.decode())
obfuscated_output = obfuscated_output[::-1]
obfuscated_output = obfuscated_output.replace('0','t')
obfuscated_output = obfuscated_output.replace('c','4')
obfuscated_output = obfuscated_output.replace('+','-')
print(obfuscated_output)

#------------------------------------------------------------
from itertools import product 
from base64 import * 

enc = '==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4'
enc = enc[::-1].replace('-','+')
a = [('0','t') if v=='t' else ('c','4') if v=='4' else (v) for v in enc]


for k in product(*a):
    try:
        #print(''.join(k))
        b = b64decode(''.join(k).encode())
        #print(b)
        c =bytes([(i-3)^8 for i in b])
        print(c)
    except:
        pass 
        
b'flag{1b36920e-c180-b250-6537-30238f5}'

run!润

从关键代码可以看出有左右上下和上下层,是个三维迷宫,先得到数据

数据在这

 

取出来打印出来看,然后手搓

from pwn import u32 

#每层map 2*32位 8层从上到下
#在memset下断点,动调得到正确的map数据
dat = open('run.dat', 'rb').read()
print(dat.hex())
dat = ''.join([bin(u32(dat[i:i+4]))[2:].zfill(32) for i in range(0, len(dat), 4)])

for i in range(0, len(dat),8):
    if i%64==0: print()
    print(dat[i:i+8])

从后向前走每步编上号,然后从前向后得到串 

j10srqpo
i1111111
hgfe1111
111d1111
111c1111
11111111
11111111
11111111

111t111n
11111111
11111111
11111111
111b1111
11111111
11111111
11111111

111u111m
1111111l
11111ijk
11111111
111a1111
11111111
11111111
11111111

111v1111
111w1111
111x1h11
111y1111
111z1111
11111111
11111111
11111111

11111111
11111111
11111g11
11111111
11111111
11111111
vutsrqpo
11111111

11111111
11111111
abcdef11
z1111111
y1111111
x1111111
w111111n
11111111

11111111
11111111
11111111
11111hij
11111g1k
1111111l
1111111m
11111111

11111111
11111111
11111111
11111111
11111f11
11111e11
11111d11
11111cba

 输入串运行得到flag

C:\2023_ctf\2023_SHCTF\week2_r>run.exe
This is a easy puzzle.
Input your route:
ssdddssuuuwwwwqqqdddduussaauuuaaaaassssqddddddduuwwwaasusssdd
Right!Here are you flag:flag{7a30a122cbf428239147d86fcb3a2a37}

 

Authur's box

初始化S和K

 

S加K交换,很符合RC4加密

从汇编里找到对应的k

 

解密,后部加了异或的RC4


s = [i for i in range(256)]
k = (b'h3rE1Sy0UkEy'*30)[:256]
v3 = 0
for i in range(256):
    v3 = (s[i]+v3+k[i])%256
    s[i],s[v3] = s[v3],s[i]

v6 = 0
v7 = 0
#byte_408A80
ekey = [0]*42
for i in range(42):
    v6 = (v6+1)%256 
    v7 = (v7 + s[v6])%256 
    s[v6],s[v7] = s[v7],s[v6]
    ekey[i] = s[(s[v6]+s[v7])%256]^0x22

str2 = bytes.fromhex('3894E7FE4C620212054AFD714D13EC165437909BD9E9D2EDED5AD4D815596C3DB1DA43CB5A7396F996B7')
from pwn import xor 
print(xor(str2, bytes(ekey)))

 

week3

java是最棒的语言吗

chacha20加密

public class ChaCha20 {
    public static void main(String[] strArr) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("input your flag:");
        String nextLine = scanner.nextLine();
        if (Arrays.equals(encrypt(nextLine.getBytes(StandardCharsets.UTF_8), "Shctf_Welcomes_Have_4_good_t1me_".getBytes(), "HsehrcOedfgs".getBytes()), hexStringToBytes("ce43283af73d106815fe5293b474f5309d44063c7fde19533300c60603dfe528d19aee2f6db615191e45"))) {
            System.out.println("right!");
        } else {
            System.out.println("error!");
        }
    }

    private static byte[] encrypt(byte[] bArr, byte[] bArr2, byte[] bArr3) {
        int[] chachaInit = chachaInit(bArr2, bArr3);
        byte[] bArr4 = new byte[bArr.length];
        byte[] bArr5 = new byte[64];
        for (int i = 0; i < bArr.length; i += 64) {
            chachaBlock(chachaInit, bArr5);
            for (int i2 = 0; i2 < 64 && i + i2 < bArr.length; i2++) {
                bArr4[i + i2] = (byte) (bArr[i + i2] ^ bArr5[i2]);
            }
            chachaInit[12] = chachaInit[12] + 1;
        }
        return bArr4;
    }

    private static int[] chachaInit(byte[] bArr, byte[] bArr2) {
        int[] iArr = new int[16];
        iArr[0] = 1634760805;
        iArr[1] = 857760878;
        iArr[2] = 2036477234;
        iArr[3] = 1797285236;
        for (int i = 0; i < 8; i++) {
            iArr[4 + i] = bytesToIntLittleEndian(bArr, i * 4);
        }
        iArr[12] = 0;
        iArr[13] = 0;
        iArr[14] = bytesToIntLittleEndian(bArr2, 0);
        iArr[15] = bytesToIntLittleEndian(bArr2, 4);
        return iArr;
    }

    private static void chachaBlock(int[] iArr, byte[] bArr) {
        int[] copyOf = Arrays.copyOf(iArr, 16);
        for (int i = 0; i < 10; i++) {
            chachaDoubleRound(copyOf);
        }
        for (int i2 = 0; i2 < 16; i2++) {
            intToBytesLittleEndian(iArr[i2] + copyOf[i2], bArr, i2 * 4);
        }
    }

    private static void chachaDoubleRound(int[] iArr) {
        quarterRound(iArr, 0, 4, 8, 12);
        quarterRound(iArr, 1, 5, 9, 13);
        quarterRound(iArr, 2, 6, 10, 14);
        quarterRound(iArr, 3, 7, 11, 15);
        quarterRound(iArr, 0, 5, 10, 15);
        quarterRound(iArr, 1, 6, 11, 12);
        quarterRound(iArr, 2, 7, 8, 13);
        quarterRound(iArr, 3, 4, 9, 14);
    }

    private static void quarterRound(int[] iArr, int i, int i2, int i3, int i4) {
        iArr[i] = iArr[i] + iArr[i2];
        iArr[i4] = rotateLeft(iArr[i4] ^ iArr[i], 16);
        iArr[i3] = iArr[i3] + iArr[i4];
        iArr[i2] = rotateLeft(iArr[i2] ^ iArr[i3], 12);
        iArr[i] = iArr[i] + iArr[i2];
        iArr[i4] = rotateLeft(iArr[i4] ^ iArr[i], 8);
        iArr[i3] = iArr[i3] + iArr[i4];
        iArr[i2] = rotateLeft(iArr[i2] ^ iArr[i3], 7);
    }

    private static int rotateLeft(int i, int i2) {
        return (i << i2) | (i >>> (32 - i2));
    }

    private static int bytesToIntLittleEndian(byte[] bArr, int i) {
        return ((bArr[i + 3] & 255) << 24) | ((bArr[i + 2] & 255) << 16) | ((bArr[i + 1] & 255) << 8) | (bArr[i] & 255);
    }

    private static void intToBytesLittleEndian(int i, byte[] bArr, int i2) {
        bArr[i2] = (byte) (i & 255);
        bArr[i2 + 1] = (byte) ((i >>> 8) & 255);
        bArr[i2 + 2] = (byte) ((i >>> 16) & 255);
        bArr[i2 + 3] = (byte) ((i >>> 24) & 255);
    }

    private static byte[] hexStringToBytes(String str) {
        int length = str.length();
        byte[] bArr = new byte[length / 2];
        for (int i = 0; i < length; i += 2) {
            bArr[i / 2] = (byte) ((Character.digit(str.charAt(i), 16) << 4) + Character.digit(str.charAt(i + 1), 16));
        }
        return bArr;
    }

    private static String bytesToHexString(byte[] bArr) {
        StringBuilder sb = new StringBuilder();
        int length = bArr.length;
        for (int i = 0; i < length; i++) {
            sb.append(String.format("%02x", Byte.valueOf(bArr[i])));
        }
        return sb.toString();
    }
}

key和密文会给了。这种解释性的语言似乎没有多少隐私。 

k1 = "Shctf_Welcomes_Have_4_good_t1me_"
k2 = "HsehrcOedfgs"
enc = bytes.fromhex("ce43283af73d106815fe5293b474f5309d44063c7fde19533300c60603dfe528d19aee2f6db615191e45")

def encrypt(m,k1,k2):
    chacha = chachainit(k1,k2)
    a4 = [0]*len(m)
    a5 = [0]*64
    for i in range(0, len(m),64):
        block(chacha, b5)
        for i2 in range(64):
            if i2>=len(m): break 
            a4[i+i2] = m[i+i2]^a5[i2]
        chacha[12] += 1 
    return a4 

def chachainit(k1,k2):
    a = [0]*16
    a[0] = 1634760805
    a[1] = 857760878
    a[2] = 2036477234
    a[3] = 1797285236
    for i in range(8):
        a[i+4] = u32(p32(a[i])[::-1])
    a[14] = u32(k2[:4]);
    a[15] = u32(k2[4:]);
    return a

 

ststst

带SMC的程序,先按原程序patch再反编译

 

 

msg = open('ststst','rb').read()
a = msg[:0x696]+bytes([i^0xc3 for i in msg[0x696:0x763]])+ msg[0x763:]
open('st2','wb').write(a)

打开新生成的文件,发现是个tea加密

 RC4和tea是逆向最爱用的,tea可以随便写左右加key,可以保证每次都不一样

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  int i; // [rsp+4h] [rbp-3Ch]
  _QWORD s1[6]; // [rsp+10h] [rbp-30h] BYREF

  s1[5] = __readfsqword(0x28u);
  puts("plz input u fl4g:");
  __isoc99_scanf("%32s", s1);
  sub_400763();
  for ( i = 0; i <= 3; ++i )
    sub_400696(&s1[i], &unk_601080);
  if ( !memcmp(s1, &unk_6010A0, 0x20uLL) )
    puts("yeh~");
  else
    puts("oh,no");
  return 0LL;
}

__int64 __fastcall sub_400696(unsigned int *a1, _DWORD *a2)
{
  __int64 result; // rax
  unsigned int v3; // [rsp+10h] [rbp-10h]
  unsigned int v4; // [rsp+14h] [rbp-Ch]
  int v5; // [rsp+18h] [rbp-8h]
  unsigned int i; // [rsp+1Ch] [rbp-4h]

  v3 = *a1;
  v4 = a1[1];
  v5 = 0;
  for ( i = 0; i <= 0x1F; ++i )
  {
    v5 -= 1640531527;
    v3 += (v4 + v5) ^ (16 * v4 + *a2) ^ ((v4 >> 5) + a2[1]);
    v4 += (v3 + v5) ^ (16 * v3 + a2[2]) ^ ((v3 >> 5) + a2[3]);
  }
  *a1 = v3;
  result = v4;
  a1[1] = v4;
  return result;
}
from pwn import u32,p32
from ctypes import *
'''
  for ( i = 0; i <= 0x1F; ++i )
  {
    v5 -= 1640531527;
    v3 += (v4 + v5) ^ (16 * v4 + *a2) ^ ((v4 >> 5) + a2[1]);
    v4 += (v3 + v5) ^ (16 * v3 + a2[2]) ^ ((v3 >> 5) + a2[3]);
  }
'''
def decrypt(v,k):
    v0 = c_uint32(v[0])
    v1 = c_uint32(v[1])
    delta = 0x9e3779b9
    sum1 = c_uint32((delta) * 32)
    for i in range(32):       
        v1.value -= (sum1.value + v0.value) ^ (k[2] + (v0.value << 4)) ^ (k[3] + (v0.value >> 5))
        v0.value -= (sum1.value + v1.value) ^ (k[0] + (v1.value << 4)) ^ (k[1] + (v1.value >> 5))
        sum1.value -= delta       
    return p32(v0.value) + p32(v1.value)

key = [0x1234567, 0x89ABCDEF, 0xFEDCBA98, 0x76543210]
enc = bytes.fromhex('69258FDBE383CD4080E633A044A6F7FF173A0C6966B821B6A7E2E73492A610AD')
enc = [u32(enc[i:i+4]) for i in range(0,32,4)]

msg = [decrypt(enc[2*i: 2*i+2], key) for i in range(4)]
print(msg)
print(b''.join(msg))
#5ef846656801c9b9714388d2ccd98cdd

 

easyre

把串异或后再当成python运行,这个值爆破得到23

import base64
import marshal
import sympy as sp
encoded_data = b'#`VVVVVVVVVVVVVVVVVVVVVSVVVVFVVVV_YZVVVVMVU|VNFV@pU|V{xUMVYvVzBSMVDSVFRVMFDSV\\VQMV@\x7fVAxPMFU{V@BPp`]vU%B_MF]eVy]VMFY|UxZUVFUbTPBSMVrSVFRVMV\x7fCVT|]N`^VVVVVVVVVVVVVVVpVVVVPVVVVF`VVV_GFVVVVsVU\'V@FUp`PSVO\'TMV].V$FUMVPSVBFVOC".U_`SqV]/UU|VQ`U/V_`RsV]/V^ZUQpVMVUtVMVR@V_\'SqV]/Vo|VqV]/UU|VVpU/Vy`RGVU/Vy`SGVUoPPFTUVU.U_\'SsVXSV_\'QqVQRVQ&pqFM/UPFSQ`U|VENVqFE/V$`TqVFMVUtVMVR@V_\'SqV]/Vo|VqV]/UU|VVpU/Vy`RGVU/Vy`SGVU/Vy`TqVFMV_`TqVZMVUtVMVR@VU|VqFs/UvVRqVM/U\'RVxFRUV_QfqVACVT|RCb|VVFVV!FVVVVSgVFVVVT|Q%pEdvOY\'%pAnN@"yMsxSuPAb%p{~rOE{NO]nNOyvUzQ`tPAbMT|^%pYeMO{vTOUdN@{bsPA#sYxUB.xUvcxUvAx\\N%{`vPAnsPA#sYxRN%\x7f\x7ftcxUv!|Vtp/VVVS!UzM&u~"`rsx[tzZ\'O%AbN$]"t_FUVVVVto`VVVVVVF`UUV^ZVDVU_V^^VFNTTVRZVEVUPpRNVEVTt\x7fRVVVUmT`VVVPA#N@&`uPAqv%A"tnxVVVSN{U!ez%M\'!&&VP ez!UZmA.\'X"g^\'/NUcvXd.TPRTTD!&UB\\`dT.R}Q{!QQUdr~UguyU&sTU"u$An^PMdN@t!rpA&sPNcXQxSr@Am@p]bu\'#gT_^EVVVVtp|VVVUvU@YxM@Ye%pA`tz{bsYxQv@"`sOCvUzAbN%.|MsxRMzo\x7fM&x]M@"}ty{`sPA|tp/VVVUnS`VVV_^GVVVVt\x7fVVVVSvTSocu%E&uPB<VFVVV_ZFVVVVTUFRVFFTTVRZVpxTTVR\\Vp**'
xor_key = int(input('Plz input key (0<key<100):'))
x = sp.symbols('x')
f = x ** 2 + x + 1
integral_value = sp.integrate(f, (x, 1, xor_key))
check_value = 13024
if integral_value * 3 == check_value:
    xor_decoded_data = bytes((lambda .0: [ byte ^ xor_key for byte in .0 ])(encoded_data))
    decoded_data = base64.b64decode(xor_decoded_data)
    code_obj = marshal.loads(decoded_data)
    exec(code_obj)
else:
    print('Wrong!!')
    return None

转出再反编译 

encoded_data = b'#`VVVVVVVVVVVVVVVVVVVVVSVVVVFVVVV_YZVVVVMVU|VNFV@pU|V{xUMVYvVzBSMVDSVFRVMFDSV\\VQMV@\x7fVAxPMFU{V@BPp`]vU%B_MF]eVy]VMFY|UxZUVFUbTPBSMVrSVFRVMV\x7fCVT|]N`^VVVVVVVVVVVVVVVpVVVVPVVVVF`VVV_GFVVVVsVU\'V@FUp`PSVO\'TMV].V$FUMVPSVBFVOC".U_`SqV]/UU|VQ`U/V_`RsV]/V^ZUQpVMVUtVMVR@V_\'SqV]/Vo|VqV]/UU|VVpU/Vy`RGVU/Vy`SGVUoPPFTUVU.U_\'SsVXSV_\'QqVQRVQ&pqFM/UPFSQ`U|VENVqFE/V$`TqVFMVUtVMVR@V_\'SqV]/Vo|VqV]/UU|VVpU/Vy`RGVU/Vy`SGVU/Vy`TqVFMV_`TqVZMVUtVMVR@VU|VqFs/UvVRqVM/U\'RVxFRUV_QfqVACVT|RCb|VVFVV!FVVVVSgVFVVVT|Q%pEdvOY\'%pAnN@"yMsxSuPAb%p{~rOE{NO]nNOyvUzQ`tPAbMT|^%pYeMO{vTOUdN@{bsPA#sYxUB.xUvcxUvAx\\N%{`vPAnsPA#sYxRN%\x7f\x7ftcxUv!|Vtp/VVVS!UzM&u~"`rsx[tzZ\'O%AbN$]"t_FUVVVVto`VVVVVVF`UUV^ZVDVU_V^^VFNTTVRZVEVUPpRNVEVTt\x7fRVVVUmT`VVVPA#N@&`uPAqv%A"tnxVVVSN{U!ez%M\'!&&VP ez!UZmA.\'X"g^\'/NUcvXd.TPRTTD!&UB\\`dT.R}Q{!QQUdr~UguyU&sTU"u$An^PMdN@t!rpA&sPNcXQxSr@Am@p]bu\'#gT_^EVVVVtp|VVVUvU@YxM@Ye%pA`tz{bsYxQv@"`sOCvUzAbN%.|MsxRMzo\x7fM&x]M@"}ty{`sPA|tp/VVVUnS`VVV_^GVVVVt\x7fVVVVSvTSocu%E&uPB<VFVVV_ZFVVVVTUFRVFFTTVRZVpxTTVR\\Vp**'

from pwn import xor 
import dis
from base64 import b64decode 

msg = xor(bytes([23]), encoded_data)
msg = b64decode(msg)
open('easyre_1.pyc','wb').write(msg)
dis.dis(msg)

 又是个rc4

def rc4_encrypt(key, plaintext):
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i],S[j] = S[j],S[i]
    i = j = 0
    ciphertext = []
    for char in plaintext:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i],S[j] = S[j],S[i]
        k = S[(S[i] + S[j]) % 256]
        ciphertext.append(char ^ k)
    print(bytes(ciphertext))

key = b'example_key'
check = b'\xd8\x94\x1e\xab\x9bft\xeb]@\x1b\xba\xe6\xe8\x133W\xdd\x0e\xe6\x924\xf1\x80mh\xeb=\x08a\x02\t.\xb5\x05B\xb0\xb0/D\x8cY'
rc4_encrypt(key, check)

喵喵喵

分别从汇编得到密文和反编译里得到大概的key

 

这是AES+base64只是key和iv未知,大概是上边这个串。用go_parser翻过来的程序参数基本看不出来,看汇编这块可以知道key是023_S0_e4sy_m1ao 然后用解密后的明文异或一下flag{得到iv(这个串的前边16字节:SHCTF_2023_S0_e4)

 网站上解密:flag{GO1an6_REAl1Y_eaSy_10R_D3V3lop_aND_quIckIY_RuN_65601185ae5b}

crackme

lua的字节码,与python,java类似,用unluac.jar解包,这个效果非常不错。

print("please input your flag:")
flag = io.read()
code = {}
secret = {
  54,57,566,532,1014,1,7,508,10,12,498,494,6,24,14,20,489,492,0,10,490,498,517,539,21,528,517,530,543,9,13,0,4,51,562,518,526,7,9,12,5,3,513,575,514,6,519,513,556,31,1,594,117,15
}
l = string.len(flag)
-- 序号从1开始
for i = 1, l do
  num = ((string.byte(flag, i) + i) % 333 + 444) % 555 - 1
  table.insert(code, num)
end
for i = 1, l do
  x = i - 1
  if i + 2 >= l then
    code[i] = code[i % l + 1] ~ code[(i + 1) % l + 1]
  else
    code[i] = code[(i + 1) % l] ~ code[(i + 2) % l]
  end
end
for i = 1, l do
  if secret[i] ~= code[i] then
    print("Incorrect")
    return
  end
end
print("You win,flag is", flag)

lua的数组0是基本不用的,这给反编译带来很大麻烦,已经习惯了从0开始,以后如果出中文的会更更更不方便。

enc = [54,57,566,532,1014,1,7,508,10,12,498,494,6,24,14,20,489,492,0,10,490,498,517,539,21,528,517,530,543,9,13,0,4,51,562,518,526,7,9,12,5,3,513,575,514,6,519,513,556,31,1,594,117,15]
flag = [546,553,543,550,16]+[0]*len(enc)
for i in range(2, len(enc)):
    flag[i] = flag[i-1]^enc[i-2]

for i in range(1,len(enc)+1):
    for j in range(0x20,0x7f):
        if ((j+i)%333+444)%555-1 == flag[i-1]:
            print(chr(j), end= '')
            break 
#flag{C000ngr4tulat1ons!Y0u_Cr4cked_m3_991468a8de6a!!!}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1155475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

赛宁网安多领域创新成果亮相第五届“纵横”论坛

10月27日&#xff0c;第五届“纵横”网络空间安全创新论坛在安徽合肥举办&#xff0c;来自中央国家机关、地方政府、军队有关单位、高校、科研院所和部分高新技术企业的领导、专家和代表500余人参加。 本届论坛由军事科学院和国防科技大学等单位共同主办&#xff0c;国防科技大…

电脑出现找不到d3dcompiler_43.dll的情况怎么办,分享d3dcompiler_43.dll丢失的办法

在使用电脑时你是不是也遇到过“未找到d3dcompiler_43.dll”的情况&#xff1f;是使用电脑的过程中d3dcompiler_43.dll丢失是一个经常出现问题&#xff0c;是一件大概率的事情&#xff0c;但是对于不了解这个文件的小伙伴而言出现这个问题是一件棘手的事情&#xff0c;那么今天…

postman做接口测试

之前搞自动化接口测试&#xff0c;由于接口的特性&#xff0c;要验证接口返回xml中的数据&#xff0c;所以没找到合适的轮子&#xff0c;就自己用requests造了个轮子&#xff0c;用着也还行&#xff0c;不过就是case管理有些麻烦&#xff0c;近几天又回头看了看postman也可以玩…

悠络客携新品UMind亮相安博会,从深耕商业连锁出发,正式进军ToG、ToC领域

2023年10月25日&#xff0c;第十九届中国国际社会公共安全博览会&#xff08;CPSE安博会&#xff09;在深圳会展中心隆重开幕。悠络客作为以公有云为核心的人工智能企业&#xff0c;联合海外事业部以全新面貌亮相展会现场。 本次参展&#xff0c;对悠络客而言有着非同寻常的重要…

【c++|opencv】二、灰度变换和空间滤波---4.高斯滤波

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 1. 高斯滤波 #include <iostream> #include <opencv2/opencv.hpp> #include"Salt.h"using namespace std; using namespace cv;/…

Android 13 Handler详解

1.Handler 简介 Handler 是一套 Android 消息传递机制。在多线程应用场景中&#xff0c;将子线程中需要更新 UI 的操作消息&#xff0c;传递到 UI 主线程&#xff0c;从而实现子线程通知 UI 更新最终实现异步消息处理。说白了是用于线程之间的通信。 Handler主要有4个重要类&a…

对xss-labs靶场的一次XSS攻击

1、首先我们进入靶场&#xff0c;提示我们开始测试 2、我使用AWVS工具进行了先行扫描&#xff0c;发现爆出XSS漏洞 3、然后对症下药 在输入框中输入&#xff1a; <script>alert(document.cookie)</script> 4、进入下一关 5、我们直接执行<script>…

priority_queue 的模拟实现

priority_queue 的底层结构 我们已经学习过栈和队列了&#xff0c;他们都是用一种容器适配出来的。今天我们要学习的 prority_queue 也是一个容器适配器。在 priority_queue 的使用部分我们已经知道想要适配出 priority_queue&#xff0c;这个底层的容器必须有以下接口&#x…

040-第三代软件开发-全新波形抓取算法

第三代软件开发-全新波形抓取算法 文章目录 第三代软件开发-全新波形抓取算法项目介绍全新波形抓取算法代码小解 关键字&#xff1a; Qt、 Qml、 抓波、 截获、 波形 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object …

【错误: 找不到或无法加载主类】回归java运行的本质

【错误: 找不到或无法加载主类】回归java运行的本质 一&#xff0c;背景 当有了idea这种工具后&#xff0c;java的mian方法执行起来是如此简单&#xff0c;很少有人再手动编辑并通过命令行执行了。 同时&#xff0c;在当今Spring Boot盛行的今天&#xff0c;恐怕很少再有人执…

基于SSM的模具制造企业订单跟踪管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

阿里云国际服务器如何申请退款

如果您的服务器配置购买错了&#xff0c;可以通过工单方式申请退款如何发工单&#xff1f; 打开如下链接登录阿里云国际多云管理服务商_Cloud MSP_九河云 (9he.com) 选择一个类目&#xff0c;提交工单&#xff0c;编辑需求内容 退款之前一定记录好当前剩余余额&#xff0c;避免…

【LeetCode:150. 逆波兰表达式求值 | 栈】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【驱动开发】注册字符设备使用gpio设备树节点控制led三盏灯的亮灭

注册字符设备使用gpio设备树节点控制led三盏灯的亮灭 设备树&#xff1a; 头文件&#xff1a; #ifndef __HEAD_H__ #define __HEAD_H__ typedef struct {unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR;unsigned int PUPDR;unsigned int IDR;unsigned int OD…

三.RocketMQ单机安装及集群搭建

RocketMQ单机安装及集群搭建 一&#xff1a;安装环境1.软硬件要求2.下载RocketMQ 二.安装单机MQ1.上传并解压2.目录介绍3.修改MQ启动时初始JVM内存4.启动NameServer与Broker5.测试RocketMQ 三.RocketMQ集群搭建1.集群概念特点2.集群模式分类3.集群工作流程4.双主双从集群搭建4.…

力扣刷题-队列-滑动窗口最大值

239. 滑动窗口最大值 给定一个数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回滑动窗口中的最大值。 进阶&#xff1a; 在线性时间复杂度内解决此题&#xff1f; …

【网络协议】聊聊http协议

当我们输入www.baidu.com的时候&#xff0c;其实是先将baidu.com的域名进行DNS解析&#xff0c;转换成对应的ip地址&#xff0c;然后开始进行基于TCP构建三次握手的连接&#xff0c;目前使用的是1.1 默认是开启了keep-Alive。可以在多次请求中进行连接复用。 HTTP 请求的构建…

【C++的OpenCV】第十四课-OpenCV基础强化(三):单通道Mat元素的访问之data和step属性

&#x1f389;&#x1f389;&#x1f389; 欢迎来到小白 p i a o 的学习空间&#xff01; \color{red}{欢迎来到小白piao的学习空间&#xff01;} 欢迎来到小白piao的学习空间&#xff01;&#x1f389;&#x1f389;&#x1f389; &#x1f496; C\Python所有的入门技术皆在 我…

JS--获取元素的高度与宽度

原文网址&#xff1a;JS--获取元素的高度与宽度_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍如何使用JavaScript获取HTML标签的高度与宽度。 读取的方法 document.getElementById("id").clientHeight 元素的尺寸属性 元素尺寸属性 说明 clientWidth 获取…

CentOS7非lvm给根分区扩容

首先查看现有磁盘信息和文件系统的信息 关闭虚拟机&#xff0c;右键虚拟机&#xff0c;点击设置&#xff0c;选中硬盘&#xff0c;右边点击拓展&#xff0c;然后给磁盘空间增加到指定的大小 打开虚拟机&#xff0c;查看扩容后的分区大小&#xff0c;此时会发现根分区大小并…