问题
I've been struggling with Windows Sockets for two days not being able to just use write to socket as in Linux it is. I want to write my own shellcode and I'm playing around how to redirect stdout, stdin to socket handle (that's where my playings come from). I use Windows 7 x64, build 7601 if it's necessary. Here's my code
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main (int argc,char ** argv)
{
// boring code starts
if (argc < 2)
{
printf("Usage getstdhandle <ip> <port> ");
}
WSADATA wsadata;
int result = WSAStartup (MAKEWORD(2,2),&wsadata);
if (result != NO_ERROR)
{
printf("error with wsastartup");
}
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons (atoi(argv[2]));
server.sin_addr.s_addr = inet_addr (argv[1]);
SOCKET soc = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (soc == INVALID_SOCKET)
{
printf("Error with creating socket");
}
if (connect(soc,(struct sockaddr *)&server,sizeof(server)) == SOCKET_ERROR)
{
printf("Problem with connecting");
}
// boring code ends
const char * buf = "Tekscik \n"; // know it's not really good in new C standards
const char buf[] = "Test\n"; // not working also, shouldn't have any influence
bool isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10,NULL,NULL);
DWORD ret = GetLastError();
printf("%.08x",ret);
closesocket(soc);
WSACleanup();
return 0;
}
This is how i run my program
C:\Users\Domin568\Desktop>getstdhandle 192.168.56.1 5555
Tekscik
00000057 <---- Error code in hex
On my second machine i just run nc to listen for this data like this :
15:14|domin568[21] ~ $ nc -l -v -p 5555
Connection from 192.168.56.101:50328
15:15|domin568[22] ~ $
I get error code 0x57 which is :
ERROR_INVALID_PARAMETER 87 (0x57) The parameter is incorrect.
Local network traffic (any data sent, pure connections handshakes and FIN)
What could be the reason of that ? I know it's not good way for sending data but MSDN says it should be possible.
回答1:
from WriteFile documentation
lpOverlapped [in, out, optional]
A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with
FILE_FLAG_OVERLAPPED
, otherwise this parameter can be NULL.
but are socket function create file (socket this is file handle, it point to FILE_OBJECT structure) with FILE_FLAG_OVERLAPPED
? this is undocumented and you cannot control this. so you need use OVERLAPPED as parameter for WriteFile.
if use WSASocket we already here have dwFlags option and can set or not set WSA_FLAG_OVERLAPPED
(which is equivalent of FILE_FLAG_OVERLAPPED
for CreateFile
)
why OVERLAPPED structure is required when we use hFile opened with FILE_FLAG_OVERLAPPED
flag (no FO_SYNCHRONOUS_IO
flag in FILE_OBJECT) ?
WriteFile call ZwWriteFile
look for
PLARGE_INTEGER ByteOffset [in, optional]
parameter of ZwWriteFile - but it optional only if we open file as synchronous. if file opened in asynchronous i/o mode - this parameter is mandatory.
from wrk source code
if (fileObject->Flags & FO_SYNCHRONOUS_IO) {
}
else if (!ARGUMENT_PRESENT( ByteOffset ) && !(fileObject->Flags & (FO_NAMED_PIPE | FO_MAILSLOT))) {
//
// The file is not open for synchronous I/O operations, but the
// caller did not specify a ByteOffset parameter. This is an error
// situation, so cleanup and return with the appropriate status.
//
if (eventObject) {
ObDereferenceObject( eventObject );
}
ObDereferenceObject( fileObject );
return STATUS_INVALID_PARAMETER;
}
this is exactly your case when you call
WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10,NULL,NULL);
NtWriteFile
return to you STATUS_INVALID_PARAMETER
which converted to win32 error ERROR_INVALID_PARAMETER
but next code will be worked ok.
OVERLAPPED ov = {};
BOOL isSent = WriteFile((HANDLE)soc,(LPCVOID)buf,(DWORD)10, 0, &ov);
because in this case ByteOffset
will be point to &ov.Offset
however for send data to socket much more better use WSASend
回答2:
MSDN says it should be possible.
Does it really? The socket handles documentation states:
A socket handle can optionally be a file handle in Windows Sockets 2. A socket handle from a Winsock provider can be used with other non-Winsock functions such as ReadFile, WriteFile, ReadFileEx, and WriteFileEx.
Note the word "optionally".
Per this discussion:
WriteFile with SocketHandle Fails
...
Not sure how you can read that page and think that it is a good idea to use a socket handle with ReadFile et al.
Let's start with this sentence "A socket handle can optionally be a file handle in Windows Sockets 2". That can be read two different ways:
You can optionally use any socket handle as a file handle for ReadFile and friends
A socket provider can optionally provide dual-use sockets that work with ReadFile as well as the socket functions.
Unfortunately there is not enough information in that article to conclusively decide whether #1 or #2 is correct. However the fact that ReadFile returns ERROR_INVALID_PARAMETER (per Mike Danes' comment) I am going to assume that #2 is the correct interpretation and your network socket is not also a file handle. (Note that frequently the MSDN documentation is written more from the perspective of the team that implemented API than from a consumer of the API. If you look at it in that light, #2 is the more likely interpretation -- I will agree that it is annoying because a consumer of the API is more likely to understand the sentence as #1)
来源:https://stackoverflow.com/questions/43939424/writefile-with-windows-sockets-returns-invalid-parameter-error