一个暂时没有名字的项目

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

数据库结构就先不共享了,看得懂的都应该知道、