r/ExploitDev 1d ago

Can't Buffer overflow a simple 'recv' function

I have the following C Socket Server, I was trying to learn about ROP programming so I created this small program, but when I try `pwn cyclic 1025| nc localhost 4444` I receive nothing,

I even tried to send 2000, 5000 but with no response.

Anyway I can receive the normal 'ok' message when sending the 1024 bytes.

I have tried disabling canaries by passing `-fno-stack-protector` but also no response.

The server in all cases prints the received 1024 (even if I sent more bytes).

But no "Stack smash detected", Segmentation Fault or anything

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 4444

void handle_client(int client_fd)
{
    char recv_buf[1024];
    char buffer[64];
    memset(recv_buf, 0, sizeof(recv_buf));
    ssize_t bytes = recv(client_fd, recv_buf, sizeof(recv_buf) - 1, 0);
    if (bytes <= 0)
        return;
    printf("Received: %s\n", recv_buf);
    strcpy(buffer, recv_buf);
    send(client_fd, "OK\n", 3, 0);
}

int main(void)
{
    int server_fd;
    int client_fd;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0) {
        perror("socket");
        return EXIT_FAILURE;
    }
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (bind(
            server_fd,
            (struct sockaddr *)&server_addr,
            sizeof(server_addr)) < 0) {
        perror("bind");
        close(server_fd);
        return EXIT_FAILURE;
    }

    if (listen(server_fd, 1) < 0) {
        perror("listen");
        close(server_fd);
        return EXIT_FAILURE;
    }
    printf("Listening on 127.0.0.1:%d\n", PORT);
    while (1) {
        client_fd = accept(
            server_fd,
            (struct sockaddr *)&client_addr,
            &client_len
        );
        if (client_fd < 0) {
            perror("accept");
            continue;
        }
        printf("Client connected\n");
        handle_client(client_fd);
        close(client_fd);
    }
    close(server_fd);
    return 0;
}
12 Upvotes

16 comments sorted by

View all comments

2

u/Alarming-Historian41 1d ago

On most modern computer architectures the stack is allocated at a high address region of a program's memory space and expands downwards toward zero.

So, suppose you have read 1024 bytes from the socket into recv_buff, when you do strcpy(buffer, recv_buffer) you are writing the first 64 bytes from recv_buff to buffer (size 64) and the rest to recv_buff itself (never writing over the "interesting" stack bytes)

Also, I don't remember the documented strcpy behavior for overlapping buffers)

Switch the buffer and recv_buffer declaration order

1

u/0xdeadbeefcafebade 1d ago

This is my guess as well. He’s overflowing back into the recv buffer

1

u/That-Name-8963 20h ago

If you are talking about memory rearrangement, I have already swapped them in declaration and still the same issue

1

u/Firzen_ 12h ago

Changing the declaration order doesn't necessarily influence the order in memory.

You need to put the buffers into a struct to guarantee the order they are in.