[HNCTF 2022 WEEK2]Try2Bebug_Plus
静态分析
64位ELF,ida打开
主函数
decrypt函数,为tea加密,v ,k 已知
tea加密解密函数(C语言)
#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;
uint32_t delta=0x9e3779b9;
uint32_t k0=k[0],k1=k[1],k2=k[2],k3=k[3];
for(i=0;i<32;i++){
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; //这里的sum是0x9e3779b9*32后截取32位的结果,截取很重要。
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};
printf("加密前的数据:%u %u\n",v[0],v[1]); //%u 以十进制形式输出无符号整数
encrypt(v,k);
printf("加密后数据:%u %u\n",v[0],v[1]);
decrypt(v,k);
printf("解密后数据:%u %u\n",v[0],v[1]);
return 0;
}
function函数
根据以上写脚本即可,不用逆向,直接写
#include <stdio.h>
#include <stdint.h>
#include<string.h>
void decrypt(unsigned int *v, int *a2)
{
unsigned int v0; // [rsp+1Ch] [rbp-24h]
unsigned int v1; // [rsp+20h] [rbp-20h]
unsigned int sum; // [rsp+24h] [rbp-1Ch]
unsigned int i; // [rsp+28h] [rbp-18h]
v0 = *v;
v1 = v[1];
sum = 0xC6EF3720;
for ( i = 0; i <= 31; ++i )
{
v1 -= (v0 + sum) ^ (16 * v0 + a2[2]) ^ ((v0 >> 5) + a2[3]);
v0 -= (v1 + sum) ^ (16 * v1 + *a2) ^ ((v1 >> 5) + a2[1]);
sum += 0x61C88647;
}
*v = v0;
v[1] = v1;
}
int main()
{
unsigned int v[12]={0x489A0BFD, 0x38DE3838, 0x16D1DA51, 0x710510ED, 0x1E619392, 0x0B487955, 0x0AB44987, 0x5DB378E5, 0x9F9DA4CD,0x49F2D9A8, 0x608F269E, 0x6261B831};
int k[4]={0xAA, 0xBB, 0xCC, 0xDD};
unsigned char v3[12];
int i;
for ( i = 0; i <= 11; i=i + 2 )
decrypt(&v[i], k);
for ( i = 0; i <= 11; ++i )
{
v3[i] = (16 * i) ^ v[i];//v是整型,占四个字节
printf("%c",v3[i]);
}
//th1s_1s_flag
return 0;
}
动态调试-learn
[HNCTF 2022 WEEK4]ez_maze
python 逆向
打开maze.pyc在生成的文件夹下面
添加前面的字节码
打开winhex--编辑--粘贴0字节--11,修改前面的部分即可
观察发现python3.9版本的,找在线网站转成py
崩溃啦...
[HNCTF 2022 WEEK3]What's 1n DLL?
题目提示有壳,给了两个文件
改一下特征值,但是中间有一段全是0,有点奇怪
然后脱壳
DDL里面看ttt函数,看出来应该是xxtea加密
看task函数
enc dd 22A577C1h, 1C12C03h, 0C74C3EBDh, 0A9D03C85h, 0ADB8FFB3h
这里用 LoadLibrary 加载了一个名为Dll1.dll的动态链接库,这个函数会返回一个模块的句柄hModule。之后用 GetProcAddress函数来获取DLL中某个导出函数的地址,在这里就是,加载Dll1.dll,来获取其中名为ttt的函数地址,之后将其保存在ProcAddress变量中。
因此我们直接去逆Dll1.dll就好。
LoadLibrary 函数
[格式]:function LoadLibrary(LibFileName : PChar): Thandle;
[功能]:加载由参数 LibFileName 指定的 DLL 文件。[说明]:参数 LibFileName 指定了要装载的 DLL 文件名,如果 LibFileName 没有包含一个路径,系统将按照:当前目录、Windows 目录、Windows 系统目录、包含当前任务可执行文件的目录、列在 PATH 环境变量中的目录等顺序查找文件。
如果函数操作成功,将返回装载 DLL 库模块的实例句柄,否则,将返回一个错误代码,错误代码的定义如引文[1]所示。
GetProcAddress 函数
[格式]:function GetProcAddress(Module:Thandle; ProcName:PChar): TfarProc;
[功能]:返回参数 Module 指定的模块中,由参数 ProcName 指定的过程或函数的入口地址。[说明]:参数 Module 包含被调用函数的 DLL 句柄,这个值由 LoadLibrary 返回, ProcName
是指向含有函数名的以 nil 结尾的字符串指针,或者可以是函数的次序值,但大多数情况下,用函数名是一种更稳妥的选择。如果该函数执行成功,则返回 DLL 中由参数 ProcName 指定的过程或函数的入口地址,否则返回 nil
exp
#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)))
#define uint32_t unsigned int
void btea(uint32_t *v, int n, uint32_t const key[4])
{
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()
{
uint32_t v[]= {0x22A577C1, 0x1C12C03, 0x0C74C3EBD,0x0A9D03C85, 0x0ADB8FFB3};
uint32_t const k[4]= {55,66,77,88};
int n= 5; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
// printf("加密前原始数据:%u %u\n",v[0],v[1]);
// btea(v, n, k);
// printf("加密后的数据:%u %u\n",v[0],v[1]);
btea(v, -n, k);
printf("解密后的数据:");
char *p=(char *) v;
for(int i=0;i<20;i++){
printf("%c",*p);
p++;}
return 0;
}
xxtea找个脚本解密
#include <stdbool.h>
#include <stdio.h>
#define MX ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))
bool btea(unsigned int* v, int n, unsigned int* k) {
unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x9e3779b9;
unsigned int p, q;
if (n > 1) { /* Coding Part */
q = 6 + 52 / n;
while (q-- > 0) {
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;
}
return 0;
} else if (n < -1) { /* Decoding Part */
n = -n;
q = 6 + 52 / n;
sum = q * DELTA;
while (sum != 0) {
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;
}
return 0;
}
return 1;
}
int main(int argc, char const* argv[]) {
unsigned int v[5] = {0x22a577c1,0x1c12c03,0xc74c3ebd,0xa9d03c85,0xadb8ffb3}, key[4] = {55,66,77,88};
int n = 5; //n为要加密的数据个数
btea(v, -n, key); // 取正为加密,取负为解密
char *p=(char *) v;
for(int i=0;i<20;i++){
printf("%c",*p);
p++;
}
return 0;
}
// NSSCTF{He110_w0r1d!}