不解释爆破框架

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;
}