Srdnlen CTF 2022 Rat Pack

Srdnlen CTF 2022に参加していました。 解き損ねたpwnのRat Packという問題のメモです。 問題 典型的なheap問でよくある、メニューがあって操作ができるタイプの問題です。 書き方はかなりCっぽいですが、C++でコンパイルされています。 まずはGhidraとかで適当にreversingをしておきます。 rat構造体 この問題の中心となるratという構造体は以下のような構造になっています。(変数名は公式Writeup1で公開されているソースコードに準拠) 1struct rat { 2 struct rat** pack; // スタック上のstruct rat* packへのポインタ 3 void(*dialogue)(struct rat*); // base pointer 4 char name[16]; // ratの名前 5 int maxlen; // ratの名前の最大長 6} 7 8// |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f| 9// +00h |pack-----------|dialogue-------| 10// +10h |name---------------------------| 11// +20h |maxlen---------| | 操作 この構造体に対して可能な操作は以下の通りです。ただし、packaddrはratを管理するサイズ16の配列です。 createRat() 1void createRat(struct rat** packaddr) { 2 // Allocate and initialize 3 struct rat* newRat = (struct rat*) malloc(sizeof(struct rat)); 4 newRat->maxlen = NAME_LEN; 5 newRat->dialogue = dialogue; 6 newRat->pack = packaddr; 7 name(newRat); 8 9 // Place rat in pack. 10 for (int i = 0; i < MAX_RATS; i++) { 11 if (packaddr[i] == NULL) { 12 packaddr[i] = newRat; 13 return; 14 } 15 } 16 printf("You ran out of rat space!\n"); 17 free(newRat); 18} sizeof(struct rat) = 0x28 のサイズの領域を確保(実際は0x30) これをnewRatとする。 newRatのメンバ変数を初期化し、name(newRat)で名前を設定 packaddrを先頭から走査し、空いている箇所にnewRatを設定 もし領域が空いていなければfree(newRat) greetRat() ...

2022-10-09 · 3 min · 564 words · Laika