GCI - Fedora Project - Exploiting a Buffer Overflow Vulnerability

Posted on December 15, 2019* in ctf-writeups


We are given a binary to exploit. By running checksec on it, we see that the binary has the following protections: [show-line-numbers]: false

Canary                        : No
NX                            : Yes
PIE                           : Yes
Fortify                       : No
RelRO                         : Partial

Because the binary has NX, we cannot place executable shell code in a buffer and then jump to it. PIE allows the code section of the binary to be located anywhere in memory. This means that we don't know the address of functions within the binary; however, we still know relative offsets.

Reverse Engineering

Dump of assembler code for function main:
   0x0000000000001145 <+0>:     push   rbp                                  # Setup Stack
   0x0000000000001146 <+1>:     mov    rbp,rsp                              
   0x0000000000001149 <+4>:     sub    rsp,0x110                            # Allocate 0x110 bytes on stack
   0x0000000000001150 <+11>:    mov    DWORD PTR [rbp-0x104],edi            # Copies edi into stack offset 0x104
   0x0000000000001156 <+17>:    mov    QWORD PTR [rbp-0x110],rsi            # Copies rsi into stack offset 0x110
   0x000000000000115d <+24>:    mov    rax,QWORD PTR [rbp-0x110]            # Copies value of pointer into rax
   0x0000000000001164 <+31>:    add    rax,0x8                              # Adds size_t
   0x0000000000001168 <+35>:    mov    rdx,QWORD PTR [rax]                  # Copies the value of the pointer [rax + 8] into rdx
   0x000000000000116b <+38>:    lea    rax,[rbp-0x100]                      # Loads the address of [rbp - 0x100] into rax
   0x0000000000001172 <+45>:    mov    rsi,rdx                              # rsi = rdx
   0x0000000000001175 <+48>:    mov    rdi,rax                              # rdi = rax
   0x0000000000001178 <+51>:    call   0x1030 <strcpy@plt>                  # Calls strcpy(rsi, rdi) ; strcpy ([rbp - 0x100], argv[1])
   0x000000000000117d <+56>:    lea    rax,[rbp-0x100]                      # Loads address of [rbp-0x100] into rax
   0x0000000000001184 <+63>:    mov    rdi,rax                              # rdi = rax
   0x0000000000001187 <+66>:    call   0x1040 <puts@plt>                    # puts(rdi)
   0x000000000000118c <+71>:    mov    eax,0x0                              # return 0
   0x0000000000001191 <+76>:    leave                                       
   0x0000000000001192 <+77>:    ret                                         
End of assembler dump.
Continue Reading

nactf 2019 - Dr. J's Group Test Randomizer #2: BBOB

Posted on September 22, 2019* in ctf-writeups


This is it. The last group test of the year. Dr. J patched his prng again so numbers won't repeat, so I guess Leaf won't get to know the group test pairs ahead of time... oh WEYL. Who knew middle square could make such a good prng?

nc shell.2019.nactf.com 31382

We're also given the source of the running application:

#include <stdio.h>
#include <stdint.h>
#include <sodium.h>
#include <stdbool.h>
#include <string.h>
#define NUM_CORRECT 10

uint64_t x = 0, w = 0, s = 0xb5ad4eceda1ce2a9;

uint32_t nextRand() {
  w += s;
  x = x*x + w;
  x = (x>>32) | (x<<32);
  return x % (1UL<<32);

void init_seed() {
  uint64_t r1 = (uint64_t) randombytes_random();
  uint64_t r2 = (uint64_t) randombytes_random();
  x = (r1 << 32) + r2;
  r1 = (uint64_t) randombytes_random();
  r2 = (uint64_t) randombytes_random();
  w = (r1 << 32) + r2;

void print_flag() {
  FILE *f = fopen("flag.txt", "r");
  char flag[100];
  fgets(flag, sizeof(flag), f);
  printf("%s\n", flag);
  fflush( stdout );

const char *messages[NUM_CORRECT] =
{ "\nHmm... lucky guess...\n",
  "\nWow, that was coincidental!\n",
  "\nWhat? How did you guess that?\n",
  "\nThat's right, but you won't be able to guess right again!\n> ",
  "\nStrangely, that's correct...\n"

int main() {
  setvbuf(stdout, NULL, _IONBF, 0);
  printf("\nWelcome to Dr. J's Random Number Generator v3! We have received reports of "
  "a vulnerability involving repetition of output. This vulnerability has since been patched, "
  "and Dr. J's RNG is now 100%% secure. \n"
  "[r] Print a new random number \n"
  "[g] Guess the next ten random numbers and receive the flag! \n"
  "[q] Quit \n\n");
  char line[100];
  while (true) {
    printf("> ");
    fgets (line, sizeof(line), stdin);
    line[strcspn(line, "\n")] = 0;

    if (!strcmp("r", line)) {
      uint64_t r = nextRand();
      printf("%lu\n", r);
    if (!strcmp("g", line)) {
      printf("\nGuess the next ten random numbers for a flag! "
      "The chance of guessing all ten numbers correctly is 1/(2*10^96). I hope you're lucky! "
      "\nEnter Guess 1:\n> ");

      for (int i = 0; i < NUM_CORRECT; i++) {
        uint64_t guess = 0;
        fgets (line, sizeof(line), stdin);
        sscanf(line, "%lu", &guess);
        if (guess == nextRand()) {
          int m = randombytes_uniform(5);
          printf("%s", messages[m]);
          if (i < NUM_CORRECT-1) {
            printf("Enter Guess %d:\n> ", i+2);
          else {
            printf("What sorcery is this? That's impossible! I guess you deserve this flag:\n");
        else {
          printf("That's incorrect. Get out of here!\n");
    if (!strcmp("q", line)) {
  return 0;
Continue Reading

picoCTF 2018 - Lambdash

Posted on October 18, 2018* in ctf-writeups


C? Who uses that anymore. If we really want to be secure, we should all start learning lambda calculus. http://2018shell2.picoctf.com:41367


An extremely large payload to the interpreter results in an node.js error message

PayloadTooLargeError: request entity too large
    at readStream (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/raw-body/index.js:155:17)
    at getRawBody (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/raw-body/index.js:108:12)
    at read (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/body-parser/lib/read.js:77:3)
    at urlencodedParser (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/body-parser/lib/types/urlencoded.js:116:5)
    at Layer.handle [as handle_request] (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/express/lib/router/index.js:317:13)
    at /problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/express/lib/router/index.js:335:12)
    at next (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/express/lib/router/index.js:275:10)
    at expressInit (/problems/lambdash-3_0_867a993b23b277b2e144cc3e2d73f6e4/node_modules/express/lib/middleware/init.js:40:5)
Continue Reading
Switch to Dark Mode
Switch to Light Mode