NewStarCTF_RE(week1,2)

[NewStarCTF 2023 公开赛道]easy_RE

ida 可能会把 一个数组或字符串拆开,可以通过计算地址,知道是一起的

也有的会藏在汇编窗口

Segments

IDA的Segments窗口 :shift+f7

https://www.cnblogs.com/sch01ar/p/9477697.html

ida 各种窗口也是需要看看

[翻译]The IDA Pro book 第5章---IDA DATA DISPLAY-外文翻译-看雪-安全社区|安全招聘|kanxue.com

Endian

python 复制代码
ant=[1968519710, 2069379587, 1297621516, 2068854845, 1936406553]
key=0x12345678
for i in range(5):
    ant[i]^=key
# for i in range(5):
#     print(str(ant[i]))
#chr((result >> (i * 8)) & 0xFF) 提取每一字节
flag=''
for i in range(5):
    flag+=''.join([chr((ant[i]>>(j*8))&0xff) for j in range(4)])
print(flag)
#flag{llittl_Endian_a

[NewStarCTF 2023 公开赛道]EzPE

这个EXE怎么运行不了呢?

去 010看看

修改后,就是正常 exe文件了。

AndroGenshin

就是一个简单的 RC4+变表base64

烦人的是,rc4工具没解出来,写脚本没有 Crypto 库,只能去虚拟机里运行。0-0

python 复制代码
from Crypto.Cipher import ARC4
arr = [0x7D, 0xEF, 101, 0x97, 77, 0xA3, 0xA3, 110, 58, 230, 0xBA, 206, 84, 84, 0xBD, 0xC1, 30, 0x3F, 104, 0xB2, 130, 0xD3, 0xA4, 94, 75, 16, 0x20, 33, 0xC1, 0xA0, 120, 0x2F, 30, 0x7F, 0x9D, 66, 0xA3, 0xB5, 0xB1, 0x2F, 0, 0xEC, 106, 107, 0x90, 0xE7, 0xFA, 16, 36, 34, 91, 9, 0xBC, 81, 5, 0xF1, 0xEB, 3, 54, 150, 40, 0x77, 202, 150]
arrBytes = bytes(arr)
key = b"genshinimpact"
enc = ARC4.new(key)
base64_table = enc.decrypt(arrBytes)
print(base64_table)

# b'BADCFEHGJILKNMPORQTSVUXWZYbadcfehgjilknmporqtsvuxwzy1032547698/+'
python 复制代码
import base64

str1 = "YnwgY2txbE8TRyQecyE1bE8DZWMkMiRgJW1="
string1 = "BADCFEHGJILKNMPORQTSVUXWZYbadcfehgjilknmporqtsvuxwzy1032547698/+"    #替换的表
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
# str.maketrans(table,result) 创建映射表,将table映射给result
# str1.translate(trans) 用 trans 映射表替换 str1
# b'flag{0h_RC4_w1th_Base64!!}'

[NewStarCTF 2023 公开赛道]C?C++?

		private static void Main(string[] args)
		{
			int num = 35;
			int[] array = new int[]
			{
				68,
				75,
				66,
				72,
				99,
				19,
				19,
				78,
				83,
				74,
				91,
				86,
				35,
				39,
				77,
				85,
				44,
				89,
				47,
				92,
				49,
				88,
				48,
				91,
				88,
				102,
				105,
				51,
				76,
				115,
				-124,
				125,
				79,
				122,
				-103
			};
			char[] array2 = new char[35];
			int[] array3 = new int[35];
			Console.Write("Input your flag: ");
			string text = Console.ReadLine();
			for (int i = 0; i < text.Length; i++)
			{
				array2[i] = text[i];
			}
			string text2 = "NEWSTAR";
			for (int j = 0; j < num; j++)
			{
				char[] array4 = array2;
				int num2 = j;
				array4[num2] += (char)j;
				char[] array5 = array2;
				int num3 = j;
				array5[num3] -= ' ';
			}
			for (int k = 0; k < 7; k++)
			{
				char[] array6 = array2;
				int num4 = k;
				array6[num4] += (char)(k ^ (int)(-(int)(text2[k] % '\u0004')));
				char[] array7 = array2;
				int num5 = k + 7;
				array7[num5] += text2[k] % '\u0005';
				char[] array8 = array2;
				int num6 = k + 14;
				array8[num6] += (char)(2 * k);
				char[] array9 = array2;
				int num7 = k + 21;
				array9[num7] += (char)(k ^ 2);
				char[] array10 = array2;
				int num8 = k + 28;
				array10[num8] += text2[k] / '\u0005' + '\n';
			}
			for (int l = 0; l < num; l++)
			{
				int num9 = (int)array2[l];
				array3[l] = num9;
			}
			for (int m = 0; m < 35; m++)
			{
				bool flag = m == 34 && array3[m] == array[m];
				if (flag)
				{
					Console.WriteLine("Right!");
				}
				bool flag2 = array3[m] == array[m];
				if (!flag2)
				{
					Console.WriteLine("Wrong!");
					break;
				}
			}
		}
	}
}

