[NewStarCTF 2023 公开赛道]SMC
下载,ida32位打开
sub_401042函数中发现smc
a = [0x11, 0x22, 0x33, 0x44]
s = 0x403040
for i in range(38):
result = a[i % 4]
patch_byte(s + i, ord(get_bytes(s + i, 1)) ^ result)
通过该脚本复原代码(注意缩进,直接复制到代码没有缩进,怪事)
修改之后依次选中函数,按c和p
分析出新的函数
反编译一下
简单的异或
a = [0x7C, 0x82, 0x75, 0x7B, 0x6F, 0x47, 0x61, 0x57, 0x53, 0x25,
0x47, 0x53, 0x25, 0x84, 0x6A, 0x27, 0x68, 0x27, 0x67, 0x6A,
0x7D, 0x84, 0x7B, 0x35, 0x35, 0x48, 0x25, 0x7B, 0x7E, 0x6A,
0x33, 0x71]
flag = ""
for i in range(len(a)):
flag += chr((a[i] - 5) ^ 0x11)
print(flag)
flag{SMC_1S_1nt3r3sting!!R1ght?}
[NewStarCTF 2023 公开赛道]ELF
拖进ida
输入flag后进行了encode函数加密,再进行base64加密,最后和字符串比较
按照逻辑进行逆向就行
base64结果
a = "V\QWkt $_e'^_ggXQ'u|v!c/m"
b = list(a)
flag = ""
for i in range(len(a)):
flag += chr((ord(b[i]) - 16) ^ 0x20)
print(flag)
flag{D0_4ou_7now_wha7_ELF_1s?}
[NewStarCTF 2023 公开赛道]EzPE
(标准pe文件头)
本题的,修改一下
但是拖进ida还是不行
补充一个知识点,第一个结构体最后的部分指向一个nt头(pe的部分)
在0030的部分最后是90 00 00 00,但是pe在 0080 的位置,这里也要改一下
改完之后就可以拖进ida了
a = [0x0A, 0x0C, 0x04, 0x1F, 0x26, 0x6C, 0x43, 0x2D, 0x3C, 0x0C,
0x54, 0x4C, 0x24, 0x25, 0x11, 0x06, 0x05, 0x3A, 0x7C, 0x51,
0x38, 0x1A, 0x03, 0x0D, 0x01, 0x36, 0x1F, 0x12, 0x26, 0x04,
0x68, 0x5D, 0x3F, 0x2D, 0x37, 0x2A, 0x7D]
for i in range(len(a) - 1, 0, -1):
a[i - 1] = a[i] ^ (i - 1) ^ a[i - 1]
for i in range(len(a)):
print(chr(a[i]), end="")
flag{Y0u_kn0w_what_1s_PE_File_F0rmat}
[NewStarCTF 公开赛赛道]Baby_Re
下载,拖进ida,打开
从下往上看,对输入的flag进行了compare函数操作后提示正确
进行了异或处理,并且可知flag长度为32,点进final数组
提取出来,写脚本解决
flag错误,可以看出来有提示
进入汇编界面,在main函数前发现
可以看出来修改了几个值,对应final数组中标记的几个位置
a = [0x66, 0x6D, 0x63, 0x64, 0x7F, 0x56, 0x36, 0x6A, 0x6D, 0x7D,
0x62, 0x3A, 0x62, 0x6A, 0x51, 0x7D, 0x65, 0x7F, 0x4D, 0x71,
0x71, 0x73, 0x26, 0x65, 0x7D, 0x46, 0x77, 0x7A, 0x75, 0x73,
0x3F, 0x62]
flag = ""
for i in range(len(a)):
flag += chr(a[i] ^ i)
print(flag)
flag{S0meth1ng_run_bef0re_main!}
[NewStarCTF 2023 公开赛道]Segments
下载,elf文件
根据提示shift+f7 打开段
直接提取也可以,但是学了一个脚本
import lief
a = lief.parse(r"E:\b22\shift_f7")
filtered_sections = []
for section in a.sections:
if section.virtual_address >= 0x1000 and section.name != '.dynamic':
filtered_sections.append(section)
sorted_sections = sorted(filtered_sections, key=lambda section: section.virtual_address)
for section in sorted_sections:
print(section.name, end="")
flag{You_ar3_g0od_at_f1nding_ELF_segments_name}
[NewStarCTF 公开赛赛道]Hello_Reverse
打开,
这里就像flag,打开字符串
都提取出来
a = [0x66, 0x6c, 0x61, 0x67, 0x7b, 0x68, 0x33, 0x6c, 0x6c, 0x6f, 0x5f, 0x72, 0x33, 0x76, 0x65, 0x72, 0x73, 0x31, 0x6e,
0x67, 0x5f, 0x77, 0x30, 0x72, 0x6c, 0x64, 0x7d]
flag = ""
for i in range(len(a)):
flag += chr(a[i])
print(flag, end="")
flag{h3llo_r3vers1ng_w0rld}
[BJDCTF 2nd]easy
拖进ida
__main函数进行了初始化,并且调用了一下时间函数,看不出来和flag有关的逻辑,查了一下wp,主要流程在_ques函数里面
打印一个图案
交叉引用发现没有函数调用它
进入主函数的汇编界面
按这个流程改一下,ida动调一下出flag
[NewStarCTF 2023 公开赛道]C?C++?
net文件,ida不好用了,拖进dnspy
// ConsoleApp1.Program
// Token: 0x06000001 RID: 1 RVA: 0x00002050 File Offset: 0x00000250
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;
}
}
找到函数主题,直接写脚本逆向
def reverse_transform(array, num):
text2 = "NEWSTAR"
array2 = [chr(c) for c in array]
# Reverse the second transformation loop
for k in range(6, -1, -1):
array2[k + 28] = chr(ord(array2[k + 28]) - (ord(text2[k]) // 5 + 10))
array2[k + 21] = chr(ord(array2[k + 21]) - (k ^ 2))
array2[k + 14] = chr(ord(array2[k + 14]) - 2 * k)
array2[k + 7] = chr(ord(array2[k + 7]) - (ord(text2[k]) % 5))
array2[k] = chr(ord(array2[k]) - (k ^ (-(ord(text2[k]) % 4))))
# Reverse the first transformation loop
for j in range(num - 1, -1, -1):
array2[j] = chr(ord(array2[j]) + ord(' ') - j)
return ''.join(array2)
def main():
num = 35
array = [
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
]
# Adjust the negative values to the correct unsigned char values
array = [a + 256 if a < 0 else a for a in array]
flag = reverse_transform(array, num)
print("The flag is:", flag)
if __name__ == "__main__":
main()
flag{45dg_ng78_d8b5_1a7d_gh47_kd5b}
[ACTF新生赛2020]fungame
拖进ida
追踪字符串找到加密逻辑
a = [113, 4, 97, 88, 39, 30, 75, 34, 94, 100,
3, 38, 94, 23, 60, 122]
b = [35, 97, 62, 105, 84, 65, 24, 77, 110, 59,
101, 83, 48, 121, 69, 91]
flag = ""
for i in range(len(a)):
flag += chr((a[i] ^ (b[i])))
print(flag)
但是不对
主函数中的下一条函数,设定长度是12,但是flag长度是16,存在栈溢出,对x进行交叉引用
溢出值也就是第二部分是函数名,但是要注意大小端序问题,同时分析函数发现是base64加密
a = [113, 4, 97, 88, 39, 30, 75, 34, 94, 100,
3, 38, 94, 23, 60, 122]
b = [35, 97, 62, 105, 84, 65, 24, 77, 110, 59,
101, 83, 48, 121, 69, 91]
flag = ""
for i in range(len(a)):
flag += chr((a[i] ^ (b[i])))
print('flag{'+flag+chr(0x3d)+chr(0x23)+chr(0x40)+'a1s0_pWn}')
[GFCTF 2021]wordy
拖进ida
这里是利用\xeb\xff来干扰ida分析的
\xeb相当于jmp 8位立即数据,\xff为Table4 reg16
start_addr=0x2D59
end_addr=0x2E3B
flag=''
for i in range(start_addr,end_addr):
if get_wide_byte(i)==0xbf:
flag+=chr(get_wide_byte(i+1))
print(flag)
跑一下这两个代码
[SWPUCTF 2021 新生赛]非常简单的逻辑题
s = 'wesyvbniazxchjko1973652048@$+-&*<>'
result = 'v0b9n1nkajz@j0c4jjo3oi1h1i937b395i5y5e0e$i'
flag_length = len(result) // 2
flag = [''] * flag_length
for i in range(flag_length):
s1_char = result[2 * i]
s2_char = result[2 * i + 1]
s1_index = s.index(s1_char)
s2_index = s.index(s2_char)
s1 = (s1_index - i) % 34
s2 = (-s2_index - i - 1) % 34
while s2 < 0:
s2 += 17
while s2 >= 17:
s2 -= 17
char_val = s1 * 17 + s2
flag[i] = chr(char_val)
flag = ''.join(flag)
print("The flag is:", flag)
[HNCTF 2022 WEEK2]Packet
upx脱下了壳,分析一下发现是bae64变表加密
[GXYCTF 2019]luck_guy
点进关键函数
找到getflag函数
已知flag和f1f2有关系,f1可以直接提取
下面对f2进行了赋值,并进行了操作
搞了半天一直交不上flag,想起来eif文件的大小端序,所以s的内容要反过来写
两部分结合一下就是flag
[NSSRound#V Team]Shatter_Time
下载,运行,看不懂
拖进ida
出题人真滴喜欢main啊
点进去看
有一个随机数
还有一个判断条件,大概是生成随机数判断是否满足条件,运气够好应该可以直接出flag
先看main1
直接爆破出随机数
aa = [
166, 419, 182, 458, 242, 36, 346, 161, 494, 330,
176, 32, 410, 287, 174, 71, 494, 412, 340, 278,
226, 184, 152, 130, 118, 116, 124, 142, 170, 208,
256, 314, 382, 460, 14, 111, 218, 335, 462, 60,
206, 362, 528, 161, 346, 541, 200, 414, 90, 323
]
for x in range(0xFFFFFFFF):
rest = True
for i in range(500, 550):
if x % i != aa[i - 500]:
rest = False
break
if rest:
print(hex(x))
break
0x15019a
下断点,动调
在分叉口,如果进入右边会输出重赛什么什么的,反着跳
flag不对,想起来那个随机数了,
在这里也下一个断点吧(做完发现没有什么用)
跳到这里了,修改eax的值
但是这一步还会改回来,再改一次(所以说断点没有什么用)
接着动调,就出现了flag
[2019红帽杯]Snake
下载,找到
拖进dnspy
引用这里发现了一个非常规的文件(不是unity引擎自带的)
找到,拖进ida
交叉引用,找到
函数,可以看见该函数只调用了一个参数a1
可以看出来a1是一个int类型的0到100的数
写脚本进行爆破
import ctypes
for i in range(0, 100):
dll = ctypes.cdll.LoadLibrary(r"E:\b22\attachment (24)\Snake\Snake_Data\Plugins\Interface.dll")
print(i)
dll.GameObject(i)
[HGAME 2023 week1]encode
下载,拖进ida
字符串找到关键函数
进行了简单加密并且进行了比较,有了加密逻辑就可以进行爆破了
a = [8, 6, 7, 6, 1,
6,
13,
6,
5,
6,
11,
7,
5,
6,
14,
6,
3,
6,
15,
6,
4,
6,
5,
6,
15,
5,
9,
6,
3,
7,
15,
5,
5,
6,
1,
6,
3,
7,
9,
7,
15,
5,
6,
6,
15,
6,
2,
7,
15,
5,
1,
6,
15,
5,
2,
7,
5,
6,
6,
7,
5,
6,
2,
7,
3,
7,
5,
6,
15,
5,
5,
6,
14,
6,
7,
6,
9,
6,
14,
6,
5,
6,
5,
6,
2,
7,
13,
7,
]
for i in range(len(a)):
for j in range(32, 127):
if a[2 * i] == j & 15 and a[2 * i + 1] == (j >> 4) & 15:
print(chr(j),end="")
hgame{encode_is_easy_for_a_reverse_engineer}
[GDOUCTF 2023]Tea
tea加密,
找到加密主体,tea是对称算法,直接写脚本逆向就行
#include<iostream>
using namespace std;
int main() {
unsigned int r = 32;
unsigned int const key[4] = { 2233,4455,6677,8899 };
uint32_t v[10] = { 0x1a800bda,0xf7a6219b,0x491811d8,0xf2013328,0x156c365b,0x3c6eaad8,0x84d4bf28,0xf11a7ee7,0x3313b252,0xdd9fe279 };
int j = 0, n = 0;
for (int j = 8; j >= 0; j--) {
unsigned int i = 0;
unsigned int delta = 256256256, sum = delta * (32 + j);
n = j + 1;
do {
i++;
v[n] -= (((key[(sum >> 11) & 3]) + sum) ^ (((v[j] << 4) ^ (v[j] >> 5)) + v[j]));
v[j] -= (((key[sum & 3] + sum) ^ ((v[n] << 4) ^ (v[n] >> 5)) + v[n]) ^ sum);
sum -= delta;
} while (i <= 0x20);
}
for (int i = 0; i < 10; i++)
{
for (int j = 3; j >= 0; j--)
{
printf("%c", (v[i] >> (j * 8)) & 0xFF);
}
}
return 0;
}
[MoeCTF 2022]Base
base64,点进base64_decode函数
找到这个
获得新表
str1 = "1wX/yRrA4RfR2wj72Qv52x3L5qa="
string1 = "abcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
LitCTF 2024
编码喵
str1 = "tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0="
string1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
hello_upx
64位upx脱壳,工具用不了,只能手嘶
断点找到入口点
两遍f9一次f8找到rsp突变处,内存窗口转到,下断点
f9运行
在4501bc的位置进行了大跳,猜测是函数入口位置
下断点,转到后f7 步入
直接脱
得到scy文件,拖入ida
v6是输入的flag,和v4进行了比较,注意ida大小段序问题,写脚本解密
a = [0x4c, 0x68, 0x72, 0x40, 0x50, 0x41, 0x75, 0x70, 0x2b, 0x63, 0x59, 0x25, 0x61, 0x58, 0x51, 0x65, 0x20, 0x4e, 0x5a,
0x1e, 0x60, 0x4e, 0x5e, 0x4f,101]
for i in range(len(a)):
a[i]=a[i]+i
print(chr(a[i]), end="")
LitCTF{w3lc0me_t0_l1tctf}
[HGAME 2023 week2]before_main
base64,但是常规解决不对,结合题目名字考虑是变表,
进入汇编界面,在main函数之前找到这个函数
变表
hgame{s0meth1ng_run_befOre_m@in}
[AFCTF 2018]凯撒
爆破
b = [108, 113, 110, 127, 113, 134, 110, 60, 63, 126,
126, 116, 110, 106, 110, 108, 112, 64, 108, 125,
136]
flag=""
for i in range(1,17):
for j in range(len(b)):
flag+=chr(b[j-1]-i)
print(flag)
[SWPUCTF 2022 新生赛]贪吃蛇
ida64位打开
第三个函数里有flag关键字
直接动调没有结果
jnz改成jz(75改成74)
在跳转下断点,动调
改zf,f8,双击t_flag,提取数据
[HNCTF 2022 WEEK2]TTTTTTTTTea
直接逆向出脚本(对称算法)
from ctypes import *
import binascii
from Crypto.Util.number import *
def encrypt(v, key):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x61C88647
total = c_uint32(0)
for i in range(32):
v0.value += (((v1.value * 16) ^ (v1.value >> 5)) +
v1.value) ^ (total.value + key[total.value & 3])
total.value += delta
v1.value += (((v0.value * 16) ^ (v0.value >> 5)) +
v0.value) ^ (total.value + key[(total.value >> 11) & 3])
return v0.value, v1.value
def decrypt(v, key):
v0, v1 = c_uint32(v[0]), c_uint32(v[1])
delta = 0x61C88647
total = c_uint32(delta * -32)
for i in range(32):
v1.value -= (((v0.value << 4) ^ (v0.value >> 5)) +
v0.value) ^ (total.value + key[(total.value >> 11) & 3])
total.value += delta
v0.value -= (((v1.value << 4) ^ (v1.value >> 5)) +
v1.value) ^ (total.value + key[total.value & 3])
return v0.value, v1.value
# test
if __name__ == "__main__":
key = [0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F]
res = [0xC11EE75A, 0xA4AD0973, 0xF61C9018,
0x32E37BCD, 0x2DCC1F26, 0x344380CC]
res2 = [0x1, 0x1]
for i in range(0, len(res), 2):
# print(i)
res2 = [0x1, 0x1]
res2[0] = res[i]
res2[1] = res[i + 1]
res22 = decrypt(res2, key)
print(str(long_to_bytes(res22[0])[::-1]) +
str(long_to_bytes(res22[1])[::-1]), end="")
"""
Data is : 0x12345678 0x78563412
Encrypted data is : 0xae685ec7 0x59af4238
Decrypted data is : 0x12345678 0x78563412
"""
[HNCTF 2022 Week1]给阿姨倒一杯Jvav
jadx打开
a=[180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
for i in range(len(a)):
print(chr((a[i]-ord("@"))^32),end="")