Created
June 5, 2015 09:31
-
-
Save maze1230/f76a5855eaa8debb8293 to your computer and use it in GitHub Desktop.
create_printable_shellcode.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <sstream> | |
#include <iomanip> | |
#include <algorithm> | |
#include <string> | |
#include <fstream> | |
#include <vector> | |
#include <random> | |
using namespace std; | |
string to_hexstring(int num); | |
int load_shellcode(string file_path, vector<int> *org_shellcode); | |
int write_shellcode(string file_path, vector<int> org_shellcode, int offset); | |
vector<unsigned int> to_printable(unsigned int last, unsigned int targ); | |
vector<unsigned int> search_elem(unsigned int last, unsigned int targ, int offset, int elem_num, unsigned int *carry); | |
int main(int argc, char *argv[]){ | |
int esp_offset; | |
vector<int> shellcode; | |
if(argc < 3){ | |
cout << "Usage: " << argv[0] << " <シェルコードを格納しているファイル> <保存先> " << endl << | |
" <espの移動量(デフォルト:200)>" << endl; | |
return 1; | |
} | |
if(argc < 4) | |
esp_offset = -200; | |
else | |
esp_offset = stoi(argv[3]); | |
if(load_shellcode(argv[1], &shellcode)){ | |
cout << "シェルコード読み込みエラー" << endl; | |
return 1; | |
} | |
cout << setfill('0'); | |
for_each(shellcode.begin(), | |
shellcode.end(), | |
[](char byte) { cout << setw(2) << hex << (static_cast<int>(byte) & 0x000000ff) << " "; }); | |
cout << endl; | |
if(write_shellcode(argv[2], shellcode, esp_offset)){ | |
cout << "シェルコード書き込みエラー" << endl; | |
return 1; | |
} | |
return 0; | |
} | |
string to_hexstring(int num){ | |
stringstream ss; | |
ss << setfill('0'); | |
ss << setw(2) << hex << (num & 0x000000ff); | |
return ss.str(); | |
} | |
int load_shellcode(string file_path, vector<int> *org_shellcode){ | |
char byte; | |
ifstream ifs(file_path, ios::in | ios::binary); | |
if(ifs == NULL) | |
return 1; | |
while(!ifs.eof()){ | |
ifs.read(&byte, 1); | |
org_shellcode->push_back(static_cast<int>(byte)); | |
} | |
org_shellcode->pop_back(); | |
reverse(org_shellcode->begin(), org_shellcode->end()); | |
while(org_shellcode->size()%4){ | |
org_shellcode->push_back('\x90'); | |
} | |
for(int i = 0;i < 4;i++){ | |
org_shellcode->push_back('\x90'); | |
} | |
return 0; | |
} | |
int write_shellcode(string file_path, vector<int> org_shellcode, int offset){ | |
string last, targ("00000000"); | |
vector<unsigned int> esp_offset; | |
vector<unsigned int> course; | |
ofstream ofs(file_path, ios::out); | |
if(ofs == NULL) | |
return 1; | |
if(offset > 0) | |
esp_offset = to_printable(0, -1 * offset); | |
else | |
esp_offset = to_printable(offset, 0); | |
ofs << "BITS 32" << endl; | |
ofs << "push esp" << endl; | |
ofs << "pop eax" << endl; | |
for(auto a : esp_offset){ | |
if(a != 0) | |
ofs << "sub eax, 0x" << hex << a << endl; | |
} | |
ofs << "push eax" << endl; | |
ofs << "pop esp" << endl; | |
ofs << "and eax, 0x454e4f4a" << endl; | |
ofs << "and eax, 0x3a313035" << endl << endl; | |
for(int i = 0;i < org_shellcode.size();i=i+4){ | |
last = targ; | |
targ = to_hexstring(org_shellcode[i]); | |
targ += to_hexstring(org_shellcode[i+1]); | |
targ += to_hexstring(org_shellcode[i+2]); | |
targ += to_hexstring(org_shellcode[i+3]); | |
course = to_printable(stoul(last, nullptr, 16), stoul(targ, nullptr, 16)); | |
for(auto elem : course){ | |
if(elem != 0) | |
ofs << "sub eax, 0x" << hex << elem << endl; | |
} | |
ofs << "push eax" << endl; | |
} | |
for(int i = 0;i < 20;i++){ | |
ofs << "push eax" << endl; | |
} | |
return 0; | |
} | |
vector<unsigned int> to_printable(unsigned int last, unsigned int targ){ | |
int success_byte = 0; | |
unsigned int result; // elemをすべて足したものを入れる変数 | |
unsigned int carry = 0; | |
vector<unsigned int> byte; | |
vector<unsigned int> elem(4, 0); | |
for(int a = 1;a < 5;a++){ | |
success_byte = carry = 0; | |
fill(elem.begin(), elem.end(), 0); | |
for(int z = 0;z < 4;z++){ | |
byte = search_elem(last, targ, z, a, &carry); | |
if(byte.size() != 0){ | |
for(int i = 0;i < a;i++){ | |
elem[i] = elem[i] | (byte[i] << z*8); | |
} | |
success_byte++; | |
result = targ + elem[0] + elem[1] + elem[2] + elem[3]; | |
if(success_byte == 4){ | |
if(result != last) | |
continue; | |
return elem; | |
} | |
} | |
} | |
} | |
return elem; | |
} | |
vector<unsigned int> search_elem(unsigned int last, unsigned int targ, int offset, int elem_num, unsigned int *carry){ | |
random_device rdev; | |
string tmp = "%_01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"; | |
vector<char> printable_chr(tmp.begin(), tmp.end()); | |
vector<unsigned int> elem; | |
unsigned int byte_t, byte_l, try_elem, single; | |
byte_t = (targ >> (offset*8)) & 0x000000ff; | |
byte_l = (last >> (offset*8)) & 0x000000ff; | |
shuffle(printable_chr.begin(), printable_chr.end(), mt19937(rdev())); | |
for(auto i = printable_chr.begin();i < printable_chr.end();i++){ | |
for(auto j = printable_chr.begin();j < printable_chr.end();j++){ | |
for(auto m = printable_chr.begin();m < printable_chr.end();m++){ | |
for(auto n = printable_chr.begin();n < printable_chr.end();n++){ | |
if(elem_num < 2) j = printable_chr.end(); | |
if(elem_num < 3) m = printable_chr.end(); | |
if(elem_num < 4) n = printable_chr.end(); | |
try_elem = byte_t + *carry + *i + *j + *m + *n; | |
single = try_elem & 0x000000ff; | |
if(single == byte_l){ | |
*carry = (try_elem & 0x0000ff00) >> 8; | |
if(i != printable_chr.end()) elem.push_back(*i); | |
if(j != printable_chr.end()) elem.push_back(*j); | |
if(m != printable_chr.end()) elem.push_back(*m); | |
if(n != printable_chr.end()) elem.push_back(*n); | |
return elem; | |
} | |
} | |
} | |
} | |
} | |
return elem; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment