Giter VIP home page Giter VIP logo

zakkak / turnin Goto Github PK

View Code? Open in Web Editor NEW

This project forked from ucsb-cs/turnin

15.0 5.0 7.0 107 KB

turnin is a utility that enables students to turnin assignments using the command line. Requires a setup where each class has a unix account in the computer infrastructure of the school/university.

License: GNU General Public License v3.0

Makefile 5.58% Shell 13.66% Python 11.33% C 67.75% Roff 1.68%
hacktoberfest

turnin's Introduction

turnin

turnin is a unix utility that allows students to turn in their homework from the School/Univerity's computers.

Setup

The root user needs to download (git clone) all files in this repository and run make; make install; make clean. Please note that this cannot be done with sudo(8) and needs access to the actual root user. This series of bash(1) commands will compile, place, and activate the turnin binary. It will also create a man(1) entry with further instructions for both professors and students.

Requirements

  • gcc
  • make
  • tar
  • libssl-dev on debian
  • git (For download and updates)

Usage for professors/TAs

A set of unix computers is required that both classes and students have access to from a unique unix account. Each class has a home directory and it can create a folder named TURNIN. If this folder is available then other unix accounts can turn in exercises to it. In order to create an assignment, i.e. Homework1, the class has to create a folder inside the TURNIN folder with the name Homework1. Please refer to the manpage (man turnin) for further details.

History

The program was first written in 1993 and then updated to fix some bugs and security flaws. The original repository can be found here. It has been created for SunOS 5 but then with updates it was able to run in modern operating systems like debian as well. On September 1st, 2014, Foivos S. Zakkak and Antonios A. Chariton (zakkak & DaKnOb) forked the original repository and created a new version of turnin that is more secure (it patches several exploitable vulnerabilities found in the original code, minimizes attack surface), faster and with partly extended functionality. On September 6th, 2014, official support for SunOS5 has been dropped. A few days later, both projects went under the GPL v3 License after contacting all the authors and agreeing to it.

Development

Pull requests

Pull requests are always welcome. Please respect the coding style and stay consistent. In your pull request you should describe exactly what it solves and in the case that you use some complex logic/algorithm please describe it as well. We would really appreciate if you could provide comments and explain most if not all parts of your code so we can maintain it, understand it and perform (security) audits. Since this is a suid-root binary, we need to establish the maximum amount of security possible for a C-written program.

New release

To create a new release first create an annotated tag (it would be nice if it is also signed), i.e.,

git tag -s -m "Release v2.2.2" v2.2.2

and then push the tags

git push --tags

Versions

The version for development builds is retrieved automatically through the command git describe at compilation time (see target version in the Makefile).

However since the .git directory is not contained in the release archives we still need to manually upgrade the version in src/version.sed.me before a release.

turnin's People

Contributors

zakkak avatar daknob avatar alx01011 avatar bboe avatar innerout avatar ru108 avatar

Stargazers

Xuanshu Luo avatar Paul avatar  avatar  avatar Georgios Leventopoulos avatar Vasileios Geladaris avatar Vaggelis Yfantis avatar Polyvios Pratikakis avatar George Kaklamanos avatar George Nikitakis avatar George Z. Zachos avatar Yuankai Z avatar  avatar  avatar

Watchers

 avatar James Cloos avatar Norman Gaywood avatar  avatar  avatar

turnin's Issues

Remove "/" from assignment name?

Is / really necessary for assignment names?
Currently one can invoke turnin(1) with the following arguments:

turnin lab1/assignment2@course report.pdf

but should this be possible?

Invalid username

Script uses invalid username when using su (checks the parent process owner).

TurnIn fails to get UID/EUID under certain conditions

There is a chance turnin can fail to get a UID/EUID and shutdown for the calling user. The following Python script demonstrates the issue:

#!/usr/bin/python
import os
os.system("echo aaaaaaaaaaaa | turnin assignment@class file.c")

The result on a Debian system is:

Cannot get user's login (uid XXXX)

Potential NULL pointer dereference

The following code converts a UNIX timestamp into a formatted time:

struct tm *t = localtime(&clock);

According to the man page, localtime() can return NULL in case there's a problem. This would lead to the following line to dereference a NULL pointer, which can lead to crashes.

Moreover, the fields used are not guaranteed to exist, and may be overwritten at any point. I think the overwrite risk is minimal, given the limited lifetime and lack of concurrency, but it seems localtime_r() exists for that reason.

A couple if statements to check for NULL should do the trick here to remove the memory issue.

SymLink / Relative Path Check Bypass

A malicious attacker can bypass the symlink recursive check as well as the relative path (contains ..) check by doing the following procedure:

  1. Turn In a normal file, e.g. hello.c
  2. While prompting for confirmation run the following commands:
mv hello.c h.c
ln -s /etc/passwd hello.c
  1. Press y on the turnin binary to proceed.
  2. The binary blindly trusts the user since all files have been checked previously.

turnin creates different SHA-256 for same tgz file

It has been found that by turning in the same file using turnin(1) results in different SHA-256 hashes being produced. The problem is not with the code of turnin(1) calculating the hash, but with the tgz files being created. Running tar(1) with the same file always produces the same output file.

Multiple Submission of file allowed

A user can include a file an infinite amount of times (unless limited by a maxfilesize) in his turnin by passing it as an argument multiple times.

Graceful Error in blank submit

Currently turnin fails badly when making a blank submission (tar subprocess crash). Since it's easily detectable, why not make it fail gracefully with a properly formatted error message?

turnin web front-end

Now that our web server uses the proper user, maybe we should consider implementing a turnin web front-end that whould work along with the command line version.

Later we could completely avoid setuid writing a python script accessing the web front-end from the command-line (this should be a new project however).

TurnIn fails to SHA digest a tgz file

A basic installation of turnin fails to digest a tgz file with the following output:

turnin: Failed to open turned in file '/home/course/TURNIN/ask1/user-1.tgz' for sha-digest.
Please notify the Instructor or a TA.

This happens because there are no unix permissions for the user to read the tgz file.

Remove unnecessary privilege escalation

In order to make the following function call:

pwd = getpwuid(user_uid);

to get the user name, turnin elevates privileges to root (for a brief period of time). Maybe this function call required the root access in the past, as it returned the user plaintext password, or their hash, but now that this moved to /etc/shadow and /etc/passwd is world-readable, perhaps it's no longer required, and we'd be able to get a response without becoming root.

We need to test the behavior of this function on the Debian 11 systems that are currently deployed, and if it works without elevated privileges, to remove the code (to become root, and then user) around it.

Max Turnins Bypass

An ill-intentioned individual can bypass the "max turnin limit" check using the following trick:

  1. When there's only 1 turnin left, open 2 copies of turnin with the same arguments (assignment, class, files)
  2. Press y on both binaries acknowledging this is your last turnin available.
  3. When both binaries ask you for file confirmation, press y on both. The second one will fail with an error that it can't write the file.
  4. You can use turnin once more and overwrite the latest turnin. The LOGFILE will look as below:
turnin 1.9: username -  1 09/18/14 18:03   2
turnin 1.9: username -  2 09/18/14 18:03   2
turnin 1.9: username -  3 09/18/14 18:03   2
turnin 1.9: username -  4 09/18/14 18:04   2
turnin 1.9: username -  5 09/18/14 18:04   2
turnin 1.9: username -  6 09/18/14 18:04   2
turnin 1.9: username -  7 09/18/14 18:05   2
turnin 1.9: username -  8 09/18/14 18:05   2
turnin 1.9: username -  9 09/18/14 18:05   2
turnin 1.9: username - 10 09/18/14 18:06   2
turnin 1.9: username - 10 09/18/14 18:08   2

It is currently unknown whether this allows n+1 turnins or unlimited. Further tests will follow.

turnin out of folder bug

An attacker can use turnin(1) to turn in arbitrary files outside of an assignment folder. More specifically, by running:

turnin @course file.c

the binary will turnin the file to:

/home/course/TURNIN//.

which of course translates to:

/home/course/TURNIN/

Undefined behaviour with malicious LIMITS file

A malicious user can cause turnin(1) to have undefined and unpredictable behaviour by issuing the following commands to a bash(1) shell:

mkdir TURNIN
mkdir TURNIN/undef
ln -s /dev/urandom TURNIN/undef/LIMITS
turnin undef@username file.c

where username is the user's username and file.c any valid and legal file.

Segmentation Fault With Maliciously Crafted Input

A malicious attacker can exploit the recursive symlink algorithm within the turnin binary to cause a segmentation fault. The issue is caused upon entering the following commands into a bash shell:

ln -s a b
ln -s b a
turnin assignment@class a

It is not clear whether this flaw is exploitable by an attacker but heuristics (i.e. I am too bored to try) show it's not.

Unhandled tar(1) crash

Under specific circumstances tar(1) can crash with flag 0xff00 if the binary turnin(1) has no permission to read the input file.
Additionally, turnin(1) can crash if it has no permission to read the files during isbinaryfile() called by addfile().
A (race condition triggering) bash(1) script to demo these vulnerabilities can be found here:

printf "y\ny" | turnin hw@course hello.c & sleep 0.001; chmod 000 hello.c

where 0.001 should probably be changed until you manage to reproduce both crashes. For minimum values that sleep(1) cannot perform, use an echo(1) and maybe an echo(1) to a file.

Program Crashes Upon Malicious Action

One can cause turnin to crash by turning in a proper file and upon requesting confirmation of the files remove the file or change its name. There will be further investigation because it is believed this can cause out of bounds read/write.

Potential NULL pointer dereference

In the following part of the code, we get the username that is associated with a particular user ID:

user_name = strdup(pwd->pw_name);

