FTCF
[简单]Xor
本题考查异或
规则0^0=0 1^0=1 0^1=1 1^1=0
将文件打开得到如下
修改代码得到flag
FCTF{You_Are_Great_Xor_is_Very_Easy}
FlowerDance
本题考查花指令
拖入exe发现是32位
拖入ida,很明显的花指令标志
花指令简单操作
1. Edit>Patch program>change byte
2. 将e8修改为90(nop) 也可以快捷键ctrl+n直接nop
3. nop完可能被认为是数据 需要按c重新识别为代码
4.找到main函数按p(重新识别成代码 创建函数),按空格到主界面,再按f5出现伪c代码
分析函数
写出解密代码
#include<stdio.h>
#include<string.h>
int main()
{
char v7[]={"JunkCode"};
char Buf1[]=
{
'F','k','b','X','X','L',12,'^','$','i','P',
127,100,33,56,112,82,47,62,29,100,
35,125,116,74,96,8,74 };
int j=26;
for (int i = 0; i < 27; ++i )
{
Buf1[i+1]^= v7[j % 8] ^ Buf1[i];
j--;
}
puts(Buf1);
return 0;
}
FCTF{S0-be@ut1fUl-f10weRs}
BUU
内涵的软件
本题考查中文字符串的显示
在ida中可能无法正常显示 需要手动设置编码步骤如下:
1.options>general>strings
2.双击UTF-8,鼠标右键insert
3.在弹出的框中输入gbk,保存确认
4.选中需要修复的字符串,按ALT+A
5.选择C-style,中文字符成功显示
先将文件拖入exe进行查看,后在ida中打开文件xor,点击main函数进入
进入main函数,F5得到伪代码,观察代码
转换成中文字符,R将数字转换成字母,最后得出flag即为{49d3c93df25caad81232130f3d2ebfad}
flag{49d3c93df25caad81232130f3d2ebfad}
新年快乐
本题主要考察脱壳和对upx的使用
先将文件拖入exe进行查看,然后对其进行脱壳处理,并且显示文件为32位
将文件拖入upx文件夹之后打开,脱壳处理为upx -d+文件名,下图表示脱壳成功,成功后拖入ida
strcpy()函数:是将一个字符串复制到另一块空间地址中 的函数,‘\0’是停止拷贝的终止条件,同时也会将 '\0' 也复制到目标空间
分析下面代码,将str2复制到str1,即str2为flag
flag{HappyNewYear!}
xor
本题考查异或
规则0^0=0 1^0=1 0^1=1 1^1=0
在ida中打开文件c,由分析可知,b[i]与b[i-1]做异或后再与global做比较
跟进global得到字符,shift+E提取数据得到十进制形式
写出如下脚本
flag{QianQiuWanDai_YiTongJiangHu}
赣CTF题解
find_flag
本题考查tea加密和fack flag的情况(找main函数之前执行的)
加密过程中:
存在一个delta值,这个值会不停的增加到sum之中,形成一种循环的效果
传入的v0,v1会和传入的key0,key1运算。v1优先参与,并且会有一个位移->与密钥相加->异或的过程。
v0 = 原先的v1值套用公式,v1 = 变化后的v0 套用公式
之前用于计算delta的sum状态值也会参与
由于是一个类似delta状态变化+异或加密的过程,所以整个流程反过来写即可得到解密
原文链接:https://blog.csdn.net/m0_73393932/article/details/130094306
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; //v0,v1分别为字符串的低字节高字节
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i < 32; i++) { //加密32轮
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}
v[0]=v0; v[1]=v1;//加密后再重新赋值
}
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i<32; i++) { //解密时将加密算法的顺序倒过来,还有+=变为-=
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
}
v[0]=v0; v[1]=v1;//解密后再重新赋值
}
int main()
{
uint32_t v[2]={1,2},k[4]={2,2,3,4};
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密前原始数据:%u %u\n",v[0],v[1]);
encrypt(v, k);
printf("加密后的数据:%u %u\n",v[0],v[1]);
decrypt(v, k);
printf("解密后的数据:%u %u\n",v[0],v[1]);
return 0;
}
本题考查tea加密拖入exe发现是64位
编辑观察,每8个字节一组
编辑 跟进sub_401641,这是一个tea加密
将其改为标准tea加密(N修改变量名称)
编辑继续观察 ,提取data,shift+e不够的情况下,按一下*号再shift+e
写出脚本,得到flag{You_found_the_flag!But_is_a_FAKE~}这是一个假的flag
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; //v0,v1分别为字符串的低字节高字节
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i < 32; i++) { //加密32轮
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}
v[0]=v0;
v[1]=v1;//加密后再重新赋值
}
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i<32; i++) { //解密时将加密算法的顺序倒过来,还有+=变为-=
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
}
v[0]=v0;
v[1]=v1;//解密后再重新赋值
}
int main()
{
unsigned int key[4] = { 0x12,0x34,0x56,0x78 };
unsigned char data[] =
{
246, 209, 106, 255, 85, 178, 123, 179, 152, 39,
152, 219, 3, 185, 61, 8, 189, 104, 155, 211,
24, 6, 24, 231, 197, 67, 206, 130, 254, 130,
209, 161, 116, 168, 38, 71, 140, 60, 224, 106
};
for (int i = 0; i < 5; i++)
decrypt((unsigned int*)data + i * 2, key);
puts((char*)data);
return 0;
}
寻找真的flag
找exports,执行顺序在main函数之前,先执行TlsCallback
对input或者data交叉应用
对input按X( 查看交叉引用),发现main函数前面还有一个函数使用了input
跟进,然后进行动态调试
进行动态调试,v4从下标3开始 ,前面三个字节归属right,right占了8个字符,七个打印字符,一个0结束符
跟进函数
发现是tea的魔改,后续还要修复ke有,只传进data,16在二进制是10000,乘16就相当于左移4位
然后跟进data,按*号设置成40位数组,shift+e提取
写出代码得到真的flag
#include <stdio.h>
#include <stdint.h>
//加密函数
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; //v0,v1分别为字符串的低字节高字节
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i < 32; i++) { //加密32轮
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
}
v[0]=v0;
v[1]=v1;//加密后再重新赋值
}
//解密函数
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i<32; i++) { //解密时将加密算法的顺序倒过来,还有+=变为-=
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
}
v[0]=v0;
v[1]=v1;//解密后再重新赋值
}
int main()
{
unsigned int key[4] = { 137,118,84,50 };
unsigned char data[] =
{
107, 121, 31, 159, 120, 115, 175, 228, 213, 223,
252, 114, 224, 255, 87, 74, 7, 186, 114, 22,
230, 123, 5, 170, 142, 31, 23, 158, 79, 62,
21, 221, 89, 158, 7, 65, 221, 120, 117, 128
};
for (int i = 0; i < 5; i++)
decrypt((unsigned int*)data + i * 2, key);
puts((char*)data);
return 0;
}
flag{W0w!You_F1nd_mE!_coNgr@tulAt1ons!}
BrownFox
加密算法
The quick brown fox jumps over the lazy dog!
ihxo{smzdodcikmodcismzd}
解:
背景和案例:
一种 Playfair密码变种加密方法如下:首先选择一个密钥单词(称为 pair)(字母不重复,且都为小写字母),
然后与字母表中其他字母一起填入至一个 5x5的方阵中,填入方法如下:
1.选取一个英文字作密钥。除去重复出现的字母。将密匙的字母逐个逐个加入5×5的矩阵内,(本题没有)剩下的空间将未加入的英文字母依a-z的顺序加入。
(将I和J视作同一字。JOY -> IOY)将要加密的讯息分成两个一组。
2.在每组中,找出两个字母在矩阵中的地方。
3.若两个字母同列,取这两个字母上下方的字母(若字母在最上方则取最下方的字母)。
4.若两个字母同行,取这两个字母左右方的字母(若字母在最左方则取最右方的字母)。
5.若两个字母不同行也不同列,在矩阵中找出另外两个字母,使这四个字母成为一个长方形的四个角(am->ob)。
6.新找到的两个字母就是原本的两个字母加密的结果。
如果密钥为 youandme,则该方阵如下:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
在加密一对字母时,如 am,在方阵中找到以这两个字母为顶点的矩形(红色字体):
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
这对字母的加密字母为该矩形的另一对顶点,如本例中为 ob。
原文链接:https://blog.csdn.net/dongyanwen6036/article/details/76719570
拖入exe发现是64,在拖入ida
按F5进入后,分析main函数首先给data赋值,接收输入后再用to_fox对输入进行加密,加密结果存储到v9数组,再和data数组比较
进入to_fox,按N修改函数名