不解释爆破框架

Author Avatar
Xzhah 1月 20, 2018
  • 在其它设备中阅读本文章

以上一篇博文美亚伯科的题为例,把爆破框架贴上来加以记录,框架不是我写的,是请教一个师傅他发给我的
贴上来只是方便记录一下,以后随时可以用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//BruteForce.h
#pragma once
typedef unsigned char bfbyte;
class BruteForce
{
private:
size_t substrLen(const bfbyte* x);
protected:
bfbyte* input;
size_t inputLen;
size_t inputProg;

bfbyte* answer;
size_t answerLen;

size_t keyProg;

void traverseNext();
virtual void doEncode() = 0;
//do in encode must call testEncodeResult
//with encoded result of current input
//(obtained by getInput) in some way
public:
BruteForce(size_t inputLen, const bfbyte* answer, size_t answerLen);
virtual ~BruteForce();

void startCrack();
void getInput(bfbyte* dst, size_t dstlen);
bool testEncodeResult(const bfbyte* answer);
void getInput(bfbyte * dst);
};

#pragma once

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//BruteForece.cpp
#include "BruteForce.h"
#include <exception>
#include <iostream>
using namespace std;

class BruteForceException
{
public:
BruteForceException(const char* info)
: info(info) {}//fucking todo
private:
const char* info;
};



BruteForce::BruteForce(size_t inputLen, const bfbyte* answer, size_t answerLen)
{
this->answerLen = answerLen;
this->answer = new bfbyte[answerLen];
memcpy(this->answer, answer, answerLen);
this->input = new bfbyte[inputLen + 1];
this->inputLen = inputLen;
memset(this->input, 0, sizeof(bfbyte) * (inputLen + 1));
this->inputProg = 0;
this->keyProg = 0;
}

BruteForce::~BruteForce()
{
delete[] this->answer;
delete[] this->input;
}

void BruteForce::traverseNext()
{
if (input[inputProg] == 0xff)
{//if fail, scroll back one byte
input[inputProg] = 1;
if (inputProg == 0 || keyProg == 0)
{
throw BruteForceException("no solution");
}
inputProg--;
keyProg--;
}
input[inputProg]++;
}
size_t BruteForce::substrLen(const bfbyte* x)
{
size_t i;
for (i = 0; i < answerLen; i++)
{
if (x[i] != this->answer[i])
return i;
}
return i;
}

bool BruteForce::testEncodeResult(const bfbyte * answer)
{
//cout << "encode res: " << answer << endl;
size_t prefLen = substrLen(answer);
if (prefLen > keyProg)
{
//if (prefLen)
//inputToKeyProg[inputProg] = prefLen;
if (inputProg < inputLen - 1)
{
inputProg++;//traverse next byte
}
else
{
printf("bp");
}
keyProg = prefLen;
if (keyProg == 16)
return true;
}
return false;
}

void BruteForce::startCrack()
{
while (true)
{
doEncode();//must call testEncodeResult in some way
traverseNext();
}
}

void BruteForce::getInput(bfbyte * dst, size_t dstlen)
{
if (dstlen < inputLen)
{
throw BruteForceException("dst len not enough");
}
getInput(dst);
}

void BruteForce::getInput(bfbyte * dst)
{//need to prevent buffer overflow by yourself!
memcpy(dst, input, inputLen);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//源.cpp
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include "BruteForce.h"

typedef int(*main_t)();
#define GETS_IAT 0x40DC
#define MAIN_DISPL 0x13E0
#define FWRITE_IAT 0x4060
#define SYSTEM_IAT 0x4068
#define FOPEN_IAT 0x406C
#define FCLOSE_IAT 0x4064
#define COUT_IAT 0x4038

#define KEY "Itl9qnxD/IJhoarL"

#define INPUT_LEN 12

main_t hismain;

class CrackCtf : public BruteForce
{
public:
CrackCtf(size_t inputLen, const bfbyte* answer, size_t answerLen)
:BruteForce(inputLen, answer, answerLen) {}
~CrackCtf();
private:

virtual void doEncode() override
{
hismain();
}
public:
static size_t __cdecl myfwrite(char *str, size_t Size, size_t Count, FILE *File);
};
CrackCtf::~CrackCtf() {}

CrackCtf crack(INPUT_LEN, (const bfbyte*)KEY, strlen(KEY));
//本应该是单例模式,但是CTF比赛的时间不可能给你写单例

size_t CrackCtf::myfwrite(char * str, size_t Size, size_t Count, FILE * File)
{
//printf("%s\n", str);
if (crack.testEncodeResult((bfbyte*)str))
{
bfbyte buf[INPUT_LEN + 1];
memset(buf, 0, INPUT_LEN + 1);
crack.getInput(buf, INPUT_LEN + 1);
MessageBoxA(NULL, (LPCSTR)buf, "flag", MB_OK);
}

return 0;
}


char* __cdecl mygets(char* buffer)
{
crack.getInput((bfbyte*)buffer);
//printf("input: %s\n", buffer);
// for (char* i = buffer; *i; i++)
// {
// printf("%x ", (bfbyte)*i);
// }
// printf("\n");
return buffer;
}


int __cdecl emptyFunc()
{
return 1;
}

int __stdcall emptyFunc2(DWORD sth)
{
return 1;
}
void changeIAT(DWORD* iat, DWORD newVal)
{
DWORD oldProtect;
VirtualProtect(iat, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtect);
*iat = newVal;
VirtualProtect(iat, sizeof(DWORD), oldProtect, &oldProtect);
}

int main()
{
char buf1[128];
char buf2[128];


PBYTE pBase = (PBYTE)LoadLibraryA("exe2dll.dll");

DWORD* getsiat = (DWORD*)(pBase + GETS_IAT);
changeIAT(getsiat, (DWORD)&mygets);

DWORD* fwriteiat = (DWORD*)(pBase + FWRITE_IAT);
changeIAT(fwriteiat, (DWORD)&CrackCtf::myfwrite);

changeIAT((DWORD*)(pBase + SYSTEM_IAT), (DWORD)&emptyFunc);
changeIAT((DWORD*)(pBase + FOPEN_IAT), (DWORD)&emptyFunc);
changeIAT((DWORD*)(pBase + FCLOSE_IAT), (DWORD)&emptyFunc);
changeIAT((DWORD*)(pBase + COUT_IAT), (DWORD)&emptyFunc2);

hismain = (main_t)(pBase + MAIN_DISPL);

crack.startCrack();

return 0;
}