Use After Free(弊研究室の某課題について考える10日目)

はじめに

この記事は弊研究室の某課題を考える10日目の記事です。

9日目に続いた今日もHeapのお話Use After Freeです。

Use After Freeの概要

いったんFreeしたメモリを後から参照することによって発生する脆弱性

  1. 領域を確保
  2. 領域を解放
  3. 新たに領域確保
  4. 領域に任意アドレスの書き込み
  5. ポインタ型を読み込みread/write

3番目までは普通のmalloc/freeですが、4番目からが問題です。

f:id:kataware8136:20171213011422p:plain

3番目までを図にしました。ここでptr->bが新しく確保した領域のbと同じ位置を指し示します。

よって新しい領域に対する書き込みを前の構造体のポインタのptrを用いて書き換えることができます。

ではこの書き換えるものが今回はint型でしたがそれが関数のポインタなら?任意の関数に書き換えてしまえばそれを実行できてしまうということになります。

Use After Freeの例

#include<stdio.h>
#include<malloc.h>

struct Buf{
        int a;
        int b;
};

int main(){
        struct Buf *buf;
        struct Buf *newbuf;
        buf=(struct Buf *)malloc(sizeof(struct Buf));
        buf->a=10;
        buf->b=20;
        printf("%d %d\n", buf->a, buf->b);
        free(buf);
        newbuf=(struct Buf *)malloc(sizeof(struct Buf));
        newbuf->a=100;
        newbuf->b=200;
        printf("%d %d\n", newbuf->a, newbuf->b);
        buf->a=30; //Use after free
        printf("%d %d\n", newbuf->a, newbuf->b);
        return 0;
}

このプログラムの実行結果ですが次のようになります

$ ./a.out
10 20
100 200
30 200

mallocの領域確保ですが同じサイズの領域を確保する際にすでに解放された領域を使うことがよくあります。これは新たな領域からサイズを確保するよりもはやく確保することができるからです。mallocの領域確保の方法はいろいろなところで行われているのでそこを参照してください。

こんかいはbufを解放した後に、同じサイズのnewbufを確保しています。この時に同じ領域のヒープが使われているため解放したbufに残ってるポインタを利用して書き換えてしまうことができます。

この脆弱性を利用して攻撃できるようになりますが、そのお話は攻撃編でやりたいです。