最开始看,觉得只要满足最后条件就行了,但发现不是,应该是要最后的,也不是每一个arrayX

都对应一步操作,要逆所有的操作

python 复制代码
v6 = 35
j = 0
v10 = [68,75,66,72,99,19,19,78,83,74,91,86,35,39,77,85,44,89,47,92,49,88,48,91,88,102,105,51,76,115,-124,125,79,122,-103]
a2 = "NEWSTAR"
for j in range(7):
    v10[j + 28] -= (ord(a2[j])//5) + 10
    v10[j + 21] -= j ^ 2
    v10[j + 14] -= 2 * j
    v10[j + 7] -= ord(a2[j]) % 5
    v10[j] -= j ^ -(ord(a2[j]) % 4)
for i in range(v6):
    v10[i] -= i
    v10[i] += 32
    print(chr(v10[i]%256), end='')

R4ndom

一个 elf 文件,42位flag,一开始打算直接动调,但想想觉得工程有点大,要42次。并且去动调的时候,发现有反调试。先想想怎么调试:

在 main 函数开头下断点,看反调试在 main 前/后;一般就是在 init_array 里。

想到ctf一般都是伪随机,去看看有没有随机数种子。

由于设置了随机数种子,所以每次rand()的结果都是一样的,这就是伪随机

一个反调试( ptrace),一个随机数种子

要用标准整数型,要引用库

#include <cstdint>

uint8_t enc;

python 复制代码
#include <iostream>
#include <cstdint>
using namespace std;
int main() {
	/*int enc[6];
	enc[0] = 0x3513AB8AB2D7E6EELL;
	enc[1] = 0x2EEDBA9CB9C97B02LL;
	enc[2] = 0x16E4F8C8EEFA4FBDLL;
	enc[3] = 0x383014F4983B6382LL;
	enc[4] = 0xEA32360C3D843607LL;
	enc[5] = 42581LL;*/
	__uint8_t enc[42] = { 0xEE, 0xE6, 0xD7, 0xB2, 0x8A, 0xAB, 0x13, 0x35, 0x02, 0x7B, 0xC9, 0xB9, 0x9C, 0xBA, 0xED, 0x2E,
						0xBD, 0x4F, 0xFA, 0xEE, 0xC8, 0xF8, 0xE4, 0x16, 0x82, 0x63, 0x3B, 0x98, 0xF4, 0x14, 0x30, 0x38,
						0x07, 0x36, 0x84, 0x3D, 0x0C, 0x36, 0x32, 0xEA, 0x55, 0xA6 };
	
	unsigned char Table[] =
	{
	  0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01,
	  0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D,
	  0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4,
	  0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
	  0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7,
	  0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
	  0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E,
	  0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
	  0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB,
	  0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB,
	  0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C,
	  0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
	  0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C,
	  0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
	  0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
	  0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
	  0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3,
	  0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
	  0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A,
	  0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
	  0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E,
	  0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
	  0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9,
	  0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
	  0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99,
	  0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
	};
	/*for (i = 0; i < strlen(input); ++i)
	{
		v3 = input[i];
		v4 = rand();
		input[i] = Table[(16 * ((v3 + v4 % 255) >> 4) + 15) & (v3 + v4 % 255)];
	}*/
	srand(0x5377654Eu);
	for (int i = 0; i < 42; ++i) {
		for (int j = 0; j < 256; ++j) {
			if (Table[j] == enc[i]) {
				printf("%c", (j - rand() % 255));
			}
		}
	}

	return 0;
}

easy_enc

第一个,类似凯撒加密

第二个,通过Key相加

第三个,按位取反

第四个,相乘

可能溢出

C 的代码都有编译器的默认类型推断影响,就是可能有(隐式)转换

可以定义 uint8_t ,或者自己去截断。

因为 input 是 char 类型,*52可能会溢出,故第四个不能逆,就只能爆破了。

python 复制代码
#include <stdio.h>
#include <string.h>
#include <cstdint>
// 感觉比 C++好一些
int main()
{
    uint8_t enc[100] = { 0xE8, 0x80, 0x84, 0x8, 0x18, 0x3C, 0x78, 0x68, 0x0, 0x70, 0x7C, 0x94, 0xC8, 0xE0, 0x10, 0xEC, 0xB4, 0xAC, 0x68, 0xA8, 0xC, 0x1C, 0x90, 0xCC, 0x54, 0x3C, 0x14, 0xDC, 0x30 };
    char key[20] = "NewStarCTF";
    int len = strlen(key);
    uint8_t i, j;
    //必须是 uint8_t 限定类型
    for (i = 0; i < 29; i++) {
        for (j = 32; j < 127; j++) {
            uint8_t tmp = j;
            //这里也是。
            if (j < 'A' || j > 'Z')
            {
                if (j < '0' ||j > '9')
                {
                    if (j >= 'a' && j <= 'z')
                        j = (j- 89) % 26 + 97;
                }
                else
                {
                    j = (j - 45) % 10 + 48;
                }
            }
            else
            {
                j = (j - 52) % 26 + 65;
            }
            j += key[i % len];
            j = ~j;
            j *= 52;
            if (j == enc[i]) {
                if ((tmp <= 'Z' && tmp >= 'A') || (tmp <= 'z' && tmp >= 'a')) {
                    printf("%c",tmp);
                }
            }
            j = tmp;
        }
    }
    return 0;
}

这么简单一个脚本,却也花了一段时间,唉!

Petals

不对,就是那个 call E8 不对,

就是下标匹配的问题

python 复制代码
enc = [0xD0, 0xD0, 0x85, 0x85, 0x80, 0x80, 0xC5, 0x8A, 0x93, 0x89,
       0x92, 0x8F, 0x87, 0x88, 0x9F, 0x8F, 0xC5, 0x84, 0xD6, 0xD1,
       0xD2, 0x82, 0xD3, 0xDE, 0x87]
longth = 25
#enc = list(map(chr, enc))
v5 = []
for i in range(256):
    v5.append(~(i ^ longth) & 0xff)

# 遍历 enc 并打印对应的索引
for i in range(longth):
    #print(enc[i])
    if enc[i] in v5:
        tmp = v5.index(enc[i])
        print(chr(tmp),end='')
    else:
        print(f"Value {enc[i]} not found in v5")

特别注意:

for 操作明确是 byte ,要 &0xff

还有就是 index()的使用

PZthon

解包,发现 python 版本是 3.8

uncompyle6只支持到py3.8

用 pycdc 或者 在线网站

代码很简单,直接秒了

AndroDbgme

放 jadx 没有什么发现,看题目名字应该是要调试

没有什么反应。

想直接在模拟器里加调试功能,结果不行,MT 有点问题

不对,最后用 MT 搞出来了,修改完 xml 文件后,保存,直接重安装。

不过这个一调试,直接就出 flag ,想知道为什么。

lazy_activtiy

要么是 data或者其他目录下藏着一个 apk 文件

或者就是存在文件里面哪里。

嗯,jeb 不好看,主要用来调试吧,还是喜欢用 jadx

不过 jeb 有一些注释还不错

两个结合用吧

嗯,这个题可以动调,也可以直接去找 editText

emmm但在我尝试动调前,AndroidKiller一把梭了

有点问题

去找一下算了

找到了。

相关推荐
XiaoLeisj38 分钟前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师2 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
逐·風2 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
捕鲸叉2 小时前
创建线程时传递参数给线程
开发语言·c++·算法
Devil枫2 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
A charmer2 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq2 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
尚梦3 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子3 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
记录成长java4 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet