2014-04-08 2 views
0

소켓을 통해 이진 파일을 보내려고합니다. 리버스 엔지니어링을 시도하기 위해 컬 헤더를 캡쳐했습니다. 내 응용 프로그램과 컬 요청은 나에게도 같지만 PHP 스크립트는 파일을받지 못합니다.C++ 소켓을 통해 POST 바이너리 파일로 PHP

curl --form "[email protected]" http://192.168.1.140:8080/upload.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!"; 
} 

?> 

: 여기

#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 = "------------------------448eacc7eda1d5ef45\r\n"; 
     strSize += "Content-Disposition: form-data; name=\"uploadedfile\"; "; 
     strSize += "filename=\"" + filename + "\"\r\n"; 
     strSize += "Content-Type: application/octet-stream\r\n\r\n"; 
     strSize += "\r\n------------------------448eacc7eda1d5ef45--\r\n"; 

     /* Calculating Content-Lenght */ 
     lenght = lenght + strSize.size(); 

     /* Building header */ 
     header = "POST /upload.php HTTP/1.1\r\n"; 
     header += "User-Agent: Bot\r\n"; 
     header += "Host: " + host + "\r\n"; 
     header += "Accept: */*\r\n"; 
     header += "Content-Length: " + std::to_string(lenght) + "\r\n"; 
     //  header += "Expect: 100-continue\r\n"; // Curl send this but I think this is not required and might only complicate things  
     header += "Content-Type: multipart/form-data-stream; "; 
     header += "boundary=------------------------448eacc7eda1d5ef45\r\n\r\n"; 

     /* Appending first part of body to header */ 
     header += "------------------------448eacc7eda1d5ef45\r\n"; 
     header += "Content-Disposition: form-data; name=\"uploadedfile\"; "; 
     header += "filename=\"" + filename + "\"\r\n"; 
     header += "Content-Type: application/octet-stream\r\n\r\n"; 

     /* 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 = "\r\n------------------------448eacc7eda1d5ef45--\r\n"; 
         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 스크립트입니다 : 여기

내 코드입니다 :

831,703,210 그런 다음 내 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 - 계속"나는이 선택 사항입니다 생각하기 때문에. 그렇지 않으면 두 요청이 완전히 똑같은 것처럼 보입니다. 내가 할 수 있었던 모든 것을 트리플 점검했지만 지금은 거기 붙어있다.

입력 해 주셔서 감사합니다.

답변

0

당신은 잘못된 헤더를 사용하고 있습니다 :

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']); 
} 

당신도이 최소한의 오류 처리가 있다면, 당신은 할 것 존재하지 않는 파일을 옮기려고 할 때 나중에 찾아 내기보다는 시작하는 업로드가 없다고 들었습니다.

+0

멀티 파트/양식 데이터를 사용하는 것이 가장 먼저 시도한 것 중 하나입니다. multipart/form-data에 코드를 편집하고 PHP 스크립트에 오류 검사를 추가했습니다. 이제는 PHP 스크립트에서 오류 0이 발생하므로 파일을 업로드하지 않은 것처럼 보이기 때문에 조사를 계속할 것입니다. – 01BTC10

관련 문제