Jump to content

C++/Qt Pass QString to System()?


vailixi

Recommended Posts

I decided to create something graphical. Got hung up on some miner details.

I'm trying to pass the value of a QString to in main to a system call in void. Basically take a bunch QComboBoxes and use them to build system call. Which was the simplest way I could think of to make a Linux GUI for a command line program. Keep in mind this is not quite done. I figure someone will take interest because it's a GUI for msfvenom / veil-evasion when it's done. Here's some of the code for the main window.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include <QtGui>
#include <string>
#include <QString>
#include <QComboBox>



int i;
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QStringList payloads;
    payloads << "Select Payload" << "auxiliary/coldwar_wrapper" << "auxiliary/pyinstaller_wrapper" << "c/meterpreter/rev_http" << "c/meterpreter/rev_http_service" << "c/meterpreter/rev_tcp" << "c/meterpreter/rev_tcp_service" << "c/shellcode_inject/flatc" << "cs/meterpreter/rev_http" << "cs/meterpreter/rev_https" << "cs/meterpreter/rev_tcp" << "cs/shellcode_inject/base64_substitution" << "cs/shellcode_inject/virtual" << "go/meterpreter/rev_http" << "go/meterpreter/rev_https" << "go/meterpreter/rev_tcp" << "go/shellcode_inject/virtual" << "native/backdoor_factory" << "native/hyperion" << "native/pe_scrambler" << "powershell/meterpreter/rev_http" << "powershell/meterpreter/rev_https" << "powershell/meterpreter/rev_tcp" << "powershell/shellcode_inject/download_virtual" << "powershell/shellcode_inject/psexec_virtual" << "powershell/shellcode_inject/virtual" << "python/meterpreter/bind_tcp" << "python/meterpreter/rev_http" << "python/meterpreter/rev_http_contained" << "python/meterpreter/rev_https" << "python/meterpreter/rev_https_contained" << "python/meterpreter/rev_tcp" << "python/shellcode_inject/aes_encrypt" << "python/shellcode_inject/aes_encrypt_HTTPKEY_Request" << "python/shellcode_inject/arc_encrypt" << "python/shellcode_inject/base64_substitution" << "python/shellcode_inject/des_encrypt" << "python/shellcode_inject/download_inject" << "python/shellcode_inject/flat" << "python/shellcode_inject/letter_substitution" << "python/shellcode_inject/pidinject" << "ruby/meterpreter/rev_http" << "ruby/meterpreter/rev_http_contained" << "ruby/meterpreter/rev_https" << "ruby/meterpreter/rev_https_contained" << "ruby/meterpreter/rev_tcp" << "ruby/shellcode_inject/flat";

    QStringListModel *model = new QStringListModel();
    model->setStringList(payloads);

    ui->comboBox->setModel(model);

    QStringList encoders;
    encoders << "Select Encoder" << "cmd/echo" << "cmd/generic_sh" << "cmd/ifs" << "cmd/perl" << "cmd/powershell_base64" << "cmd/printf_php_mq" << "generic/eicar" << "mipsbe/byte_xori" << "mipsbe/longxor" << "mipsle/byte_xori" << "mipsle/longxor" << "php/base64" << "ppc/longxor" << "ppc/longxor_tag" << "sparc/longxor_tag" << "x64/xor" << "x86/add_sub" << "x86/alpha_mixed" << "x86/alpha_upper" << "x86/avoid_underscore_tolower" << "x86/avoid_utf8_tolower" << "x86/bloxor" << "x86/call4_dword_xor" << "x86/context_cpuid" << "x86/context_stat" << "x86/context_time" << "x86/countdown" << "x86/fnstenv_mov" << "x86/jmp_call_additive" << "x86/nonalpha" << "x86/nonupper" << "x86/opt_sub" << "x86/shikata_ga_nai" << "x86/single_static_bit" << "x86/unicode_mixed" << "x86/unicode_upper";

    QStringListModel *model1 = new QStringListModel();
    model1->setStringList(encoders);

    ui->comboBox1->setModel(model1);

    QStringList platforms;
    platforms << "Select Platform" << "openbsd" << "javascript" << "bsdi" << "python" << "netbsd" << "nodejs" << "freebsd" << "firefox" << "aix" << "mainframe" << "hpux" << "irix" << "unix" << "php" << "bsd" << "netware" << "osx" << "android" << "java" << "ruby" << "linux" << "cisco" << "solaris" << "windows";

    QStringListModel *model2 = new QStringListModel();
    model2->setStringList(platforms);

    ui->comboBox2->setModel(model2);

    QStringList arch;
    arch << "Select Architecture";


    QStringList format;
    format << "Select Format" << "asp" << "aspx" << "aspx-exe" << "dll" << "elf" << "elf-so" << "exe" << "exe-only" << "exe-service" << "exe-small" << "hta-psh" << "loop-vbs" << "macho" << "msi" << "msi-nouac" << "osx-app" << "psh" << "psh-net" << "psh-reflection" << "psh-cmd" << "vba" << "vba-exe" << "vba-psh" << "vbs" << "war" << "bash" << "c" << "csharp" << "dw" << "dword" << "pl" << "powershell" << "ps1" << "py" << "python" << "raw" << "rb" << "ruby" << "sh" << "vbapplication" << "vbscript";

    QStringListModel *model4 = new QStringListModel();
    model4->setStringList(format);

    ui->comboBox4->setModel(model4);

    QString var1 = "gnome-terminal -e \"msfvenom --payload \"";

    QString var2;
    var1 = ui->comboBox->currentIndex();
    QString var3;
    var1 = ui->comboBox1->currentIndex();
    QString var4;
    var1 = ui->comboBox2->currentIndex();

    QString command = var1 + " " + var2 + var3 + var4;

}



MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{

    system("");
}


Link to comment
Share on other sites

I'm not that good with C++ but the easiest would be a global where you keep track of the selections and in the on_pushButton_clicked() method (terrible name of a function I should say) you'd assemble the parameters needed to start the program. A probably better way is to utilise the fact that on_pushButton_clicked() is an instance method (MainWindow is an object, and that function is method executed on that specific object instance), meaning that accessing "this" should give you the full MainWindow, allowing you to access and query the state of the various UI elements and, based on that, decide what needs to be done.

Also, system() is fire-and-forget which kinda sorta really sucks. You should fork() a new thread and from within the child thread use the execve() function to run the program. Doing this allows you explicitly provide the individual parameters parameters. When you use system() you're basically passing a string to a shell, with all the injection caveats that go with that. Do note that execve doesn't look at the PATH variable. Check out this stackoverflow question on your possible options.

Link to comment
Share on other sites

ok, so a while back I wrote a program in qt that was a GUI-ish iptables logger for the desktop, I just posted it but its really not done either (although it is functioning). It's got a tasktray icon and uses the notify-osd system to send bubble notifications when iptables sends a log entry to syslog. The real guts of the program is executing a QProcess->start() to do a system() like command. But is also able to retrieve the results of the command to use back into the program. Qt uses lots of SIGNALS/SLOT to provide functionality to buttons and stuff like that, and I find it quiet confusing myself. Maybe this program might be able to provide you with some help to get you program in the direction you would like to go. http://iple.sourceforge.net

Link to comment
Share on other sites

Place "QString command;" at the top near your "int i;" or somewhere you can access it from your button clicked function. Then:

int returnValue = system(command.toUtf8());
//or
int returnValue = system(command.toStdString().c_string()); //which gets an std::string from it, then calls c_string() of it... toUtf8() is like c_string() of an std::string

Like Cooper has mentioned though, I would also recommend using a different method. fork() and execve() is one way, I did it a little different for quickpixie though, where I treated running the command as if it were a file, with my ProcessExecutor class. Note it doesn't work on windows though since windows doesn't allow you to treat a command as a pipe and pipe as a file, but works on pretty much every other platform. So it's maybe not the best way since Qt is supposed to be for cross platform development, but you could check for windows and do it differently there, it's not too much trickier but I don't remember exactly how I did it before on windows... I used allocConsoleWindow I think and wrote to it that way.

You have to include the <memory> header, and also add c+11 to CONFIG of your .pro file: so if it's like "CONFIG += mobility" add it to the end like "CONFIG += mobility c++11"

#include <memory>

class ProcessExecutor
{
private:
    static std::unique_ptr<ProcessExecutor> mainInstance;
public:
    FILE *file;
    std::string output;
    char buffer[4096];

    ProcessExecutor() { memset(buffer, 0, sizeof(buffer)); }
    static std::unique_ptr<ProcessExecutor> make()
    {
        return std::unique_ptr<ProcessExecutor>(new ProcessExecutor());
    }
    static ProcessExecutor *get()
    {
        if(!mainInstance.get()) mainInstance = make();
        return mainInstance.get();
    }
    int run(const char *cmd)
    {
        file = popen(cmd,"r");
        if(!file) return 1;

        output.clear();
        while(fgets(buffer, sizeof(buffer), file) != 0)
        {
            output += buffer;
        }

        pclose(file);
        return 0;
    }
};
std::unique_ptr<ProcessExecutor> ProcessExecutor::mainInstance;
 
 
void MainWindow::on_pushButton_clicked()
{
    QString qs = "ls -lah";
    ProcessExecutor *pe = ProcessExecutor::get();
    pe->run(qs.toUtf8());

    QString qs2 = qs.fromStdString(pe->output);

    ui->textEdit->setText(qs2);
}

Output into a text edit box I used as an example, is the result of running that command... In this case a simple file listing of the current directory.

EDIT: To clarify, the only needed code not including the smart pointer and singleton convenience code is as follows:

class ProcessExecutor
{
public:
    FILE *file;
    QString output;
    char buffer[4096];

    ProcessExecutor() { memset(buffer, 0, sizeof(buffer)); }
    int run(const char *cmd)
    {
        file = popen(cmd,"r");
        if(!file) return 1;

        output.clear();
        while(fgets(buffer, sizeof(buffer), file) != 0)
        {
            output += buffer;
        }

        pclose(file);
        return 0;
    }
};

And we might as well make the "output" variable of it a QString since we're using Qt here... ^^

Lastly without the convenience code, you need to manually delete the allocated process executor object... You won't however need the C++11 features or <memory> header.

QString cmd = "ls -lah";
 
ProcessExecutor *proc = new ProcessExecutor();
if(proc)
{
    proc->run(cmd.toUtf8());
    ui->textEdit->setText(proc->output);

    delete proc;
}
Edited by AlfAlfa
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...