暑假第七周
[湖湘杯2018]HighwayHash64
HighwayHash是是伪随机的 函数(即键控散列函数)优化了速度 信息,由Jyrki Alakuijala、Bill Cox和Jan Wassenberg设计 谷歌研究
我看有大佬WP是通过导入HighwayHash-cffi包用python来爆破的
但我没安装成功,贴个博客地址
先运行看看回显

ida打开查看主函数有两处check

法一
两处check的retcode都是1,可以把第二处修改为2,爆破第一处check得到长度
第二处check地址为1400019D6

010edit修改

写个bat爆破长度
@echo off
:next
reverse.exe
if %ERRORLEVEL% EQU 2 echo !!!!!get_len!!!!! & goto next
if %ERRORLEVEL% EQU 1 echo again & goto next
if %ERRORLEVEL% EQU 0 echo ############ & goto next
可以得到flag长度为19,除去hxb2018{}中间数字有10位

对照github上HighwayHash源码分析sub_1400017A0函数

其中HighwayHashReset是修改过的

将下载下来的源码highwayhash.c里的HighwayHashReset修改

可以通过第一个check验证一下我们的修改是否正确

#include "highwayhash.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
const uint64_t key[4]={0};
uint8_t data[11] = {19};
printf("%llx",HighwayHash64(data, 4, key));
return 0;
}
结果正确,说明我们的修改是符合题目所给的,那我们就可以爆破了

exp
#include "highwayhash.h"
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
const uint64_t key[4]={0};
uint8_t data[11]={0,0,0,0,0,0,0,0,0,0};
for(uint8_t v1='9';v1>='0';v1--){
for(uint8_t v2='9';v2>='0';v2--){
for(uint8_t v3='9';v3>='0';v3--){
for(uint8_t v4='9';v4>='0';v4--){
for(uint8_t v5='9';v5>='0';v5--){
for(uint8_t v6='9';v6>='0';v6--){
for(uint8_t v7='9';v7>='0';v7--){
for(uint8_t v8='9';v8>='0';v8--){
for(uint8_t v9='9';v9>='0';v9--){
for(uint8_t v10='9';v10>='0';v10--){
data[0]=v1;
data[1]=v2;
data[2]=v3;
data[3]=v4;
data[4]=v5;
data[5]=v6;
data[6]=v7;
data[7]=v8;
data[8]=v9;
data[9]=v10;
if(HighwayHash64(data, 10, key) == 0xC886BDF39CB4ED72){
puts((char *)data);
}
} } } } } } } } } }
return 0;
}
大概2-3分钟跑出结果

法二
调用函数有两种方法,一种是写一个dll注入到exe中进行调用,另一种则是将该exe直接改成dll,另外写一个exe来调用
考虑后者将exe修改成dll
可以用010editor修改pe的NT头
- IMAGE_FILE_HEADER->Characteristics(文件属性)->2102h(DLL文件一般是2102h)
- IMAGE_OPTIONAL_HEADER->AddressOfEntryPoint(程序执行入口RVA)->0000h

或者用DIE的PE菜单修改


exp
//#include "pch.h"
#include <iostream>
#include<windows.h>
typedef __int64(__fastcall *f)(__int64 buff, unsigned __int64 len);
f func;
void len()
{
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);
return;
}
}
printf("Not found the lenn");
return;
}
void hash()
{
unsigned long long i;
unsigned long long result;
char buff[20];
for (i = 10000000000; i > 0; i--)
{
sprintf_s(buff, "%0.10llu", i);
/*if (i % 100000 == 0)
{
printf("%0.10llu\n", i);
}*/
result = func((long long)buff, 10);
if (result == 0xC886BDF39CB4ED72)
{
printf("flag is %lld\n", i);
return;
}
}
}
int main()
{
HINSTANCE hdll;
hdll = LoadLibrary(TEXT("D:\\C++\\reverse.dll"));
if (hdll == NULL)
{
printf("Load dll Error: %dn", GetLastError());
return 0;
}
printf("Dll base is %llx\n", hdll);
func = ((f)((char*)hdll + 0x17A0));
len();
hash();
}
/*
Dll base is 7ffb57d20000
Len is 10
flag is 9352641078
*/
大概跑5分钟的样子

flag
hxb2018{9352641078}