哇 我真的好菜啊 最近心态爆炸了 然后 我这种 密码学不好的人 我本来想自己用C语言实现 但是考试临近 就没有办法了
因为密码学不好的我 导致我现在关于密码学的题就会有点不自信 所以 想等暑假实习回来就把网络编程 然后 因为 某个ctf里面的 xtea 还有crc16 我没有看出来 我想练一下xtea的题目 然后,,,,
就遇到了这个题
先看一下 ida 里面的 xtea
https://blog.csdn.net/gsls200808/article/details/48243019
发现 这里的sum+= 被优化成 -= 然后 其它也大同小异
然后我太过认为这个xtea 是标准的xtea 用了网站 还有python 发现都不行
然后自己心态就崩了
后来一个南邮的大佬学弟和我说是 有所变化的 需要自己实现
晕,,, 还是自己太菜了
反其道实现就可以了
#include <stdio.h>
#include <stdint.h>
typedef unsigned char uint8;
#define _BYTE uint8
#define LOBYTE(x) (*((_BYTE*)&(x)))
void decrypt(int a1, int a2, _BYTE *input, int key)
{
int sum; // eax
char *result; // eax
sum = (int)input;
LOBYTE(a2) = *input;
LOBYTE(a1) = input[1];
LOBYTE(sum) = 0xD9u;
do
{
sum += 71;
a1 -= (sum + *(unsigned __int8 *)(key + (((char)sum >> 11) & 3))) ^ (a2 + (16 * (char)a2 ^ ((char)a2 >> 5)));
a2 -= (a1 + (((char)a1 >> 5) ^ 16 * (char)a1)) ^ (sum + *(unsigned __int8 *)(key + (sum & 3)));
}
while ( (_BYTE)sum != 0xB9u );
result = (char *)input;
*input = a2;
input[1] = a1;
printf("%c%c",input[0],input[1]);
}
int main()
{
unsigned char key[]={0xde,0xad,0xbe,0xef};
unsigned char a[]={0xBF, 0xF1, 0x6A, 0x2C, 0x10, 0x0B, 0x16, 0x59, 0xBA, 0x3A,
0x8C, 0x49, 0x05, 0x1B, 0x04, 0xE2, 0x85, 0xD5, 0xC2, 0xFC,
0xD7, 0x9B, 0xE9, 0x42};
int i;
int v3=0,v4=0;
for(i=0;i<24;i+=2)
{
decrypt(v4, v3, a+i, (int)key);
}
return 0;
}
然后这个题目看起来就结束了 但是后来想了想 可以完全导出 dll函数 然后可以实现调试dll函数功能
说干就干 然后这个题目给了 符号表 完全可以 直接用符号导出
如果没有的话 也可以 句柄加偏移
#include <iostream>
#include <Windows.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<time.h>
#include<queue>
typedef int(*encrypt_str)(char*, int, int*);
typedef int(*get_string)();
encrypt_str encrypt_strs = NULL;
get_string get_strings = NULL;
char input[50];
int key = 0xEFBEADDE;
unsigned char strs[] = { 0xBF, 0xF1, 0x6A, 0x2C, 0x10, 0x0B, 0x16, 0x59, 0xBA, 0x3A,
0x8C, 0x49, 0x05, 0x1B, 0x04, 0xE2, 0x85, 0xD5, 0xC2, 0xFC,
0xD7, 0x9B, 0xE9, 0x42 };
HMODULE hdll = NULL;
int main()
{
hdll = ::LoadLibrary(TEXT("C:\\Users\\Lenovo\\Desktop\\CTF\\ctf3.dll"));
if(hdll==NULL)
{
printf("dll加载失败!\n");
::FreeLibrary(hdll);
}
else
{
printf("%0x\n", hdll);
//encrypt_strs=(encrypt_str)((int)hdll + 0x127C)
encrypt_strs = (encrypt_str)GetProcAddress(hdll, "encrypt_str");
get_strings = (get_string)::GetProcAddress(hdll, "get_string");
if(get_strings==NULL)
{
printf("调用get_string函数失败!\n");
}
else
{
get_strings();
printf("成功!\n");
}
if(encrypt_strs==NULL)
{
printf("加载运行函数失败!\n");
::FreeLibrary(hdll);
free(encrypt_strs);
}
else
{
scanf("%s", input);
encrypt_strs(input, strlen(input)+1, &key);
printf("%s\n", input);
}
}
}
然后就可以用od 调试这个函数了
虽然 od也可以直接拉近dll 但是总感觉没有这样写好 这样自己实现也方便
直接拉的话 dll 输入都没有办法输入~~~~
HighwayHash64
这个题目和上面差不多 但是唯一的一点就是这个是exe
然后百度了一波
参考链接的操作是 exe 改成dll 需要修改两处
- IMAGE_FILE_HEADER->Characteristics(文件属性)->2102h(DLL文件一般是2102h)
- IMAGE_OPTIONAL_HEADER->AddressOfEntryPoint(程序执行入口RVA)->0000h
改成
02 21
rva
改成 0 0
然后后缀改成dll
然后用x64的程序打开 就可以加载函数 然后进行爆破了
代码就是参考链接的小小改动 = = 用x64编译,,, 原谅我的小小懒惰,,,,
#include "pch.h"
#include<Windows.h>
#include <cstdio>
typedef __int64(__fastcall *f)(__int64 buff, unsigned __int64 len);
int main()
{
HINSTANCE hdll;
hdll = LoadLibrary(TEXT("reverse.dll"));
if (hdll == NULL)
{
printf("Load dll Error: %d\n", GetLastError());
return 0;
}
printf("Dll base is %llx\n", hdll);
f func = ((f)((char*)hdll + 0x17A0));
int i;
unsigned long long result;
for (i = 0; i < 50; i++)
{
result = func((long long)&i, 4);
if (result == 0xD31580A28DD8E6C4)
{
printf("Len is %d\n", i - 9);
}
}
unsigned long long j;
unsigned long long result2;
char buff[20];
for (j = 0; j < 10000000000; j++)
{
sprintf_s(buff, "%0.10llu", j);
result2 = func((long long)buff, 10);
if (result2 == 0xE3BE26AF8730545A)
{
printf("flag is %lld\n", j);
system("pause");
system("pause");
return 0;
}
}
return 0;
}
参考链接
https://blog.csdn.net/charlesgodx/article/details/86762347