通过C++套接字将二进制文件发布到 PHP
POST binary file to PHP via C++ socket
我正在尝试通过套接字发送二进制文件。我捕获了 Curl 标头以尝试对其进行逆向工程。我的应用程序和 curl 请求对我来说似乎相同,但 PHP 脚本无法接收文件。
这是我的代码:
#include <iostream>
#include <string>
#include <fstream>
#include <winsock.h>
#pragma comment(lib, "wsock32.lib")
/***************** PROTOTYPE *******************/
int SockRecv(SOCKET sock);
int SockSend(SOCKET sock, std::string request);
std::streamoff FileSize(std::string filename);
int HTTP_POST(SOCKET sock, std::string host, std::string filename);
int SendFile(SOCKET sock, std::string filename);
/***************** PROTOTYPE *******************/
int main(){
/* Standard networking stuff */
u_short Port = 8080;
const char* IP = "192.168.1.140";
std::string host(IP);
host += ":" + std::to_string(Port);
WSAData wsa;
WSAStartup(MAKEWORD(1, 1), &wsa);
SOCKET sock;
sockaddr_in RemoteSin;
RemoteSin.sin_family = AF_INET;
RemoteSin.sin_port = htons(Port);
if ((RemoteSin.sin_addr.S_un.S_addr = inet_addr(IP)) == INADDR_NONE){
std::cout << "Error setting IP: " << GetLastError() << std::endl;
return 1;
}
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR){
std::cout << "Error creating socket" << std::endl;
return 1;
}
if (connect(sock, (sockaddr *)&RemoteSin, sizeof(sockaddr_in)) == SOCKET_ERROR){
std::cout << "Error connecting to remote host: " << GetLastError() << std::endl;
return 1;
}
/* Sending the binary file */
HTTP_POST(sock, host, "test.exe");
/* Closing and cleaning connection */
closesocket(sock);
WSACleanup();
getchar();
}
std::streamoff FileSize(std::string filename){
std::ifstream file(filename, std::ios::binary | std::ios::ate);
return file.tellg();
}
int HTTP_POST(SOCKET sock, std::string host, std::string filename){
std::string header;
std::streamoff lenght = FileSize(filename);
/* Pre-building body to get the size */
std::string strSize = "------------------------448eacc7eda1d5ef45rn";
strSize += "Content-Disposition: form-data; name="uploadedfile"; ";
strSize += "filename="" + filename + ""rn";
strSize += "Content-Type: application/octet-streamrnrn";
strSize += "rn------------------------448eacc7eda1d5ef45--rn";
/* Calculating Content-Lenght */
lenght = lenght + strSize.size();
/* Building header */
header = "POST /upload.php HTTP/1.1rn";
header += "User-Agent: Botrn";
header += "Host: " + host + "rn";
header += "Accept: */*rn";
header += "Content-Length: " + std::to_string(lenght) + "rn";
// header += "Expect: 100-continuern"; // Curl send this but I think this is not required and might only complicate things
header += "Content-Type: multipart/form-data-stream; ";
header += "boundary=------------------------448eacc7eda1d5ef45rnrn";
/* Appending first part of body to header */
header += "------------------------448eacc7eda1d5ef45rn";
header += "Content-Disposition: form-data; name="uploadedfile"; ";
header += "filename="" + filename + ""rn";
header += "Content-Type: application/octet-streamrnrn";
/* Sending header with first part of body */
if (!SockSend(sock, header)) {
/* Sending binary file */
if (!SendFile(sock, filename)){
/* Closing body by sending end of boundary string */
std::string header_end = "rn------------------------448eacc7eda1d5ef45--rn";
if (!SockSend(sock, header_end)){
/* Printing server response to stdout */
if (!SockRecv(sock)){
return 0;
}
return 1;
}
}
}
return 1;
}
int SockSend(SOCKET sock, std::string request){
if (send(sock, request.c_str(), strlen(request.c_str()), 0) == SOCKET_ERROR){
return 1;
}
return 0;
}
int SockRecv(SOCKET sock){
char reply[1024];
ZeroMemory(reply, 1024);
if (recv(sock, reply, 1024, 0) == SOCKET_ERROR){
return 1;
}
std::cout << reply << std::endl;
return 0;
}
int SendFile(SOCKET sock, std::string filename){
char buf[1040];
std::ifstream infile;
infile.open(filename.c_str(), std::ios::in | std::ios::binary);
if (infile.fail() == 1)
{
infile.close();
return 1;
}
while (!infile.eof())
{
infile.read(buf, sizeof(buf));
if (send(sock, buf, infile.gcount(), 0) == SOCKET_ERROR){
return 1;
}
}
infile.close();
return 0;
}
这是接收 PHP 脚本:
<?php
// Where the file is going to be placed
$target_path = "upload/";
/* Add the original filename to our target path.
Result is "uploads/filename.extension" */
$target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['name']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
?>
使用此 curl 请求:
curl --form "uploadedfile=@test.exe" http://192.168.1.140:8080/upload.php
这是成功上传的样子:
Request:
POST /upload.php HTTP/1.1
User-Agent: curl/7.35.0
Host: 192.168.1.140:8080
Accept: */*
Content-Length: 69328
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------bfaa9a39adfbb3c1
--------------------------bfaa9a39adfbb3c1
Content-Disposition: form-data; name="uploadedfile"; filename="test.exe"
Content-Type: application/octet-stream
/* Binary data */
--------------------------bfaa9a39adfbb3c1--
Response:
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Server: nginx/1.2.6 (Ubuntu)
Date: Tue, 08 Apr 2014 19:45:38 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.4.9-4ubuntu2.4
Content-Length: 35
The file test.exe has been uploaded
然后使用我的C++应用程序,这是上传失败的样子:
Request:
POST /upload.php HTTP/1.1
User-Agent: Bot
Host: 192.168.1.140:8080
Accept: */*
Content-Length: 69328
Content-Type: multipart/form-data-stream; boundary=------------------------448eacc7eda1d5ef45
------------------------448eacc7eda1d5ef45
Content-Disposition: form-data; name="uploadedfile"; filename="test.exe"
Content-Type: application/octet-stream
/* Binary data */
------------------------448eacc7eda1d5ef45--
Response:
HTTP/1.1 200 OK
Server: nginx/1.2.6 (Ubuntu)
Date: Tue, 08 Apr 2014 19:45:49 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.4.9-4ubuntu2.4
Content-Length: 56
There was an error uploading the file, please try again!
我省略了"期望:100-继续",因为我认为这是可选的。否则,这两个请求对我来说看起来完全相同。三重检查了我能做的一切,但现在我被困在那里。
感谢您的任何输入!
您使用了错误的标头:
header += "Content-Type: multipart/form-data-stream; ";
^^^^^^^---- wrong type
它应该只是multipart/form-data
.
至于你的PHP代码,你没有检查成功/有效的上传,只是假设一切正常:
if ($_FILES['uploadedfile']['error'] !== UPLOAD_ERR_OK) {
die("Upload failed with error code" . $_FILES['uploadedfile']['error']);
}
如果你有这个最小的错误处理,你会被告知一开始就没有上传,而不是后来当你尝试移动不存在的文件时发现。
相关文章:
- 我应该如何获取配置文件的绝对路径与 Windows .exe一起发布?
- 如何使用PHP将上传到本地主机的一个html文件重定向到磁盘上的另一个html文档
- 删除编译器优化并在发布中启用 pdb 文件
- 如何使用curl c ++源代码发布wav文件数据,如何使用c ++使用--data-binary?
- 在 eclipse 中以发布模式构建后没有可执行文件
- 从 PHP 调用已编译的C++可执行文件来创建套接字
- 文件写入在PHP扩展c / c ++(linux)中不起作用
- 在h文件上内联发布版本并在cpp上实现调试版本的函数
- 当 PHP、C++ 和 shell 脚本尝试访问同一个文件时,如何避免错误?
- 如何使用 GLFW 预编译的二进制文件编译 Visual Studio 2019 发布版本
- ESP8266读取 JSON,但不读取 PHP 文件
- Visual Studio在发布模式下构建,但用户收到消息说他们需要调试文件
- Apache在PHP文件上保持文件锁定,直到关闭
- QT项目在配置文件上崩溃,与发布和调试器一起运行
- 为什么PHP的Shell_exec没有给出某些A.Out文件的输出
- php 如何从 exe 文件接收多个 cout
- 在发布-版本中读取文件时调试断言失败
- 发布我的 *.so文件时,应使用哪个版本的glibc
- 无法使用wininet将ZIP文件发布到服务器
- 通过C++套接字将二进制文件发布到 PHP