Python代写 | CSCI 3202 Remote edition Fall 2020



We show two example CTF challenges related to COMP2700 Assignment 1 on software and system security. These examples are meant to demonstrate a typical approach to vulnerability discovery (albeit in a much simplified setting, compared to real-world software systems) that you may find useful in solving the challenges in Assignment 1. The write-ups for these two challenges also serve as examples of the kind of details that we expect to see in your report for Assignment 1.

The example challenges must be downloaded and installed in the lab VM, in the home directory of user admin2700, using the following commands:

$ wget

$ extract-lab ctf-examples.tar.gz

We assume that the attacker is the user bob in the lab VM. If you want to attempt these challenges yourself,make sure you login as bob, using the command su bob.

Example 1: easy_flag

This challenge is located in the directory /home/admin2700/ctf-examples/easy_flag. Let us first check what files and directories are there and their permissions:

bob@comp2700_lab:/home/admin2700/ctf-examples/easy_flag$ ls -al

total 40

dr-xrwxr-x 4 admin2700 admin2700 4096 Sep 4 05:39 .

drwxrwxr-x 4 admin2700 admin2700 4096 Sep 4 11:40 ..

-rwsrwxr-x 1 admin2700 admin2700 12904 Sep 4 11:41 easy_flag

-rw-rw-r– 1 admin2700 admin2700 1646 Sep 4 10:56 easy_flag.c

-rwxrwxr-x 1 admin2700 admin2700 169 Sep 4 05:24

drwx—— 2 admin2700 admin2700 4096 Sep 4 07:07 private

drwxrwxr-x 2 admin2700 admin2700 4096 Sep 4 11:42 public

We see that easy_flag is an SUID binary, owned by admin2700, so we expect that this program will have the effective UID of admin2700, hence will be able to access the private directory. Running the program easy_flag reveals that it requires a password as its (only) argument. Let’s try supplying it with some arbitrary password:

$ ./easy_flag hello

Wrong password. This incident has been logged.

The output does not provide much information, other than the password is wrong. We could try to bruteforce the password, but at this stage it’s probably better to examine the source code to gain a better understanding of what the program does.

The main function in the program appears rather simple. It sets the current directory to a fixed location (/home/admin2700/ctf-examples/easy_flag), checks whether the user input (the first argument to the program, i.e., argv[1]) hashes to the same hard-coded crypt hash (in the authenticate function). If not, the program appears to execute a command that invokes the bash script, which adds an error message to the file public/error.log, and exit. Otherwise, it displays the file

./private/flag.txt using the cat command. From the latter, we now know that the flag is located in the directory private. However, looking at the output of ls above, that directory is inaccessible to anyone other than admin2700. So it seems that we will need to somehow leverage one or more bugs in the program to make it display the flag.

By examining the source code, we see that there are at least three potential vulnerabilities:

Vulnerability #1: The command executed when the password is wrong is encoded in the buffer error. It appears to take input from the environment variable USER.

line 58: char error[256] = “./ $USER “;

One potential exploit could be to inject a command through this environment variable.

Vulnerability #2: The password (argv[1]) is appended to the command string error:

line 77: strcat(error, pass);

This is potentially another site for injecting a shell command.

Vulnerability #3: The command to display the flag uses cat without specifying the full path to the

program (/bin/cat).

line 83: execute(“cat ./private/flag.txt”);

If we change the PATH environment variable, we could trick the program to execute any command we choose.

Note that the above may not be an exhaustive list of vulnerabilities. In particular, we did not look into potential issues with some functions from standard C library, such as execl and crypt. Checking the manual pages for execl and crypt (using man 3 execl and man 3 crypt) did not turn up any useful information, other than they seem to be applied correctly. So we’ll proceed first with analysing the three potential vulnerabilities identified above.

A quick inspection on the code shows that Vulnerability #3 is not really exploitable, since it is only reachable once a correct password is inputted, at which point, we would have obtained the flag anyway.

Let’s test to see if we can exploit Vulnerability #1 above. Looking at the script, it seems that it expects two arguments, the first being the user name and the second being the (incorrect) password. So if we set the USER environment variable to the string “bob a; ls ; “, and enter hello as the password,the combined string that will be passed to the execute command in line 78 would be:

./ bob a; ls ; hello

Let’s test this to see if we can get the ls command to be executed.

$ env USER=”bob; ls ; ” ./easy_flag hello

Wrong password. This incident has been logged.


But the ls command did not seem to get executed. Examing the error.log we see:

[04/09/2021 12:17:46] Wrong password attempt by bob;: ls

It seems that the part of the string $USER after ; is removed. There is no obvious explanation from the nonlibrary functions why this is the case, so perhaps this is caused by the execl command. Attempting different combination of command symbols (e.g., | or &&) did not seem to work either.

This leaves us with the remaining vulnerability (#2), i.e., to inject a command through the password string. A  simple test shows that this works:

$ ./easy_flag ‘hello; whoami’

Wrong password. This incident has been logged.


So we have now a way to get the program to execute any command we want under the privilege of admin2700 as the output of whoami command shows. Let us now attempt to cat the flag:

$ ./easy_flag ‘hello; cat private/flag.txt’

Wrong password. This incident has been logged.

cat: pri: No such file or directory

It seems that the path private/flag.txt is truncated. Going back to the C code, we see that the password length is restricted to 14 characters (we need to reserve 1 character for the null terminator). So we must fit all of the injected command within the 14 character limit. There are several alternatives:

Instructor note: We include more than one solution here for pedagogical purposes — in your solution to the actual assignment problems, you don’t need to list all solutions; explaining one solution per problem is enough.)