I have a website that uses ManageEngine Service Plus and it has a SQL injection vulnerability

the linksays that with the help of the following url we would be able to inject postgresql commands to get the complete control of the system:

/reports/CreateReportTable.jsp?site=0 AND
3133=(SELECT 3133 FROM PG_SLEEP(1))

I don't understand the part 3133=(SELECT 3133 FROM PG_SLEEP(1)). I know the databse is Postgresql but when I try to find an appropriate injection command on PayloadsAllTheThings or other sites I cannot anything in that format.

Can you give me tips on how to dump table names or so since it doesn't seem to execute any function other than pg_sleep()?

  • The part between parentheses is a subquery. – Sjoerd Feb 19 at 9:47
  • Could you please tell me how I can get the version using that subquery? – hasanou59 Feb 19 at 10:12
  • What makes you think that the SQL Injection attack isn't working? Do you get an error when you use the example URL? – Dijkgraaf Feb 19 at 11:50
  • SQLi works perfectly, the sleep function does the work it is supposed to do. I just cannot type exact query to get the table of credentials since it is postgresql and I already searched about subquries but it still doesn't ring a bell. Could you please write that exact query so I could understand it. What gets me most confused is the 3133= before the subquery. – hasanou59 Feb 19 at 14:08
  • All it is doing is creating a true condition of 3133=3133 in the Where clause and proving that you can inject other SQL queries into the querystring, which is a SQL Injection vunerability. – Dijkgraaf Feb 19 at 22:57

Attack type

0 AND 3133=(SELECT 3133 FROM PG_SLEEP(1))

is a method of blind sql injection. Blind sqli applies time to determine the content of the database, mostly using if conditions (cf eg SQL Injection Cheat Sheet - Conditional Time Delays). So if you are interested in using this technique for dumping explore it for postgreSQL.

3133 is a fixed value and PG_SLEEP(1) delays the execution at the database for 1 second. So basically this sums up to 0 AND true with a waiting time of 1 second. You can use this to check if this type of sqli is feasible.

Basically the referenced exploit is a proof-of-concept to show that sql injection is possible.

It is also listed as CVE.

How does it work?

I don't know what CreateReportTable.jsp does exactly. I only found this documentation. The documentation mentions:

To use Advanced Filtering, select the column name such as, Requester name, region site and so on from the combo box.

which probably belongs to a filtering of sites/branches you can define for your company. So this could be an entry point to check where the issue is in your application. Analyse the query parameter site.

If you want a deeper understanding what SELECT 3133 FROM PG_SLEEP(1) does you can verify it using docker:

sudo docker run -it --rm --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_USER=user -e POSTGRES_DB=db -d postgres:latest 

sudo docker exec -ti <your_docker_container_id> psql "dbname=db user=user password=mysecretpassword"

psql is the interactive terminal for postgres. In this terminal \dt gives you an overview about what the function pg_sleep does. The function has a return data type of void - which is basically an empty value. Enter select * from pg_sleep(1) to double check that. This will bring you back after one second and outputs no value. At first the function is applied and then the select is executed. The empty return value then can be overwritten by choosing a constant:

select 1 from pg_sleep(1);

psql example

Mitigation possibilities and impact

The CVE states

SQL injection vulnerability in reports/CreateReportTable.jsp in ZOHO ManageEngine ServiceDesk Plus (SDP) before 9.0 build 9031 allows remote authenticated users to execute arbitrary SQL commands via the site parameter.

So probably it is fixed with an update to a higher version.

The other thing is that you have to consider a possible breach depending if and how long your site has been exposed.


I think you misunderstand what SQL Injection is. It means you can run arbitrary SQL command against the database and do things like inserts into tables or drop tables. It does not necessarily mean that it returns a results from a function when you run the SQL Injection, but that if it used to insert into a table it could serve up what was injected to another user.

The example in your question could be changed to use an OR instead of an AND, and that could list all sites, instead of just the site=0 which would prove that it is in fact vulnerable, rather than it not throwing an error as the test expects.


/reports/CreateReportTable.jsp?site=0 OR 3133=(SELECT 3133 FROM PG_SLEEP(1))

The example they gave is designed not to do any harm.

All the AND 3133=(SELECT 3133 FROM PG_SLEEP(1)) in the example does is produce a TRUE condition in the WHERE clause.

  • The thing is in the link I embedded it is mentioned that this is an sql injection attack and AFAR you can see the table names and credentials by doing it, like using UNION SELECT and seeing the rows retrieved. – hasanou59 Feb 19 at 11:55
  • 1
    @hasanou59 According to the ExploitDB article the site parameter is prone to SQLi, meaning that any input given in that parameter is not properly validated/sanitized allowing you to escape the intended query by providing your own query. Now from your statement it’s not clear to me whether the sleep condition is triggered or not. If it is and you struggle to find a valid query by copy pasting payloads from all across the Internet will bring you nowhere since you probably don’t even care to understand what each of them is doing. 1/2 – cyzczy Feb 19 at 12:04
  • What I would suggest, run sqlmap with Wireshark/tcpdump in the background and see what worked and try to understand what was achieved with a given query. Asking here for help in they way you ask will not bring you a single step further nor will it make you a pentester. First learn how things work then learn how certain conditions can allow you compromise a system/application 2/2. – cyzczy Feb 19 at 12:07
  • @hasanou59 Yes, the MySQL one returns the Username in one of the rows returned. However the Postgress example does not return any extra rows (except possible with using an OR). As cyzczy said, you have to understand how the application works to create a SQL injection attack to do what you want. Again, what makes you think that the SQL Injection example isn't working? – Dijkgraaf Feb 19 at 12:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.