一.reverse
1.签到
需要以管理员身份运行,给出了密文,之后可以看到凯撒加密和换位的循环,写代码解决
#include<stdio.h>
int main(){
char a1[]="}xr1w_1RvI_r_31_31yK{xrcw"; //26
char a2[26];
int i,j;
char v3;
for ( i = 0; i < 26; ++i ) // 大小写
{
if ( a1[i] <= 96 || a1[i] > 122 )
{
if ( a1[i] <= 64 || a1[i] > 90 )
a2[i] = a1[i];
else
a2[i] = (a1[i] - 65 - 17 + 26) % 26 + 65;//-48=-65+17
}
else
{
a2[i] = (a1[i] -97 -17 +26) % 26 + 97;//-80=-97+17
}
}
//puts(a2);
//0 25
//1 24
for ( j = 0; 13 > j; ++j )
{
v3 = a2[j];
a2[j] = a2[26 - 1 - j];
a2[26 - 1 - j] = v3;
}
for(i=0;i<26;i++){
printf("%c",a2[i]);
}
//flag{Th13_13_a_ReA1_f1ag}
}
2.茶
查壳是16位,没思路,pe查壳,看到和一般exe文件差好多东西,找正常exe文件,把text前面的都改了
之后查壳就是64位的 ,进入ida查看逻辑:
分析得到有一个xxtea加密,让后有一个字符串转整数数组的函数,直接写代码得到,
注意xxtea的密钥是整数类型
#include <stdio.h>
#include <stdint.h>
#define DELTA 0x9e3779b9
#define MX (((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z)))
void btea(uint32_t *v, int n, int key[4]) // 将 key 的类型改为 int
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52 / n;
sum = 0;
z = v[n - 1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
{
y = v[p + 1];
z = v[p] += MX;
}
y = v[0];
z = v[n - 1] += MX;
} while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52 / n;
sum = rounds * DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
{
z = v[p - 1];
y = v[p] -= MX;
}
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}
}
int main()
{
int k[4] = {103, 48, 48, 100}; // 将 key 的类型改为 int
uint32_t v[6] = {
0x6928F0E9, 0xD717C054, 0x38E7072, 0xF47ED5D7, 0xFBDA4305, 0x49C394C8
};
btea(v, -6, k); // 注意这里的 n 应该是 -6,因为我们要解码 6 个 uint32_t
for (int i = 0; i < 6; i++)
{
printf("0X%08X,", v[i]);
}
//0X67616C66,0X7032687B,0X665F7970,0X375F6E75,0X54435F6F,0X00007D46,
return 0;
}
让后知道flag的16进制是0x66 0x6C 0x61 0x67,看到输出是这样的,所以写代码解决
#include <stdio.h >
int main() {
int a[]={0X67616C66,0X7032687B,0X665F7970,
0X375F6E75,0X54435F6F,0X00007D46,};
for (int i=0;i<6;i++){
for (int j=0;j<4;j++){
printf("%c",a[i]%256);
a[i]/=256;
}
}
//flag{h2ppy_fun_7o_CTF}
}
3.eazyre
查壳是VMP壳非常的麻烦,之后运行程序看到
以管理员身份运行
需要查看控件,有mfc逆向,学习一下
在这里找到flag和key,使用xspy
得到了窗口句柄HWND:flag
00640CE4(944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b)
同样的这里有特殊的onMsg是自定义消息,是传入数字0464,来触发效果的
写代码解决
#include<Windows.h>
#include<stdio.h>
int main()
{
//如果参数NULL,则忽略此参数
//窗口类的名称,窗口的标题
HWND h = FindWindowA("944c8d100f82f0c18b682f63e4dbaa207a2f1e72581c2f1b", "Flag就在控件里");
if (h)
{
SendMessage(h, 0x464, NULL, NULL);
//窗口程序将接收消息的窗口的句柄
//将被发送的消息。
//指定附加的消息信息。
//指定附加的消息信息
getchar();
}
return 0;
}
此时窗口变成了
有密文和密钥找网站解决
得到flag{thIs_Is_real_kEy_hahaaa}
4.ezreee
题目带一个j__CheckForDebuggerJustMyCode 不用管,是启用自己编写的代码的,不影响分析代码
ida进入之后可以看到有
1.flag长22
2.交换相邻字符
3.rc4加密可以看到有异或3,是魔改的,key可以查看到
也是写代码解决了
#include <stdio.h>
#include <string.h>
unsigned char sbox[256] = {0};
const unsigned char* key = (const unsigned char*)"welcome";
unsigned char data[] = {
0x09, 0xD6, 0x3D, 0x91, 0x88, 0x77, 0xCF, 0xAE, 0x4B, 0xB5,
0x5D, 0xC8, 0x43, 0xB9, 0xB4, 0xA1, 0x88, 0x58, 0x0C, 0x05,
0xC3, 0x77
};
void swap(unsigned char* a, unsigned char* b) {
unsigned char tmp = *a;
*a = *b;
*b = tmp;
}
void init_sbox(const unsigned char key[]) {
for (unsigned int i = 0; i < 256; i++) sbox[i] = i;
unsigned int keyLen = strlen((const char*)key);
unsigned char Ttable[256] = {0};
for (int i = 0; i < 256; i++) Ttable[i] = key[i % keyLen];
for (int j = 0, i = 0; i < 256; i++) {
j = (j + sbox[i] + Ttable[i]) % 256;
swap(&sbox[i], &sbox[j]);
}
}
void RC4(unsigned char* data, unsigned int dataLen, const unsigned char key[]) {
unsigned char k, i = 0, j = 0, t;
init_sbox(key);
for (unsigned int h = 0; h < dataLen; h++) {
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swap(&sbox[i], &sbox[j]);
t = (sbox[i] + sbox[j]) % 256;
k = sbox[t];
data[h] ^= k^3;//异或3
}
}
int main(void) {
unsigned int dataLen = sizeof(data) / sizeof(data[0]);
RC4(data, dataLen, key);
for (unsigned int i = 0; i < dataLen; i++) {
printf("%c", data[i]);
}
return 0;
}
#include<stdio.h>
int main(){
char flag[22];
//0123456789012345678912
//相邻的一交换
//rc4
char data[] =
{
0x09, 0xD6, 0x3D, 0x91, 0x88, 0x77, 0xCF, 0xAE, 0x4B, 0xB5,
0x5D, 0xC8, 0x43, 0xB9, 0xB4, 0xA1, 0x88, 0x58, 0x0C, 0x05,
0xC3, 0x77
};
char text[]="lfga!{hTsIi__SlFGa!!}!";
char k;
int i;
for ( i = 0; i < 22; i += 2 )
{
k = text[i];
text[i] = text[i + 1];
text[i + 1] = k;
}
puts(text);
}
//flag{!ThIs_iS_FlaG!!!}
5.ezre
查壳是64位upx没有修改pe文件,直接脱壳
进入ida,F12查看到有success进入,自己分析分析代码,修改一下函数名称啥的,最后得到逻辑
密文base64加密一下,之后改变一下base64表,让后再加密一下,反着改一下就行了
之后base变表加密找工具解决
#include<stdio.h>
int main(){
char s1[]="ABCQIJ1234PnopRSTUVWXYbcdefZaFGHqrsghijklKLMNOyz0mDEtuvwx56789+/";
char s2[100];
int j;
for ( j = 0; j < 64; ++j )
s2[j] = s1[(j + 32) % 64];
puts(s2);//qrsghijklKLMNOyz0mDEtuvwx56789+/ABCQIJ1234PnopRSTUVWXYbcdefZaFGH
char enc[]="5v4p81ucEWOJvjYyucteu1uQ5t4x6cr4NbOXz0==";
//ejmrewO3eXmNWu9VeceJXkpi3ct=
//flag{HeLlO_RevERse!}
}
二.crypto
1.签到
根据题干:
有2位32岁的贝斯手正在修理栅栏,在听说河北师范大学要举办2025年的新生杯后,特地过来给新生们出了一道题,并拿着一张什么表对我说,新生们肯定想不到,这张表已经被我换过了:YTNMETXXY2JMUDXWW3NMZPVEQCTL5TU7YQTK5SF76SIIAXH3,你知道flag是什么吗?
有base32加密,让后有一个2,有栅栏,有一串数据,因为base32编码表长度必须是32位,而这一串数据长度是48,所以编码表应该是在原基础的上面改变的,而这一串数据是密文
原编码表栅栏加密2位,之后base32得到答案
flag{cheGk_ln_B@s_e_b2_&_zH@n}
2.方程组
问ai出了
import math
from sympy import isprime
def fermat_factorization(n):
# 从 ceil(sqrt(n)) 开始
a = math.isqrt(n) + 1
while True:
b2 = a * a - n
if b2 >= 0:
b = math.isqrt(b2)
if b * b == b2:
p = a - b
q = a + b
return p, q
a += 1
n = 172997839026008090731214685110288930926554268384610580884446052632058451872308461738005002543140093831336981845282841921393298753609141144247199379682893588657385154114243565522800365531564269794597306928138621498863498866313637343164190168911398049247069119516060276473462718571056646024605610289922922245757
p, q = fermat_factorization(n)
print("p =", p)
print("q =", q)
from Crypto.Util.number import long_to_bytes
p = 13152864289804258857413344850811495815429166408430336176160221444136703484044405746648842440054562763279693159128710845652439561717887733078268852844425177
q = 13152864289804258857413344850811495815429166408430336176160221444136703484044405746648842440054562763279693159128710845652439561717887733078268852844425541
c = 91950090419027697889027398458199624452528482939055058355665878556469594830215031998535600304085530927643278735776530093262200384337226361626323072988361276887537447747590285027636735526279811489664683774328788756295398152173955955572407760974395253413063944193118452824816336218454697930960077601937051696314
n = 172997839026008090731214685110288930926554268384610580884446052632058451872308461738005002543140093831336981845282841921393298753609141144247199379682893588657385154114243565522800365531564269794597306928138621498863498866313637343164190168911398049247069119516060276473462718571056646024605610289922922245757
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, x, y = egcd(b % a, a)
return (g, y - (b // a) * x, x)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('Modular inverse does not exist')
else:
return x % m
e = 65537
phi = (p - 1) * (q - 1)
d = modinv(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print("flag =", flag.decode())
flag = flag{CAN_y0u_b&@t_xSs?}
三.WEB
1.源码在哪里
进入网站,不能右键,也不能f12查看源码
直接找解决办法:在网站前面添加这一数据
view-source:154.64.254.169:32899
让后就看到了源码,一看就是flag{格式}
跑一下
flag{we1come_t0_this_game!_enj0y}
四.MISC
1.签到
仁济
2.music
猜测是最后的和开始的重复了所以有%,所以直接拼出来
PR@CTICE_L0VE
然后不对,小写也不对,最后是有一个"0"所以结果是falg{pr@ctice_l0ve}