FD

image 139.png

fd是编译好的可执行二进制文件。

fd.c 是源文件查看:

#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;
        }
        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;

}

*int atoi(const char str)可以查看此文章

就是将输入的值取整。该函数返回转换后的长整数,如果没有执行有效的转换,则返回零。

0x1234 是十六进制,因为有0x或0X。

read() 这行代码调用的是 Linux/Unix 系统提供的 系统调用 read,原型如下:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

从文件描述符 fd 所指向的“文件”(可以是普通文件、管道、socket、终端等)中尝试读取最多 count 个字节,放入用户态缓冲区 buf 中。

0=stdin, 1=stdout, 2=stderr, 3+=open()返回

不同 fd 时的具体行为(重点):

fd 值对应的资源read() 行为举例
0标准输入 (stdin)通常连接到终端键盘
→ 没输入时阻塞等待
→ 用户输入后回车 → 返回实际字节数(含 \n)
→ 用户按 Ctrl+D → 返回 0(EOF)
1标准输出 (stdout)几乎永远不能读,返回 -1,errno=EBADF(坏的文件描述符)
2标准错误 (stderr)同上,不能读
3+open() 返回的 fd取决于打开的是什么文件/管道/socket

所以解题思路:

当!strcmp(“LETMEWIN\n”, buf)为0时,也就是buf=LETMEWIN\n时,才能得到flag

len = read(fd, buf, 32);fd要等于0才能从终端输入字符。

所以fd = atoi( argv[1] ) - 0x1234;所以atoi( argv[1] ) = 0x1234

./fd 4660
LETMEWIN

FD

image 139.png

fd is a compiled executable binary file.

The source file fd.c is as follows:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]) {
    if (argc < 2) {
        printf("Please pass a number as an argument.\n");
        return 0;
    }
    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 input/output.\n");
    return 0;
}

The atoi() function can be learned more about. It converts a string to an integer. If the conversion is not successful, it returns 0.

The value 0x1234 is in hexadecimal format (indicated by the 0x prefix).

The read() function is a system call provided by Linux/Unix. Its prototype is:

#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

It attempts to read at most count bytes from the file specified by the file descriptor fd and stores them in the user-space buffer buf.

  • 0: Standard input (stdin): Usually connected to the terminal keyboard.
    • If no input is provided, it blocks until the user presses Enter.
    • After the user enters a value and presses Enter, the function returns the number of bytes read (including the \n character).
    • If the user presses Ctrl+D, it returns 0 (indicating the end of the file).
  • 1: Standard output (stdout): Almost always returns -1 with errno = EBADF (invalid file descriptor).
  • 2: Standard error (stderr): Similar to stdout, it cannot be read.
  • 3+: The file descriptor returned by open(): The behavior depends on the type of file/pipe/socket that was opened.

Solution approach:

The program checks if buf contains the string LETMEWIN\n. If it does, it retrieves the flag value by executing the system("/bin/cat flag") command.

The read() function is used to read a string of up to 32 bytes from the standard input (stdin). The file descriptor fd must be set to 0 to read from the terminal.

Therefore, the expression fd = atoi(argv[1]) - 0x1234 is used to calculate the correct file descriptor value.

Example usage:

./fd 4660
LETMEWIN