I am facing a CTF challenge in which I have to conduct an attack using a ROP chain on this program below:

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <fcntl.h>

void setup() {
    setbuf(stdin, NULL);
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

void read_file(char* file, char* buffer) {
    int fd = open(file, O_RDONLY);
    read(fd, buffer, 0x200);

void main() {

    char buffer[0x200];

    puts("can you read flag.txt");

    read_file("./flag.txt", buffer);


    // puts(buffer);

My plan is to use ROP gadgets to call the read_file function again, and then to call the puts() function to print out the contents of the file. However, while I have the address in memory of the "./flag.txt" string to submit as the first parameter, I don't know what address to use for the second parameter(for char* buffer), or if it is even possible to do this.

Is my strategy even viable to begin with? Should I instead try to use ROP gadgets to call the base library functions(read, open, etc) instead? If my strategy is viable what address/space should I submit as the second parameter? Thanks.

For reference, this is the payload I tried submitting, but for which I got nothing:

payload = b"A" * 0x200
payload += b"B" * 0x8
payload += pop_rsi_pop_r15_ret_address + p64(0x7fffffffd950) + p64(flag_txt_string_address) + read_file_address
payload += pop_rdi_ret_address + p64(0x7fffffffd950) + plt_puts_address

Also, ASLR is enabled, but PIE is disabled.

1 Answer 1


You can read data into the .bss section of the program memory. It's readable and writable, and its position and size is defined by the executable itself, so having PIE disabled means it'll have a constant address.

Note that other data may also be stored in the .bss section, so you may need to add an offset when reading/writing your own data.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .