Bug ID | 1209587 |
---|---|
Summary | AUDIT-FIND: lastlog2: SQL injection via user names |
Classification | openSUSE |
Product | openSUSE Tumbleweed |
Version | Current |
Hardware | Other |
OS | Other |
Status | NEW |
Severity | Normal |
Priority | P5 - None |
Component | Security |
Assignee | security-team@suse.de |
Reporter | wolfgang.frisch@suse.com |
QA Contact | qa-bugs@suse.de |
CC | kukuk@suse.com, matthias.gerstner@suse.com, wolfgang.frisch@suse.com |
Depends on | 1209238 |
Found By | --- |
Blocker | --- |
A possible SQL injection was found in lib/lastlog2.c [1]: ``` 183 if (asprintf (&sql, "CREATE TABLE IF NOT EXISTS Lastlog(Name TEXT PRIMARY KEY, Time INT, TTY TEXT, RemoteHost TEXT);" 184 "REPLACE INTO Lastlog VALUES('%s', %llu, '%s', '%s');", 185 user, (long long int)ll_time, tty ? tty : "", 186 rhost ? rhost : "") < 0) ``` This unfiltered concatenation of variables allows an attacker to craft malicious inputs that lead to arbitrary SQL execution. The `Name` field is most promising candidate for injection. Linux systems can be surprisingly lax with respect to user name formats. Steps to reproduce: ``` # Create a user with a malicious name useradd --badname "$username" # Log in once su -l "$username" ``` Example usernames: 1. username="',NULL,NULL,NULL);--" Segmentation fault in /usr/bin/lastlog2. 2. username="',0,,);--" This user is invisible to lastlog2. 3. username="',1,'','');DROP TABLE Lastlog;--" Clears the log. Even though it might seem far-fetched to encounter such unusual user names in the wild, there are conceivable scenarios where this might be the case, e.g. hijacked LDAP servers (in conjunction with pam_ldap), or systems management software which allows lesser privileged administrators to create arbitrary unprivileged users. Standard file-based authentication limits user names to 32 characters but other authentication mechanisms might accept up to 256 characters [2], which could lead to arbitrary file writes as root, using sqlite's ATTACH DATABASE statement [3]. Suggested improvements: 1. Use prepared SQL statements instead of concatenation [4] 2. Constrain the columns with NOT NULL [1] https://github.com/thkukuk/lastlog2/blob/6a3244c3a0cf5bc631d518463e58a44eef9c1f08/lib/lastlog2.c#L183 [2] /usr/include/bits/local_lim.h (LOGIN_NAME_MAX) [3] https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLite%20Injection.md#remote-command-execution-using-sqlite-command---attach-database [4] https://www.sqlite.org/c3ref/stmt.html