[NewStarCTF2023]Week3


NewStarctf2023_Week3_Offical

Reverse

去花
img
按c强制生成代码
img
第二处
img
第三处
img
在0x00401500处按P生成函数
主函数,RC4加密,key是WOWOWOWWOWOWOW
img

exp

from Crypto.Cipher import ARC4
a =[
  0xF4, 0x87, 0xD4, 0xFA, 0x61, 0xA6, 0x71, 0x12, 0x75, 0x09, 
  0xFE, 0xD8, 0xE4, 0x38, 0x97, 0x51, 0xA8, 0xDF, 0x85, 0x65, 
  0xC2, 0xB2, 0x15, 0xEF, 0x1F, 0xEC, 0x69, 0xDD, 0x6E, 0xE9, 
  0xCF, 0x07, 0xAE, 0xC8, 0x17, 0xF0, 0x65, 0x72, 0xE6, 0x73, 
  0xA4, 0x0C, 0x87, 0x64, 0x9E, 0x9E, 0x71, 0x8C, 0x7F, 0xD7, 
  0x75, 0x84]
key = b'WOWOWOWWOWOWOW'
enc = b''.join([bytes([i]) for i in a])
rc4 = ARC4.new(key)
decrypted_data = rc4.decrypt(enc)
print(decrypted_data.decode('utf-8'))
# flag{You!FlowerMaster!YouPassTheThirdPZGALAXYlevel!}

flag

flag{You!FlowerMaster!YouPassTheThirdPZGALAXYlevel!}

STL

C++逆向,大致能读懂相关函数
img
直接爆破,脚本跑得有点慢,大致20min能出结果

exp

from Crypto.Util.number import long_to_bytes
enc = [
  0x2882D802120E, 0x28529A05954, 0x486088C03, 0xC0FB3B55754,
  0xC2B9B7F8651, 0xAE83FB054C, 0x29ABF6DDCB15, 0x10E261FC807,
  0x2A82FE86D707, 0xE0CB79A5706, 0x330560890D06]
hex_list = [0]
flag = ''
for v in enc:
    tmp = ''
    for v7 in range(0x90000,0x70000000): # 这个爆破范围是用enc的最大值最小值右移15计算出来的
       if ((v7 << 15) ^ v7) == v:
          #print(long_to_bytes(v7),hex(v),hex(v7)[2:].zfill(8))
          tmp = hex(v7)[2:].zfill(8) # enc有些值爆破出来的值不足8位,用zill补齐
          #print(tmp)
          for i in range(len(tmp)-1,0,-2): # 小端序的处理
             hex_list.append(int(tmp[i-1:i+1],16))
          #hex_list = [int(tmp[i:i+2], 16) for i in range(0, len(tmp), 2)]
          break


print(hex_list)
for i in range(len(hex_list)-2,0,-1): # 异或处理
  hex_list[i] ^= hex_list[i+1]
for i in hex_list[::-1]: # 翻转在这里
  flag += chr(i)
print(flag)
# [0, 14, 18, 5, 81, 84, 89, 10, 5, 3, 12, 9, 0, 84, 87, 31, 24, 81, 6, 87, 24, 76, 5, 93, 1, 21, 75, 87, 83, 7, 72, 28, 2, 7, 87, 5, 85, 6, 87, 25, 28, 6, 13, 10, 102]
# flag{b53fc431-eb1f-89da-5bd5-2e1184728a5das}

flag

flag{b53fc431-eb1f-89da-5bd5-2e1184728a5das}

EzDLL

主程序中分析
img
key是
img
看看dll中的encrypt,是魔改过的xtea,注意魔改的地方
img
然后写脚本解,结果发现已知解不出来
倒回去重新分析主程序发现在TLS中加入了反调试,并且修改了xtea的key
img
计算一下真正的key是[5,20,13,14]
刚刚臭不可闻的key瞬间就浪漫起来了

