The WPICTF 2018 “Shell-JAIL-1” challenge:
After downloading the linked private key and connecting to the remote server we are dropped into a limited user account and the directory /home/pc_owner
. In that folder there are only 3 files – including flag.txt to which our user has no access:
The access
file is basically a setuid executable which will run as the pc_owner
user. The source of the executable is also available in access.c
(mirror here). The program will take all arguments and pass it to system()
unless it contains blacklisted strings, relevant parts in the source code:
int filter(const char *cmd){ int valid = 1; valid &= strstr(cmd, "*") == NULL; valid &= strstr(cmd, "sh") == NULL; valid &= strstr(cmd, "/") == NULL; valid &= strstr(cmd, "home") == NULL; valid &= strstr(cmd, "pc_owner") == NULL; valid &= strstr(cmd, "flag") == NULL; valid &= strstr(cmd, "txt") == NULL; return valid; } int main(int argc, const char **argv){ setreuid(UID, UID); char *cmd = gen_cmd(argc, argv); if (!filter(cmd)){ exit(-1); } system(cmd); }
This means passing id
to it will work but cat flag.txt
will not:
Of course circumventing that filter is rather easy, the *
wildcard is forbidden, but ?
is not. We can use those wildcards to read flag.txt by passing cat "fla?.tx?"
to it:
The flag is: wpi{MaNY_WayS_T0_r3Ad}