A remotely exploitable vulnerability was found in the framework core component. Exploitation of this bug does not require authentication and will lead to remotely exposed potentially sensitive information from the Publique! database. Particularly, an attacker can extract usernames and passwords needed to authenticate to the administrative interface and gain full control of the web site and (depending on certain conditions) the server itself.
It was found that Publique! does not validate properly the "sid" parameter value and causes this input to be interpreted as a SQL command instead of ordinary data.
The following error is displayed when a simple quote is added after the original value (sid=1'):
Lua error on configuration (or extension)
Error: unexpected type to index table
function _ERRORMESSAGE at C code
function _initStart at
main of //S/Publique/work/carregal/sys/reader/start.lua
function old_dofile at C code
function dofile at
main of string " write("") dofile(ReaderDir.."start.bin")
write("\n") det", 2
function dostring at C code
function: 0042E0D0 at
function: 0042A8C8 at
function: 0035CE60 at
function: 0035D650 at
main of //S/Publique/work/carregal/cgi/cgilua/cgilua.conf/cgilua.lua
CGILua 3.2.1 CGI 1995-99.
After several tests, it appears that the framework is executing two SQL queries sequentially and the error is issued by the first query. It is unlikely that the bug could be exploited using conventional methods. However, it is possible to extract information from the database using Time-Based Blind SQL Injection.
Basically, this consists of using some time-taking SQL operations (e.g. the BENCHMARK() MySQL built-in function) that will delay server responses if the specific condition is satisfied. By monitoring the response time, it is possible to know if the conditional expression is True or False.
Using this technique, it is possible to extract the usernames and passwords needed to authenticate into the Publique! management interface. Database information can be retrieved by testing the ASCII value of each character returned by the injected query.
For example, the following payload may be used to extract the ASCII value of the first character returned by the query:
This query first concatenates "F_Login" and "F_Password" columns of the internal table "T_Actor" and returns the first row (thanks to the "LIMIT 1 OFFSET 0" statement). Then, it checks if the ASCII value of the first character returned is greater than 97 (the letter 'a'). If the condition is satisfied it will trigger the BENCHMARK function, causing a significant delay in the server response (approximately 4 seconds using our test lab). By repeating the query with different values to compare to, it is possible to retrieve the exact value of the first character. The complete string can be extracted by reproducing the process for each character.
Although the password is encrypted, it is possible to discover it. After further investigation and reverse engineering the Lua pre-compiled binaries of Publique! framework, it appears that the encryption algorithm used is reversible (i.e. is not a hashing function).
Basically, before storing passwords in the database, the framework encrypts them with two CGILUA  built-in functions: "crypt()" and "encode()". Since the key used by the encryption algorithm is hard-coded in Publique! binaries, it is possible to retrieve the plain password from the cypher by using the two following built-in functions: "decrypt()" and "decode()".
These plain credentials could be used to log into the Publique! management interface, enabling the framework upload functionality, and eventually permitting an attacker to install malicious code on the remote server, for example.
Find out how to use a SQL injection vulnerability scanner.