exp

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 999999999, sum = delta * num_rounds + 1;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 3) ^ (v0 >> 4)) + v0) ^ (sum + key[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 3) ^ (v1 >> 4)) + v1) ^ (sum + key[sum & 3]);
        
    }
    v[0] = v0; v[1] = v1;
}
void encrypt(unsigned int *a1, uint32_t const a2[4]) {
    unsigned int v3; // [rsp+24h] [rbp+4h]
  unsigned int v4; // [rsp+44h] [rbp+24h]
  unsigned int v5; // [rsp+64h] [rbp+44h]
  unsigned __int64 i; // [rsp+A8h] [rbp+88h]

  v3 = *a1;
  v4 = a1[1];
  v5 = 1;
  for ( i = 0; i < 0x21; ++i )
  {
    v3 += (a2[(v5 & 3)] + v5) ^ (v4 + ((v4 >> 4) ^ (8 * v4)));
    v5 += 999999999;
    v4 += (a2[(v5 >> 11) & 3] + v5) ^ (v3 + ((v3 >> 4) ^ (8 * v3)));
  }
  *a1 = v3;
  a1[1] = v4;
}
int main() {
    uint32_t const k[4] = {5,20,13,14};
    uint32_t enc[] = {
      0x89A34382, 0xC880BA6F, 0xBD56B4F8, 0x8DB241B3, 0x040E44DA,
      0xDE382E03, 0x89AD5412, 0x21633095, 0x11940DDF, 0x11D0B2DC};
    unsigned int r = 33;
    uint32_t test[] = {305402420,287454020};
    encrypt(test,k);
    //printf("%u %u\n",test[0], test[1]);
    //decrypt(r,test,k);
    //printf("%u %u\n",test[0], test[1]);
    for(int i=8; i>=0; i-=2){
        decrypt(r, &enc[i], k);
    }
    printf("Decrypted data is: %s\n",(char*)enc);
    return 0;
}
//Decrypted data is: flag{Ca1l_y0u_3ven_1f_w3_@r3_f@r_Apart!}@

flag

flag{Ca1l_y0u_3ven_1f_w3_@r3_f@r_Apart!}

pyexe

直接pyinstxtractor,得到的文件是加密过的。注意使用和源文件同版本python,不然会出现如下skipping pyz extraction的问题
img
img

在反编译python生成可执行文件exe时,引用的类库文件经常遇到使用Crypto模块AES算法加密,解包生成的并不是pyc文件,而是加密的pyc.encrypted文件,它无法查看编译。
第一步,获取Crypto的key,这是打包时由开发者指定的。解包完成后将在根目录形成名为 pyimod00_crypto_key.pyc 的文件,将它转为py文件即可查看key文件。
第二步,编写解密处理的脚本代码

我们先获取key = '00000000new1star'
img
然后用脚本fix

import glob
import zlib
import tinyaes
from pathlib import Path
 
CRYPT_BLOCK_SIZE = 16
 
# key obtained from pyimod00_crypto_key
key = bytes('00000000new1star', 'utf-8')
 
for p in Path("./fakekey.exe_extracted/PYZ-00.pyz_extracted").glob("**/*.pyc.encrypted"):
    inf = open(p, 'rb') # encrypted file input
    outf = open(p.with_name(p.stem), 'wb') # output file
 
    # Initialization vector
    iv = inf.read(CRYPT_BLOCK_SIZE)
 
    cipher = tinyaes.AES(key, iv)
 
    # Decrypt and decompress
    plaintext = zlib.decompress(cipher.CTR_xcrypt_buffer(inf.read()))
 
    # Write pyc header
    # The header below is for Python 3.8
    outf.write(b'\x55\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0')
 
    # Write decrypted data
    outf.write(plaintext)
 
    inf.close()
    outf.close()
 
    # Delete .pyc.encrypted file
    p.unlink()
"""
Python 2.7: \x03\xf3\x0d\x0a\0\0\0\0
Python 3.0: \x3b\x0c\x0d\x0a\0\0\0\0
Python 3.1: \x4f\x0c\x0d\x0a\0\0\0\0
Python 3.2: \x6c\x0c\x0d\x0a\0\0\0\0
Python 3.3: \x9e\x0c\x0d\x0a\0\0\0\0\0\0\0\0
Python 3.4: \xee\x0c\x0d\x0a\0\0\0\0\0\0\0\0
Python 3.5: \x17\x0d\x0d\x0a\0\0\0\0\0\0\0\0
Python 3.6: \x33\x0d\x0d\x0a\0\0\0\0\0\0\0\0
Python 3.7: \x42\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0
Python 3.8: \x55\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0
Python 3.9: \x61\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0
Python 3.10: \x6f\x0d\x0d\x0a\0\0\0\0\0\0\0\0\0\0\0\0
"""

