[NewStarCTF2023]Week3
NewStarctf2023_Week3_Offical
Reverse
花
去花
按c强制生成代码
第二处
第三处
在0x00401500处按P生成函数
主函数,RC4加密,key是WOWOWOWWOWOWOW
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++逆向,大致能读懂相关函数
直接爆破,脚本跑得有点慢,大致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
主程序中分析
key是
看看dll中的encrypt,是魔改过的xtea,注意魔改的地方
然后写脚本解,结果发现已知解不出来
倒回去重新分析主程序发现在TLS中加入了反调试,并且修改了xtea的key
计算一下真正的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的问题
在反编译python生成可执行文件exe时,引用的类库文件经常遇到使用Crypto模块AES算法加密,解包生成的并不是pyc文件,而是加密的pyc.encrypted文件,它无法查看编译。
第一步,获取Crypto的key,这是打包时由开发者指定的。解包完成后将在根目录形成名为 pyimod00_crypto_key.pyc 的文件,将它转为py文件即可查看key文件。
第二步,编写解密处理的脚本代码
我们先获取key = '00000000new1star'
然后用脚本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
源代码不难理解,主要是changefun2,让GPT解释一下
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
接着看main_main
动调看看iv是什么
iv是和key一样,但是记得异或0x32
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
主函数分析如下
再看看sub_401170,明显xtea,多了个异或
动调获取key
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
解包之后查看librunfaraway.so
的encode函数
先看看最后的check,最后的结果经过test后与
6DTNDRc1uJyyyd/GrT+bW3NNIoXzPQyK722kicTTFTTySTzyRE+BWdXnW6zF7UY9iUZK27QN
比较
查看test,应该是base64
往前看,对v22赋完值(0~0xff)后,进行了_ROL2_移位
_ROL2_是ida内置函数,在ida/plugins/defs.h中可以查看到定义
再看看_ROL_函数
有两个参数:(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;
}
之后的加密逻辑其实就是和传进来的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
再新开一个命令行,执行adb forward tcp:23946 tcp:23946
转发端口
然后打开DDMS
(没有的的请自行安装android sdk)
以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
sebug option设置和端口设置
找到要attach的进程进行attach
返回DDMS,查看进程端口
恢复java层运行,注意8626是DDMS里查询到的端口号。
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8626
此时就可以开始动态调试了,具体调试过程就不写了
本文来自博客园,作者:{Tree_24},转载请注明原文链接:{https://www.cnblogs.com/Tree-24/}