libcurl-指北针
libcurl是一个易用免费的http客户端库,其支持众多应用层传输协议,如DICT(dict://dict.org/d:computer,RFC2229定义的基于TCP的字典查询协议)、FILE、FTP, FTPS、GOPHER(诞生于1980年代末期的早期互联网协议,用于浏览和检索文本文档,已淘汰)、GOPHERS、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、MQTT、POP3、POP3S、RTMP、RTMPS、RTSP、SCP、SFTP、SMB、SMBS、SMTP、SMTPS、TELNET、TFTP、WS和WSS等协议。并且在功能特性上libcurl支持SSL证书,以及POST|PUT|FTP等上传,各种代理隧道模式,身份认证方式,文件传输中断恢复等。libcurl支持各种操作系统平台,如常见的Linux,Windows,FreeBSD, OpenBSD,甚至不常见的UnixWare, HURD, Windows, Amiga, OS/2等
接口类型
easy接口
libcurl提供简单高效同步的easy接口簇供开发者快速上手,目前大量开源软件依赖这些接口。按照libcurl的官方文档,该使用模式只需要调用curl_easy_init获取curl句柄(后续调用easy函数簇入参),再设置相关的curl句柄的options(其中必须设置CURLOPT_URL,该参数决定后续模式和对象),最后调用curl_easy_perform执行操作,如果没有后续操作,或者并不需要长连接,记得调用curl_easy_cleanup销毁句柄。
typedef CURL* (*curl_easy_init_func)();
typedef CURLcode (*curl_easy_setopt_func)(CURL*, CURLoption, ...);
typedef CURLcode (*curl_easy_perform_func)(CURL*);
typedef void (*curl_easy_cleanup_func)(CURL*);
typedef const char* (*curl_easy_strerror_func)(CURLcode errornum);
typedef struct curl_slist* (*curl_slist_append_func)(struct curl_slist* list, const char* string);
typedef void (*curl_slist_free_all_func)(struct curl_slist* list);
typedef struct {
curl_easy_init_func init;
curl_easy_setopt_func setopt;
curl_easy_perform_func perform;
curl_easy_cleanup_func cleanup;
curl_easy_strerror_func strerror;
curl_slist_append_func slist_append;
curl_slist_free_all_func slist_free_all;
} CurlInterface;
int onvif_auth_lack_verify(CurlInterface *ci, int argc, const char **argv) {
int res = -1;
CURL *curl = NULL;
if (argc < 1) {
log_error("onvif_auth_lack poc verify require url");
goto done;
}
const char *url = argv[0];
onvif_auth_resp_body_t chunk = {0};
curl = ci->init();
if (!curl) {
log_error("onvif_auth_lack failed to initialize curl");
goto done;
}
CHECK_F2_LABEL((ci->setopt(curl, CURLOPT_URL, url) == CURLE_OK), done, "set url fail");
CHECK_F2_LABEL((ci->setopt(curl, CURLOPT_TIMEOUT, 5L)) == CURLE_OK, done, "set timeout failed");
CHECK_F2_LABEL((ci->setopt(curl, CURLOPT_WRITEFUNCTION, onvif_resp_callback) == CURLE_OK), done, "set write func fail");
CHECK_F2_LABEL((ci->setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk)) == CURLE_OK, done, "set write data fail");
CURLcode curl_res = ci->perform(curl);
if (curl_res != CURLE_OK) {
log_error("CURL error: %s", ci->strerror(curl_res));
goto done;
}
if (memcmp(chunk.data + 2048 - 10, ONVIF_AUTH_LACK_MAGIC_STRING, 10) == 0) {
log_trace("Vulnerability found at URL: %s", url);
}
res = 0; // success
done:
if (curl) ci->cleanup(curl);
return res;
}
multi接口
The multi interface is the asynchronous brother in the family and it also offers multiple transfers using a single thread and more. Get a grip of how to work with it in the multi interface overview.
Read more...