然后uncompyle6 反编译 fakekey.pyc得到源码

# uncompyle6 version 3.9.0
# Python bytecode version base 3.8.0 (3413)
# Decompiled from: Python 3.9.11 (tags/v3.9.11:2de452f, Mar 16 2022, 14:33:45) [MSC v.1929 64 bit (AMD64)]
# Embedded file name: fakekey.py
import base64
from settings import key

def eval_(data):
    return str(base64.b64decode(data))[2:-1]


consefued2 = [b'MA==', b'MQ==', b'Mg==', b'Mw==', b'NA==', b'NQ==', b'Ng==', b'Nw==', b'OA==', 
 b'OQ==', b'YQ==', b'Yg==', b'Yw==', b'ZA==', b'ZQ==', b'Zg==', b'Zw==', 
 b'aA==', b'aQ==', b'ag==', b'aw==', b'bA==', b'bQ==', b'bg==', b'bw==', 
 b'cA==', b'cQ==', b'cg==', b'cw==', b'dA==', b'dQ==', b'dg==', b'dw==', 
 b'eA==', b'eQ==', b'eg==', b'QQ==', b'Qg==', b'Qw==', b'RA==', b'RQ==', 
 b'Rg==', b'Rw==', b'SA==', b'SQ==', b'Sg==', b'Sw==', b'TA==', b'TQ==', 
 b'Tg==', b'Tw==', b'UA==', b'UQ==', b'Ug==', b'Uw==', b'VA==', b'VQ==', 
 b'Vg==', b'Vw==', b'WA==', b'WQ==', b'Wg==', b'IQ==', b'Ig==', b'Iw==', 
 b'JA==', b'JQ==', b'Jg==', b'Jw==', b'KA==', b'KQ==', b'Kg==', b'Kw==', 
 b'LA==', b'LQ==', b'Lg==', b'Lw==', b'Og==', b'Ow==', b'PA==', b'PQ==', 
 b'Pg==', b'Pw==', b'QA==', b'Ww==', b'XA==', b'XQ==', b'Xg==', b'Xw==', 
 b'YA==', b'ew==', b'fA==', b'fQ==', b'fg==', b'IA==', b'CQ==', b'Cg==', 
 b'DQ==', b'Cw==', b'DA==', b'YmFzZTY0LmI2NGRlY29kZQ==']

def change_fun2(fun):

    def real_fun(*args):
        ans = fun(*args)
        ans.pop(eval(eval(eval_(b'YmFzZTY0LmI2NGRlY29kZQ==') + '(consefued2[0])')) - 3)
        ans.pop(eval(eval(eval_(b'YmFzZTY0LmI2NGRlY29kZQ==') + '(consefued2[5])')))
        return ans

    return real_fun