The code correctly copies the string to a local variable, as according to the man page, there's no guarantee that this value will continue to live there long term (it's in the static section, and is overwritten by subsequent calls).

However, according to the man page, there's no guarantee that the struct fields that are pointers to char arrays will not be NULL. Although in practice this always worked, I think it's much safer to introduce a NULL check to avoid a dereference.

Add Support for Automatic Grading

turnin is a homework submission platform. We can add support for automatic grading during submission.

If the AUTOGRADE file is present, turnin should refer to the LIMITS file and look for the following configuration value:

autograde ~/tests/ask1_test.py
  • If this line is not discovered in the LIMITS file, turnin should continue normally.
  • If the file does not exist, turnin should continue normally.
  • If the file is not executable, turnin should continue normally.

If this line is discovered, turnin should execute, as the class account, the script at ~/tests/ask1_test.py.
It should pass as the first argument the full path of the submitted file, in the .tgz format. After the script execution finishes, the stdout will be presented to the user, while the stderr of the script will be sent to /dev/null or ignored.

This feature can be used to automate grading and let the students know, during the submission, of any incorrect things they did or things they should pay attention to. Optionally, this script can also return a grade estimation for the current submission.

Every time the script runs, it must log a new entry to the SHA256 file containing the SHA-256 hash of the script, marked appropriately so as to be distinguished from student submissions.

Edit: Add bullets @zakkak

MaxTurnIns Bypass Race Condition

A bypass for the maxturnins argument on LIMITS file has been found possible under certain conditions.
More specifically, a user that has initiated a turnin that is legal in terms of quota can finalise the submission even if the course changes the maxturnins during the process of submission.
Steps to reproduce:

  1. Run turnin assignment@course file.c as user and finalise the turn in
  2. Run turnin assignment@course file.c as user and wait before pressing the final y.
  3. Run echo "maxturnins 1" > ~/TURNIN/assignment/LIMITSas course.
  4. Press y as user on the second turnin.

Abuse of this race condition is detectable through the LOGFILE and SHA256 since it marks the submission sequentially, even if it's over the maximum allowed limit.

turnin can use 100% of CPU

It has been observed that the binary turnin(1) and more specifically turnin v2.3.1-2 under unknown conditions consumes 100% of the CPU and the process hangs forever.

Add bash script in submissions folder

Due to the changes happening usually in the way we compress (and therefore decompress) files, I recommend turnin to create a bash(1) script that accepts one argument, the username and decompresses the file in the proper directory.
Example:
check user9999
And:

#!/bin/bash
mkdir $1 2> /dev/null > /dev/null
tar <args> $1 -C ./$1/
echo "Decompressed $1 to ./$1"

Relative / Absolute Path Bypass

A bypass has been found that allows a malicious user to avoid checks for absolute paths in the files turned it..
Calling turnin with the following bash(1) command can result in bypass of the check:

turnin assign@class `printf "a\b/etc/passwd"`

Weak Permission Set for turnin_extract

When running turnin_extract, all files are decompressed into folders with default permissions (755 on most systems). Additionally, the files inside are (by default) deployed as 744. This can cause users to be able to read extracted assignments if the assignment and/or TURNIN folder have a weak permission set.
This may not be the expected behavior, so either warn the instructors / TAs or run the proper chmod(1)'s.

Add support for late submissions

We could add support to turnin(1) for late submissions that will notify the student the assignment is due but he can still turn in with a small penalty on the final grade. For example, add file DUE when the assignment is due and from that point on alert all users turning in that n days have passed since that and there will be let's say n*10 % penalty on the final grade. The LOCK file shall close the turnin just as it does now.

turnin performs terribly under heavy load

Tests of turnin(1) under "heavy" load have been completed. More specifically, the following bash(1) command was issued to a debian computer:

while [ true ]; do printf "y\ny" | turnin assignment@course file.c & done

Although it is extremely unlikely that such a case will happen in a production environment, the whole purpose was to simulate race conditions, i.e. how turnin(1) handles submissions by users simultaneously.
Parts of the LOGFILE and the SHA256 files can be seen below:

LOGFILE

turnin 2.0: student -  1 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  2 09/21/14 15:07   1
turnin 2.0: student -  3 09/21/14 15:07   1
turnin 2.0: student -  4 09/21/14 15:07   1
turnin 2.0: student -  6 09/21/14 15:07   1
turnin 2.0: student -  6 09/21/14 15:07   1
turnin 2.0: student -  7 09/21/14 15:07   1
turnin 2.0: student -  6 09/21/14 15:07   1
turnin 2.0: student -  6 09/21/14 15:07   1

SHA256

4a28ddd1770703177a9e2dafd1e9a3aea3de53723e39d539de8358fff25d0afb  student-4.tgz
4a28ddd1770703177a9e2dafd1e9a3aea3de53723e39d539de8358fff25d0afb  student-5.tgz
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  student-6.tgz
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  student-18.tgz
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  student-18.tgz
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  student-6.tgz
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  student-18.tgz

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.