Author Topic: [C++] Multipart POST request sender  (Read 1621 times)

0 Members and 1 Guest are viewing this topic.

Offline Kulverstukas

  • Administrator
  • Zeus
  • *
  • Posts: 6627
  • Cookies: 542
  • Fascist dictator
    • View Profile
    • My blog
[C++] Multipart POST request sender
« on: February 23, 2014, 05:13:11 pm »
Finally I had the time to revisit it again. Many moons ago I tried to understand how Multipart file upload works and kinda didn't succeed, but then again I didn't put that much effort into it. I did it now because I have a project on my hands which requires this, whole theory didn't seem very hard and I was able to produce working code for client and server sides in a few hours.

Sending multipart requests is great for file uploading and other large quantities of data. I won't go about and write a tutorial on how to send these requests, instead I will point you to an awesome RFC and this tutorial.

While browsing I had found a working example done in Python. Cannot remember where I found it or to who it belongs, but anyway, that example code can be found in my projects folder here.

And so based on the docs and that example code I was able to produce a CPP project for my own needs. I tried to make it very simple to adapt for other projects. The project can be found here, and along with it I made a simple PHP script that receives the commands and acts upon them, it's also a part of other bigger project...

Here's a C++ code I produced:

Code: (cpp) [Select]
/*
    Author: Kulverstukas
    Date: 2014.02.23
    Website: http://9v.lt; Evilzone.org
    Description:
        Simple prototype of Multipart POST sending in C++
*/

#include <iostream>
#include <winsock2.h>
#include <string>
#include <fstream>
#include "windows.h"
#include "stdio.h"

using namespace std;

#define PORT       80
#define IP         "127.0.0.1"
#define HOST       "locahost"
#define RECEIVER   "/receive_data.php"
#define COMPNAME   "compname"
#define PROGRAM    "program"
#define FILENAME   "file"
#define BOUNDARY   "----------Evil_B0uNd4Ry_$"
#define DUMMY_DATA "c2FzYXNhc2FzZGRmZGZkY2Q="
#define DUMMY_FILE "dummy.txt"

//------------------------------------
string constructBody(string args[2], string file[2]);
string readFile(string fileName);
//------------------------------------

int main() {
    // initiate the socket!
    SOCKET dataSock;
    WSADATA wsaData;
    int error = WSAStartup(0x0202, &wsaData);
    if (error != 0) {
        WSACleanup();
        exit(1);  // oh shit, this shouldn't happen!
    }
    // all internets, engage!
    SOCKADDR_IN target;
    target.sin_family = AF_INET;
    target.sin_port = htons(PORT);
    target.sin_addr.s_addr = inet_addr(IP);
    dataSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (dataSock == INVALID_SOCKET) {
        exit(1); // Houston, we have a problem!
    }
    connect(dataSock, (SOCKADDR*)&target, sizeof(target));

    string programNames[5][2] = {{"KULVERTOP", "Chrome"}, {"KULVERTOP", "Firefox"}, {"KULVERTOP", "InternetExplorer"}, {"KULVERTOP", "Opera"}, {"KULVERTOP", "Skype"}};
    string file[2] = {FILENAME, "Default.txt"};

    int a = sizeof(programNames)/sizeof(programNames[0]);
    for (int i = 0; i < a; i++) {
        printf("Sending data for %s\n", (programNames[i][1]).c_str());
        string body = constructBody(programNames[i], file);
        char header[1024];
        sprintf(header, "POST %s HTTP 1.1\r\n"
                        "Host: %s\r\n"
                        "Content-Length: %d\r\n"
                        "Connection: Keep-Alive\r\n"
                        "Content-Type: multipart/form-data; boundary=%s\r\n"
                        "Accept-Charset: utf-8\r\n\r\n", RECEIVER, IP, strlen(body.c_str()), BOUNDARY);
//        printf("%s\n\n", header);
        int p = send(dataSock, header, strlen(header), 0);
//        printf("p == %d\n", p);
        int k = send(dataSock, body.c_str(), strlen(body.c_str()), 0);
//        printf("k == %d\n", k);

//        char buff[1024];
//        recv(dataSock, buff, 1024, 0);
//        printf("%s\n\n", buff);
    }

    closesocket(dataSock);
    WSACleanup();
}

string readFile(string fileName) {
    string fileContents;
    ifstream tmp(fileName.c_str());
    getline(tmp, fileContents);
    tmp.close();

    return fileContents;
}


string constructBody(string args[2], string file[2]) {
    string body;
    string CRLF = "\r\n";

    // first we add the args
    body.append("--"+string(BOUNDARY)+CRLF);
    body.append("Content-Disposition: form-data; name=\""+string(COMPNAME)+"\""+CRLF);
    body.append(CRLF);
    body.append(args[0]+CRLF);
    body.append("--"+string(BOUNDARY)+CRLF);
    body.append("Content-Disposition: form-data; name=\""+string(PROGRAM)+"\""+CRLF);
    body.append(CRLF);
    body.append(args[1]+CRLF);

    // now we add the file
    body.append("--"+string(BOUNDARY)+CRLF);
    body.append("Content-Disposition: form-data; name=\""+string(FILENAME)+"\"; filename=\""+string(DUMMY_FILE)+"\""+CRLF);
    body.append("Content-Type: text/plain"+CRLF);
    body.append(CRLF);
    body.append(DUMMY_DATA+CRLF);
    body.append("--"+string(BOUNDARY)+"--"+CRLF);
    body.append(CRLF);

//    printf(body.c_str()); exit(0);

    return body;
}


Offline ZeroBoy

  • /dev/null
  • *
  • Posts: 14
  • Cookies: 0
    • View Profile
    • Python for Pentesting @OffensivePython
Re: [C++] Multipart POST request sender
« Reply #1 on: February 23, 2014, 10:31:11 pm »
How many time the for loop gets executed?

Offline Traitor4000

  • Knight
  • **
  • Posts: 191
  • Cookies: 8
    • View Profile
Re: [C++] Multipart POST request sender
« Reply #2 on: February 24, 2014, 05:16:51 am »
The for loop loops for the number of program names. This is because sizeof( any array name ) gives the size of the array and sizeof( any item in that array ) gives the size of an item in the array. Therefore dividing the 1st by the 2nd equals the number of items in an array.


... Sorry I'm kinda bad at explaining things


@OP:
Nice, good that you went back and pushed through to learn it.
« Last Edit: February 24, 2014, 05:18:01 am by Traitor4000 »
The most vulnerable part of an impenetrable system is those who believe it to be so.