def main(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]
    else:
        i, j = (0, 0)
        keystream = []
        for _ in range(len(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]
            keystream.append(k)
        else:
            ciphertext = []
            for i in range(len(plaintext)):
                ciphertext.append(ord(plaintext[i]) ^ keystream[i] ^ 5)
            else:
                return ciphertext


@change_fun2
def encode1(text):
    res = main(text)
    return res


def encode2(xxxx):
    return base64.b64encode((b'').join([chr(t).encode() for t in xxxx]))


if __name__ == '__main__':
    print('你好,祝您游戏愉快')
    flag = input('请输入flag (flag的长度为20)> ')
    b = encode2(encode1(flag))
    assert len(flag) == 20
    while True:
        if b == b'IMKJw4jCkgQxw6A1w5QRw7A5SG14wobDs8KF':
            print('you are right!')
            break
        else:
            print('work hard')

首先从 settings import了一个key
看看\PYZ-00.pyz_extracted里面的settings.pyc
img
源代码不难理解,主要是changefun2,让GPT解释一下
img
img
main函数是一个rc4然后异或5
所以整体加密就是rc4加密后异或5,接着pop加密后的flag的第5和-3位,最后base64
我们只需爆破第5位和第-3位字符即可

exp

import base64
import hashlib
def rc4(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
    keystream = []
    for _ in range(len(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]
        keystream.append(k)
    ciphertext = []
    for i in range(len(plaintext)):
        ciphertext.append(ord(plaintext[i]) ^ keystream[i] ^ 5)
    return ciphertext
def decode2(encoded_str):
    decoded_str = base64.b64decode(encoded_str).decode()
    return [ord(t) for t in decoded_str]
def decode(data):
    for a in range(256):
        for b in range(256):
            tmp_list = data[:5]+ [a] +data[5:-2]+ [ b,data[-2],data[-1]]    #拼接还原
            string_tmp = "".join([chr(t) for t in tmp_list])
            flag = "".join([chr(t) for t in rc4(string_tmp)])
            if hashlib.md5(flag.encode()).hexdigest()[:6] == "cbd746":
                print(flag)
a = b'IMKJw4jCkgQxw6A1w5QRw7A5SG14wobDs8KF'
key = b'new_star'
decode(decode2(a))
# flag{no_ke1_no_fuN!}

flag

flag{no_ke1_no_fuN!}

Let's Go

go逆向,直接用ida7.7
先看main_init,iv异或了0x32
img
接着看main_main
img
img
动调看看iv是什么
img
iv是和key一样,但是记得异或0x32
img

exp

from Crypto.Cipher import AES
iv = [0x4E, 0x65, 0x77, 0x53, 0x74, 0x61, 0x72, 0x21, 0x4E, 0x65, 0x77, 0x53, 0x74, 0x61, 0x72, 0x21]
iv = bytes([i ^ 0x32 for i in iv])
# print(iv)
key = b'NewStar!NewStar!'
enc = bytes.fromhex("ee01674b13ff8dd86f8e481aa86f5d25e773a3fd0338f60988cb738b8b178c44")
aes = AES.new(key, mode=AES.MODE_CBC, iv=iv)
print(aes.decrypt(enc))
# b"flag{It's_time_to_Go!!!Let's_Go}"

flag

flag{It's_time_to_Go!!!Let's_Go}

ez_chal_1

主函数分析如下
img
再看看sub_401170,明显xtea,多了个异或
img
动调获取key
img

exp

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string>
#include <string.h>
void decrypt(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x9E3778B9, sum = delta * num_rounds;
    for (i=0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]) ^ v0;
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]) ^ v1;
        
    }
    v[0] = v0; v[1] = v1;
}
char a[40] = {0};
int main() {
    uint32_t k[4] = {0};
    uint32_t enc[] = {
      0xC19EA29C,0xDC091F87,0x91F6E33B,0xF69A5C7A,
      0x93529F20,0x8A5B94E1,0xF91D069B,0x23B0E340};
    unsigned int r = 64;
    memcpy(a,"NewStar!NewStar!",strlen("NewStar!NewStar!"));
    for (int i = 0; i < strlen(a); i+=4) {
        k[i / 4] = *(uint32_t*)(a + i);
        //printf("%u ",k[i/4]);
    }
    for(int i=0; i<8; i+=2){
        decrypt(r, &enc[i], k);
    }
    printf("Decrypted data is: %s\n",(char*)enc);
    return 0;
}
//Decrypted data is: flag{Let's_Dr1nk_A_Cup_Of_Te4!!}NewStar!NewStar!

flag

