MessagePack unpack失败,通过Libcurl收到C中的大型Metasploit Framework消息

时间:2013-08-21 16:59:40

标签: c libcurl msgpack metasploit

首先,我使用How do I unpack and extract data properly using msgpack-c?来弄清楚如何正确解包数据,因为MessagePack自己的C API文档并不好。虽然,http://wiki.msgpack.org/display/MSGPACK/QuickStart+for+C+Language也可以。

我想要注意的是,对于大多数对metasploit的API调用,代码工作正常,只有大的(返回约16KB的module.exploits)失败。

就像我上一期的问题,我正在工作,所以不能发布实际的代码。我会尝试准确地显示我的代码在做什么,但在下面的代码片段中。

// Function declaration from msgpack headers
bool msgpack_unpack_next(msgpack_unpacked* result, const char* data, size_t len, size_t* off);

// Called by curl after request
size_t unpack_result(char *ptr, size_t size, size_t nmemb, void *userdata){
    size_t real_size = size * nmemb;

    msgpack_unpacked msg;
    msgpack_unpacked_init(&msg);
    // Fails [returns false] when used on "module.exploits" return, not when
    // "module.payloads" is called nor "auth.login".
    msgpack_unpack_next(&msg, ptr, real_size, 0); 


}

msgpack_sbuffer* pack_payload(char **data, size_t size){
    // Code that actually packs payload, pretty standard with nothing special
    // Definitely works, have not had any problems with my payloads
}


int main(void)
{
    CURL *curl;
    CURLcode res;

    curl = curl_easy_init();

    char *auth_payload_array[3] = {"auth.login", "<username>", "<password>"};

    msgpack_sbuffer *auth_payload = pack_payload(auth_payload_array, 3);
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://<IP Address>/api/");
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, auth_payload->data);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, auth_payload->size);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);

        // Add custom content type header
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers, "Content-Type: binary/message-pack");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, unpack_result);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK){
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(res));
            return 1;
        }

        char *exploit_payload_array[2] = {"module.exploits", AUTH_TOKEN};
        msgpack_sbuffer *exploit_payload = pack_payload(exploit_payload_array,2);

        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, exploit_payload->data);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, exploit_payload->size);

        res = curl_easy_perform(curl);
        if (res != CURLE_OK){
            fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(res));
            return 1;
        }
    }
}

我知道上面有内存泄漏,我不想输入所有正确的破坏/释放,因为这只是一个例子。我遗漏了AUTH_TOKEN实际抓取的部分,因为它不应该是错误,因为我在代码中没有问题。我也知道一些卷曲请求代码可以优化为函数。

重要的一点是ruby gem可以在这个相同的API调用中正常工作,但它是一个C扩展,不使用标准的msgpack库,而是进行二进制解析。

当我从返回文件中写入原始数据而不是字符串缓冲区时,手动显示它看起来是正确的msgpack格式。

任何想法在这里出了什么问题?我将开始使用gdb尝试跟踪问题,同时考虑将ruby c扩展转换为我可以使用的库,因为它似乎可以工作。希望,这很简单,你们中的一个会抓住它!

1 个答案:

答案 0 :(得分:1)

写回调不会返回正确的返回码。