一个暂时没有名字的项目
0x00 简介
0x02 编译环境 - Linux 平台
git clone https://github.com/jtv/libpqxx.git # clone软件包
apt-get install pkg-config
apt-get install make # 安装make
apt-get install g++ # 安装g++编译器
apt-get install libpq-dev
cd libpqxx
./configure
make
make install
libpqxx 是用来给其他C/C++程序提供连接、操作postgresql的库。
目录结构:
├── CMakeLists.txt
├── Command.cpp
├── Command.h
├── Postgres.cpp
├── Postgres.h
├── cmake-build-debug
├── main.cpp
├── psql
└── psql.dSYM
0x03 编译
g++ main.cpp Postgres.cpp Command.cpp -o psql -lpqxx -lpq -lpthread -std=c++11 -g
0x04 使用
使用方法已经在视频中了,后来我在慢慢完善数据库结构
liyingzhes-MBP:psql liyingzhe$ ./psql
Connected Success !
[*]Console >list
[-]Please input list [<Target><Request><Detection><Techniques><Injection><Optimization><Fingerprint><Enumeration>]
[*]Console >list Target
opt_name opt_value explain
direct Direct connection to the database.
logFile Parse targets from Burp or WebScarab logs
bulkFile Scan multiple targets enlisted in a given textual file
requestFile Load HTTP request from a fil
googleDork Rather than providing a target URL, let Google return target
sitemapUrl Parse target(s) from remote sitemap(.xml) file.
url http://127.0.0.1:8081/vulnerabilities/test.php?id=2 Target URL.
----------
Rows : 7
[*]Console >
list 中的每一个可选项对应一个数据表,用来保存我们设置的值。
该程序只要执行 exploit/run 即可进行攻击
0x05 展望
由于Metasploit采用的数据库就是postgresql,笔者只研究了一段时间,然后用Python写了一个快速搜索msf模块的脚本,发现对于效率提升了很多,另外不需要开启msfconsole,它的加载速度太慢了。
程序中有很多东西都写死了,完全可以加到数据库的配置中,这样会更加灵活
# 勿喷,要脸 —— 倾旋
只要花时间研究数据库结构,我想是可以集成更多的工具。 将它部署在Kali这种平台下,减少工作量,提高渗透效率。
附:数据库是个好东西
0x06 忠告
这个项目我只是突发奇想,锻炼自己的C++功底,创造自己所想的,程序中可能会出现SQL注入之类的问题,别跟我扯什么高大上的安全问题,我做我想做的,不会在意被人怎么看。
0x07 源代码
main.cpp
#include <iostream>
#include <pqxx/pqxx>
#include <iomanip>
#include "Postgres.h"
#include <vector>
#include "Command.h"
int main(int argc, char * argv[])
{
Postgres postSqler;
CommandHelper * Command = new CommandHelper;
// std::string listOpt[] = {"Target","Request"};
std::string listOpt[] = {"Target","Request","Detection","Techniques","Injection","Optimization","Fingerprint","Enumeration"};
std::string sqlmap = "sqlmap -c ";
std::string filename = "/Users/liyingzhe/Downloads/a.txt";
try{
std::string globalCommand[] = {"sql","list","set","exploit","run","show","info","help"};
pqxx::connection Link("dbname=testdb user=liyingzhe password=kali1997 hostaddr=127.0.0.1 port=5432");
if(Link.is_open()){
std::cout << "Connected Success !" << std::endl;
}
char line[300];
while(true){
std::cout << "[*]Console >";
std::cin.getline(line,299);
if(strlen(line) == 0){
continue;
}
//std::cout << "length : " << strlen(line) << std::endl;
std::vector<std::string> Commandlines = Command->getCommandStr(line);
//std::cout << "length : " << strlen(line) << std::endl;
if(Commandlines[0] == "sql"){
if(Command->Sql(Commandlines,postSqler,Link)){
continue;
}
std::cout << "[-]sql <SQL Query>" << std::endl;
}
if(Commandlines[0] == "list"){
if(Commandlines.size() < 2 || !Command->findVectorSet(listOpt,Commandlines[1], sizeof(listOpt))){
std::cout << "[-]Please input list [";
for(int p = 0;p < (sizeof(listOpt)/sizeof(std::string));p++){
std::cout << "<" << listOpt[p] << ">";
}
std::cout << "]" <<std::endl;
continue;
}
std::string sql = "SELECT opt_name,opt_value,explain FROM " + Commandlines[1];
Command->Exec(sql,postSqler,Link);
}
if(Commandlines[0] == "exit"){
break;
}
if(Commandlines[0] == "set"){
Command->SetVal(Commandlines,postSqler,Link);
continue;
}
if(Commandlines[0] == "info"){
if(Commandlines.size() < 4 || !Command->findVectorSet(listOpt,Commandlines[1], sizeof(listOpt))){
std::cout << "[-]Please input info [";
for(int p = 0;p < (sizeof(listOpt)/sizeof(std::string));p++){
std::cout << "<" << listOpt[p] << ">";
}
std::cout << "] <opt_name>" <<std::endl;
continue;
}
std::string sql = "SELECT * FROM " + Commandlines[1] + " WHERE opt_name = '" + Commandlines[2] + "'";
// std::cout << sql <<std::endl;
Command->Exec(sql,postSqler,Link);
continue;
}
if(Commandlines[0] == "save"){
Command->Save(listOpt, sizeof(listOpt)/ sizeof(std::string),postSqler,Link,filename);
}
if(Commandlines[0] == "unset"){
Command->UnSetVal(Commandlines,postSqler,Link);
continue;
}
if(Commandlines[0] == "exploit" || Commandlines[0] == "run"){
Command->Save(listOpt, sizeof(listOpt)/ sizeof(std::string),postSqler,Link,filename);
Command->Exploit(filename,sqlmap);
continue;
}
if(Commandlines[0] == "help"){
std::cout << "Usage :"
<< std::endl
<<"list <table name>"<< std::endl
<< "\t 查看局部配置项"
<< std::endl
<<"set <table name> <opt_name> <opt_value>"
<< "\t 设置配置项"
<< std::endl
<< "info <table name> <opt_name>"
<< "\t 查看单独配置项"
<< std::endl
<< "exploit"
<< "\t 运行"
<< std::endl;
continue;
}
continue;
}
}catch (const std::exception &e){
std::cerr << e.what() << std::endl;
return 1;
}
delete Command;
}
Command.h
//
// Created by liyingzhe on 20/10/17.
//
#include <vector>
#include <iostream>
#include <string>
#ifndef PSQL_COMMAND_H
#include "Postgres.h"
#define PSQL_COMMAND_H
#include <pqxx/pqxx>
class CommandHelper{
public:
//CommandHelper();
//~CommandHelper();
/**
* 获取命令
* @param line 命令行
* @param cutStr 分割字符
* @return
*/
std::vector<std::string> getCommandStr(char * line);
/**
* 判断元素是否存在vector
* @param VecArray
* @param strArr
* @return
*/
bool findVectorSet(std::string strArr[],std::string Str,int strArrSize);
/**
* SQL命令:执行SQL语句
* @param CommandArray
* @param postSqler
* @param Link
* @return
*/
bool Sql(std::vector<std::string> CommandArray,Postgres postSqler,pqxx::connection &Link);
/**
* 执行SQL 且输出结果
* @param sql
* @param postSqler
* @param Link
* @return
*/
bool Exec(std::string sql,Postgres postSqler,pqxx::connection &Link);
/**
* 更改属性值
* @param Commandline
* @param postgres
* @param Link
* @return
*/
bool SetVal(std::vector<std::string> Commandline,Postgres postgres,pqxx::connection &Link);
/**
* 保存配置
* @param tableList
* @param tableLength
* @param postgres
* @param Link
* @param filename
* @return
*/
bool Save(std::string tableList[],int tableLength,Postgres postgres,pqxx::connection &Link,std::string filename);
/**
* 清空属性
* @param Commandline
* @param postgres
* @param Link
* @return
*/
bool UnSetVal(std::vector<std::string> Commandline,Postgres postgres,pqxx::connection &Link);
/**
* 执行
* @param filename
* @param command
* @return
*/
bool Exploit(std::string filename,std::string command);
};
#endif //PSQL_COMMAND_H
Command.cpp
//
// Created by liyingzhe on 20/10/17.
//
#include "Command.h"
#include <pqxx/pqxx>
#include "Postgres.h"
#include <fstream>
#include <stdio.h>
bool CommandHelper::findVectorSet(std::string strArr[],std::string Str,int strArrSize) {
for(int x = 0; x < strArrSize ; x++){
if(strArr[x] == Str){
return true;
}
}
return false;
}
std::vector<std::string> CommandHelper::getCommandStr(char *line) {
std::vector<std::string> CommandResult;
char * token = strtok(line," ");
while(token != NULL){
std::string x = token;
CommandResult.push_back(x);
token = strtok(NULL," ");
}
return CommandResult;
}
bool CommandHelper::Sql(std::vector<std::string> CommandArray, Postgres postSqler, pqxx::connection &Link){
std::string sqlQuery;
for(int x = 0;x<CommandArray.size();x++){
if(x==0){ continue;}
sqlQuery += CommandArray[x] + " ";
}
return CommandHelper::Exec(sqlQuery,postSqler,Link);
}
bool CommandHelper::Exec(std::string sql, Postgres postSqler, pqxx::connection &Link) {
try{
pqxx::result res = postSqler.Select(sql.c_str(),Link);
postSqler.Print(res);
}catch (std::exception &e) {
std::cout << e.what() << std::endl;
return false;
}
return true;
}
bool CommandHelper::SetVal(std::vector<std::string> Commandlines, Postgres postgres, pqxx::connection &Link) {
if(Commandlines.size() < 4){
// set target url value
std::cout << "[-]set <table name> <opt_name> <opt_value>" << std::endl;
return false;
}
std::string sql = "UPDATE " + Commandlines[1] + " SET opt_value = '" + Commandlines[3] + "' where opt_name = '" + Commandlines[2] +"'";
if(!CommandHelper::Exec(sql,postgres,Link)){
return false;
}
return true;
}
bool CommandHelper::Save(std::string tableList[],int tableLength,Postgres postgres,pqxx::connection &Link,std::string filename){
try{
// std::ofstream
std::ofstream Out(filename.c_str());
if(!Out.is_open()){
std::cout << "[-]Error Opened file ..." << filename.c_str() << std::endl;
return false;
}
for(int y=0; y < tableLength && Out.is_open(); y++){
Out << "[" + tableList[y] +"]" << std::endl;
std::string sql = "SELECT opt_name,opt_value FROM " + tableList[y] +" WHERE State = true";
pqxx::result res = postgres.Select(sql.c_str(),Link);
for(pqxx::result::const_iterator c = res.begin(); c != res.end(); ++c) {
Out << c[0].c_str() << " = " << c[1].c_str() << std::endl;
}
}
Out.close();
return true;
}catch (std::exception &e){
std::cout << e.what() << std::endl;
return false;
}
}
bool CommandHelper::UnSetVal(std::vector<std::string> Commandlines, Postgres postgres, pqxx::connection &Link) {
if(Commandlines.size() < 3){
// set target url value
std::cout << "[-]unset <table name> <opt_name>" << std::endl;
return false;
}
std::string sql = "UPDATE " + Commandlines[1] + " SET opt_value = '' where opt_name = '" + Commandlines[2] +"'";
if(!CommandHelper::Exec(sql,postgres,Link)){
return false;
}
return true;
}
bool CommandHelper::Exploit(std::string filename, std::string command) {
command += filename;
char line[100];
FILE * FP = popen(command.c_str(),"r");
while(fgets(line, sizeof(line) - 1,FP)){
std::cout << line ;
}
pclose(FP);
return true;
}
Postgres.h
#include <pqxx/pqxx>
#include <iostream>
#include <iomanip>
#include <pqxx/result>
#ifndef PSQL_POSTGRES_H
#define PSQL_POSTGRES_H
class Postgres{
public:
// 初始化方法
//void Connect(const char * connection_string,pqxx::connection &C);
/**
* 查询并返回结果
* @param sql
* @param C
* @return
*/
pqxx::result Select(const char * sql,pqxx::connection &C);
/**
* 执行插入操作
* @param sql
* @param C
* @return
*/
pqxx::result Insert(const char * sql,pqxx::connection &C);
/**
* 打印查询结果
* @param res
*/
void Print(pqxx::result res);
//~Postgres(pqxx::connection C);
};
#endif //PSQL_POSTGRES_H
Postgres.cpp
#include <pqxx/pqxx>
#include <iostream>
#include "Postgres.h"
#include <iomanip>
#include <pqxx/result>
using namespace pqxx;
using namespace std;
// void Postgres::Connect(const char *connection_string,pqxx::connection &C){
// try{
//
// C.(connection_string);
// if(C.is_open()) {
// std::cout <<"[*]Connection success "<< std::endl;
// }
// }catch (std::exception &e){
// std::cerr << e.what() << endl;
// exit(-1);
// }
// }
pqxx::result Postgres::Insert(const char * sql,pqxx::connection &C){
pqxx::work W(C);
pqxx::result res = W.exec(sql);
W.commit();
return res;
}
pqxx::result Postgres::Select(const char * sql,pqxx::connection &C){
pqxx::work W(C);
pqxx::result res = W.exec(sql);
W.commit();
return res;
}
void Postgres::Print(pqxx::result res){
// std::cout << "columns number :" << res.columns() << std::endl; // 字段数目
// res.column_name() 字段名称
for(unsigned int a=0;a<res.columns();a++){
std::cout << left;
std::cout << std::setw(12)
<< res.column_name(a)
<< std::setw(12) << "\t";
}
std::cout << std::endl;
//std::cout << "ROW :"<<res.affected_rows() << std::endl;
//std::cout << "id column_table :"<<res.column_table("id") << std::endl;
//std::cout << "table_column :"<<res.table_column(1) << std::endl;
for(pqxx::result::const_iterator c = res.begin(); c != res.end(); ++c) {
//std::cout << left;
for(int i=0;i < res.columns();i++){
std::cout
<< std::left
<<std::setw(12)
<< c[i].c_str()
<< std::setw(12) << "\t";
}
std::cout << std::endl;
}
string s(10,'-');
std::cout << s << std::endl;
std:: cout << "Rows : " << res.affected_rows() << std::endl;
}
数据库结构就先不共享了,看得懂的都应该知道、