flag{Let's_Dr1nk_A_Cup_Of_Te4!!}

Andronative

调用了native层的encode,传入输入和deadbeef
img
解包之后查看librunfaraway.so的encode函数
先看看最后的check,最后的结果经过test后与
6DTNDRc1uJyyyd/GrT+bW3NNIoXzPQyK722kicTTFTTySTzyRE+BWdXnW6zF7UY9iUZK27QN 比较
img
查看test,应该是base64
img
往前看,对v22赋完值(0~0xff)后,进行了_ROL2_移位
img
_ROL2_是ida内置函数,在ida/plugins/defs.h中可以查看到定义
img
再看看_ROL_函数
img

有两个参数:(value, int count)
第一个参数为左移的数,第二个参数为左移的位数。
如果第二个参数值为负数,则实际上为循环右移 -count位。
该函数的实现细节为:
先得到value的位数,然后count对位数取模。
如果count值大于0,则先右移-count取模的结果,然后在左移取模的结果,得到的两个数相或,即为循环左移的结果。
如果count值小于0,先左移在右移即可。
举例来说: value = 0110, count = 6
value为4位数, 6 % 4 = 2,
0110先右移4-2=2位,得到0001,然后在左移2位,得到1000,0001 | 1000结果为1001,即循环左移结果为1001。

知道ROL2的含义后只需将v22的数据用lazyida dump出来(其实就是0-255)
然后自己写个c模拟一下,可以得到所需的box表

#include <stdio.h>
#include <stdint.h>

uint16_t __ROL2__(uint16_t value, int count) {
    return (value << count) | (value >> (16 - count));
}

int main() {
    uint16_t v22[128];  // 128个uint16_t等于16个__int128

    // 初始化v22,每两个字节存储为一个uint16_t
    uint16_t initData[16][8] = {
        {0x0100, 0x0302, 0x0504, 0x0706, 0x0908, 0x0B0A, 0x0D0C, 0x0F0E},
        {0x1110, 0x1312, 0x1514, 0x1716, 0x1918, 0x1B1A, 0x1D1C, 0x1F1E},
        {0x2120, 0x2322, 0x2524, 0x2726, 0x2928, 0x2B2A, 0x2D2C, 0x2F2E},
        {0x3130, 0x3332, 0x3534, 0x3736, 0x3938, 0x3B3A, 0x3D3C, 0x3F3E},
        {0x4140, 0x4342, 0x4544, 0x4746, 0x4948, 0x4B4A, 0x4D4C, 0x4F4E},
        {0x5150, 0x5352, 0x5554, 0x5756, 0x5958, 0x5B5A, 0x5D5C, 0x5F5E},
        {0x6160, 0x6362, 0x6564, 0x6766, 0x6968, 0x6B6A, 0x6D6C, 0x6F6E},
        {0x7170, 0x7372, 0x7574, 0x7776, 0x7978, 0x7B7A, 0x7D7C, 0x7F7E},
        {0x8180, 0x8382, 0x8584, 0x8786, 0x8988, 0x8B8A, 0x8D8C, 0x8F8E},
        {0x9190, 0x9392, 0x9594, 0x9796, 0x9998, 0x9B9A, 0x9D9C, 0x9F9E},
        {0xA1A0, 0xA3A2, 0xA5A4, 0xA7A6, 0xA9A8, 0xABAA, 0xADAC, 0xAFAE},
        {0xB1B0, 0xB3B2, 0xB5B4, 0xB7B6, 0xB9B8, 0xBBBA, 0xBDBC, 0xBFBE},
        {0xC1C0, 0xC3C2, 0xC5C4, 0xC7C6, 0xC9C8, 0xCBCA, 0xCDCC, 0xCFCE},
        {0xD1D0, 0xD3D2, 0xD5D4, 0xD7D6, 0xD9D8, 0xDBDA, 0xDDDC, 0xDFDE},
        {0xE1E0, 0xE3E2, 0xE5E4, 0xE7E6, 0xE9E8, 0xEBEA, 0xEDEC, 0xEFEE},
        {0xF1F0, 0xF3F2, 0xF5F4, 0xF7F6, 0xF9F8, 0xFBFA, 0xFDFC, 0xFFFE},
    };

    for(int i = 0; i < 16; i++) {
        for(int j = 0; j < 8; j++) {
            v22[i * 8 + j] = initData[i][j];
        }
    }

    for(int i = 1; i < 127; i += 2) {
        v22[i] = __ROL2__(v22[i], 8);
        v22[i+1] = __ROL2__(v22[i+1], 8);
    }
    for(int i = 0; i < 128; i++) {
        printf("%d, %d", v22[i] & 0xFF, (v22[i] >> 8) & 0xFF);
        if (i != 127) {
            printf(", ");
        }
        if (i % 8 == 7) {
            printf("\n");
        }
    }

    return 0;
}

img
之后的加密逻辑其实就是和传进来的key异或,然后执行ROL1移位
ROL1根据以上分析其实就等效于

uint16_t __ROL1__(uint16_t value, int count) {
    return (value << count) | (value >> (8 - count));
}

据此可以写出exp

exp

import base64
def custom_base64_decode(data):
    custom_chars = 'TcdXDE6oNOPQRUepFGHwxfIJKnklSqrsyz+/LYZVW123ij789ABCMtuvgab045hm'
    # 创建标准Base64字符集和自定义字符集的映射表
    base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    char_map = str.maketrans( custom_chars, base64_chars)
    # 替换为自定义字符
    data = data.translate(char_map)
    # 使用标准Base64解码
    decoded_data = base64.b64decode(data.encode())
    return decoded_data
enc = '6DTNDRc1uJyyyd/GrT+bW3NNIoXzPQyK722kicTTFTTySTzyRE+BWdXnW6zF7UY9iUZK27QN'

result =  list(custom_base64_decode(enc))
print(result)

box = [0, 1, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14,
17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28, 31, 30,
33, 32, 35, 34, 37, 36, 39, 38, 41, 40, 43, 42, 45, 44, 47, 46,
49, 48, 51, 50, 53, 52, 55, 54, 57, 56, 59, 58, 61, 60, 63, 62,
65, 64, 67, 66, 69, 68, 71, 70, 73, 72, 75, 74, 77, 76, 79, 78,
81, 80, 83, 82, 85, 84, 87, 86, 89, 88, 91, 90, 93, 92, 95, 94,
97, 96, 99, 98, 101, 100, 103, 102, 105, 104, 107, 106, 109, 108, 111, 110,
113, 112, 115, 114, 117, 116, 119, 118, 121, 120, 123, 122, 125, 124, 127, 126,
129, 128, 131, 130, 133, 132, 135, 134, 137, 136, 139, 138, 141, 140, 143, 142,
145, 144, 147, 146, 149, 148, 151, 150, 153, 152, 155, 154, 157, 156, 159, 158,
161, 160, 163, 162, 165, 164, 167, 166, 169, 168, 171, 170, 173, 172, 175, 174,
177, 176, 179, 178, 181, 180, 183, 182, 185, 184, 187, 186, 189, 188, 191, 190,
193, 192, 195, 194, 197, 196, 199, 198, 201, 200, 203, 202, 205, 204, 207, 206,
209, 208, 211, 210, 213, 212, 215, 214, 217, 216, 219, 218, 221, 220, 223, 222,
225, 224, 227, 226, 229, 228, 231, 230, 233, 232, 235, 234, 237, 236, 239, 238,
241, 240, 243, 242, 245, 244, 247, 246, 249, 248, 251, 250, 253, 252, 254, 255]
key = 'deadbeef'
flag = ''
for i,val in enumerate(result):
    val = ((val << 3) | (val >> 5)) & 0xff
    val = ((val << 2) | (val >> 6)) & 0xff
    val ^= ord(key[i % len(key)])
    flag += chr(box.index(val))
print(flag)
# [24, 64, 8, 16, 192, 105, 217, 120, 32, 128, 40, 209, 120, 8, 186, 162, 178, 8, 88, 112, 225, 40, 184, 24, 186, 170, 154, 176, 16, 0, 64, 0, 32, 112, 8, 96, 48, 88, 178, 160, 32, 217, 160, 104, 80, 184, 217, 112, 176, 217, 152, 170, 226, 200]
# flag{I_hate_le333ekk_asd213sadlgajaieo2sa_this_is_s0?}

flag

flag{I_hate_le333ekk_asd213sadlgajaieo2sa_this_is_s0?}
除此之外还可以考虑动态调试来获取box
先配置一下ida调试所需要的android_server,先打开模拟器
然后在命令行中依次输入以下命令

adb devices
adb push xxx\dbgsrv\android_server /data/local/tmp #ida目录下的dbgsrv中的android_server,路径自行修改
adb push xxx\dbgsrv\android_server64 /data/local/tmp
adb shell
su
cd /data/local/tmp
ls -l
chmod 777 android_server
chmod 777 android_server64
ls -l
./android_server64

img
再新开一个命令行,执行adb forward tcp:23946 tcp:23946转发端口
然后打开DDMS(没有的的请自行安装android sdk
img
以debug模式启动进程

adb shell am start -D -n com.chick.runfaraway/com.chick.runfaraway.MainActivity #包名/包名.入口Activity

提示Waiting for debugger
ida 打开选择Debugger->Attach->Remote ARM Linux/Android debugger
img
sebug option设置和端口设置
img
找到要attach的进程进行attach
img
返回DDMS,查看进程端口
img
恢复java层运行,注意8626是DDMS里查询到的端口号。

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8626

此时就可以开始动态调试了,具体调试过程就不写了

posted @ 2023-10-15 23:49  Tree_24  阅读(294)  评论(0编辑  收藏  举报