FEAT:🚩 Pwnable.kr 「fd (Toddler's Bottle)」
file descriptor の理解を試すpwn問題
FEAT:🚩 Pwnable.kr 「fd (Toddler's Bottle)」
20260727-pwnable_kr-toddlers_bottle-fd
Summary
本問は,file descriptor の理解を試すpwn問題です.
- Category: Pwn
- Description: Mommy! what is a file descriptor in Linux?
- Tools & TechStack:
- C
- Release: N/A
階層構造
1
2
3
4
5
6
7
.
├── fd
├── fd.c
├── flag
└── readme
0 directories, 4 files
ソースコードの調査
メインの操作を抜き出すと,大まかに以下の処理で構成されています.
buf[32]で 32byte の文字列型の配列を用意する.atoi(argv[1])でコマンドライン引数で入力された Ascii文字列を整数に変換 し,そこから0x1234 = 4660を減算したものを,fd (file descriptor) として設定する.read(fd, buf, 32)で,fdに応じた入力で,buf[]に書き込まれる.buf[]内の文字列が,"LETMEWIN\n"と一致すれば,cat flagされる.
fd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
if(argc<2){
printf("pass argv[1] a number\n");
return 0;
}
// ascii を int に変換し.0x1234 を引く
int fd = atoi( argv[1] ) - 0x1234;
int len = 0;
len = read(fd, buf, 32);
if(!strcmp("LETMEWIN\n", buf)){
printf("good job :)\n");
setregid(getegid(), getegid());
system("/bin/cat flag");
exit(0);
}
printf("learn about Linux file IO\n");
return 0;
}
解法
atoi( argv[1] ) - 0x1234; より,10進数で 4660 を入力することで,fd を 0 (標準入力) に設定することができます.
その後,標準入力の待ち受けで "LETMEWIN" と入力し,Enter キーを押すと改行文字 \n が入力データに付加されます.
よって,その後の !strcmp("LETMEWIN\n", "LETMEWIN\n") が 1 となり,flag が表示されます.
1
2
3
4
fd@ubuntu:~$ ./fd 4660
LETMEWIN
good job :)
Mama! Now_I_understand_what_file_descriptors_are!
Post-Mortem & Dead ends
毎回思うんだけど,!strcmp(A, B) って書き方分かりづらくない?
普通に読んだら,否定演算子 ! があるせいで,非一致を判定してるように見えるから,個人的には strcmp(A, B) == 0 の書き方の方が好み.
References
N/A
This post is licensed under CC BY 4.0 by the author.