Password Spammer

Hey I had this pretend password spammer program (which just outputted a cycle of many combinations) but after randomly browsing MSDN for a while I wondered if I could make it work for real...
I don't think an awful lot of this is right but it compiles, only to get a runtime error.

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
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <string>

#define NAME_SIZE 20
#define PASS_SIZE 20

using namespace std;
void CALLBACK sendMessage(string arg);

int main(){
    char user[NAME_SIZE];
    printf("User to hack: ");
    for(int i=0; i<NAME_SIZE; i++){
        char temp = getchar();
        if(isalnum(temp))
            user[i] = temp;
        else
            break;
    }
    string word;
    word.push_back(' '); //To add first field to vector before while loop
    
    short asSet = 32;
    short asGet;
    short pos; //used to index position of word[]
    printf("Trying Combination:\n");
    while(word.size() < PASS_SIZE){
        pos = 0;
              
        while(asSet < 127){ //To cycle through 1st number
            word[0] = (asSet); //Set word[0] to asSet ASCII
            LPTHREAD_START_ROUTINE address = (LPTHREAD_START_ROUTINE)sendMessage;
            if(CreateThread(NULL, NULL, address, &word, NULL, NULL)){
                //Compiler was complaining about how I was putting string together so I gave up and changed it to this
                string full = "RUNAS //user:";
                full += user;
                full += " found.exe "; //Application doesn't exist yet but will take the password as launch argument
                full += word;
                if(system(full.c_str()))
                    exit(0);
                printf("%s", (word.c_str()));
                printf("\r");
                asSet++; //increment ASCII code for word[0]
            }
        }//CLOSE while(temp < 127)
        
        
        while(asSet != 32){
            asGet = (word[pos]); //gets ASCII code for word[pos]
            if(asGet == 126){ //if ASCII for word[pos] is maxed
                word[pos] = ' '; //reset this to SP (ASCII=32)
                if(pos == (word.size() -1)) //if this is last character (i.e last combination)
                    word.push_back('!'); //add another charater for new combinations
                else //if this is NOT last character
                    pos++; //move to next character for testing
            }//CLOSE if(asGet == 126)
            
            else{ //if ASCII for word[pos] is NOT maxed
                word[pos] = (asGet +1); //increment it's current ASCII value
                asSet = 32; //reset iterater for word[0] to exit loop and re-enter top loop
            }//CLOSE else
        }//CLOSE while(asSet != 32)
    }//CLOSE while(word.size() < PASS_SIZE)
}

void CALLBACK sendMessage(string arg){
    BlockInput(TRUE);
    INPUT msg[PASS_SIZE];
    for(int i=0; i<PASS_SIZE; i++){
        msg[i].type = INPUT_KEYBOARD;
        KEYBDINPUT key;
        key.wVk = arg[i];
        key.wScan = NULL;
        key.dwFlags = NULL;
        key.time = NULL;
        key.dwExtraInfo = NULL;
        msg[i].ki = key;
    }
    SendInput(PASS_SIZE, msg, sizeof(INPUT));
    BlockInput(FALSE);
}


The runtime error I get is in a big message box from either windows or the IDE saying "Expression: Subscript out of range", however the box only appears for a split second before it, and the application terminate (I quickly used print screen and paint to view the message).

So... How badly does this program kill my computer and how insane am I for trying it?

I may also want to mention that a lot of this doesn't even make sense to myself, I made half the code years ago when I first started programming so it's a bit messed up, secondly I'm not all in the right mind right now as it's 1:45am XD
Last edited on
Wait... I've had a nice long kip and I think I see the error is because I'm sending ascii character values as key values.
I.e. it starts with '!' which as a key value should be '1' with the shift bit (or whatever it is that needs to be active)

So once I've corrected that do you think it'll work?
Nope, here goes the reason:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CALLBACK sendMessage(string arg){
    BlockInput(TRUE);
    INPUT msg[PASS_SIZE];
    for(int i=0; i<PASS_SIZE; i++){
        msg[i].type = INPUT_KEYBOARD;
        KEYBDINPUT key;
        key.wVk = arg[i];
        key.wScan = NULL;
        key.dwFlags = NULL;
        key.time = NULL;
        key.dwExtraInfo = NULL;
        msg[i].ki = key;
    }
    SendInput(PASS_SIZE, msg, sizeof(INPUT));
    BlockInput(FALSE);
}

Besides the fact you don't need it to be CALLBACK, the problem is here:

for(int i=0; i<PASS_SIZE; i++){

If your input string is shorter (in length) than PASS_SIZE, you will get a runtime error (Out of range maybe?)

You should change it with:

1
2
3
4
int Limit = PASS_SIZE;
if(arg.length() < Limit)
    Limit = arg.length();
for(int i=0; i<PASS_SIZE; i++){


Also, the BlockInput is kinda risky, you should do a little protection against crashes (even tho Windows should handle it well):

1
2
3
4
5
6
7
8
9
10
11
12
// Outside of any function:
struct SafeBlockInput {
    SafeBlockInput() { BlockInput(TRUE); }
    ~SafeBlockInput() { BlockInput(FALSE); }
};

// Remove all your BlockInput calls into the sendMessage function and:

void CALLBACK sendMessage(string arg){
    SafeBlockInput sbi;
    // ...
}


This way, whichever way the function quits, even in case of exceptions, SafeBlockInput::~SafeBlockInput will be called, and it will call BlockInput(FALSE); which will unblock input for the user.
Last edited on
Well I think I've changed that since I last posted but I can't be sure without checking, cheers for pointing that out, and yes windows does handle the errors, although I'd say a little badly but none the less.
Just another thing:
You may get some errors, due to CreateThread and asynchronies with your main program flow.
Also you should create a LPTHREAD_START_ROUTINE function without casting it!
To solve this error (At least in this example):

1. Change from
1
2
LPTHREAD_START_ROUTINE address = (LPTHREAD_START_ROUTINE)sendMessage;
if(CreateThread(NULL, NULL, address, &word, NULL, NULL))/*...*/

to
 
if(CreateThread(NULL, NULL, sendMessage, new std::string(word), NULL, NULL))/*...*/


2. Change from
void CALLBACK sendMessage(string arg);
to
DWORD CALLBACK sendMessage(void * arg);

3. Change from
void CALLBACK sendMessage(string arg){/*...*/}
( This time the definition! )
to
1
2
3
4
5
6
7
8
9
DWORD CALLBACK sendMessage(void * parg){
std::string * pstr = (std::string*)parg;
if(!pstr)
    return 0;
std::string str = *pstr;
delete pstr;
pstr = 0;
/*...*/
}
Last edited on
Topic archived. No new replies allowed.