ModSecurity是一个入侵探测与阻止的引擎,它主要是用于Web应用程序所以也可以叫做Web应用程序防火墙.它可以作为Apache Web服务器的一个模块或单独的应用程序来运行。ModSecurity的目的是为增强Web应用程序的安全性和保护Web应用程序避免遭受来自已知与未知的攻击。本文主要介绍了针对开源WAF的一次渗透测试比赛中的思路。

1. 文章背景


ModSecurity SQL Injection Challenge(ModSecurity发起的一个针对开源WAF的一次渗透测试比赛)

http://www.modsecurity.org/demo/challenge.html

owasp-modsecurity-crs(OWASP针对ModSecurity编写的权威rule)

https://github.com/SpiderLabs/owasp-modsecurity-crs

2. 绕过思路分析


0×1:

目标应用系统: Acunetix Acuart Site

注入点: http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=1';

分析:

注入点很明显,通过测试可以知道这个注入点为数字型的注入,各种拼接都可以进行,但是普通的注入方法无一例外都会触发Mod的拦截规则。

这里采用mysql注释+CRLF绕过思路来进行注入

Mysql Comment Syntax

1) "#"用于单行注释

2) "– "用于单行注释,但要注意使用这种风格的注释符必须保证在"双横线"后面跟上一个"空格或控制符Control Char(控制符可以是空格, Tab制表符, 换行符Newline…)"(在使用的时候要注意URL编码,例如换行符的URL编码为%0D%0A)。关于这种"Double Dash注释符"在Mysql的官方文档中还有一点细节要注意(重点就是新版的Mysql解析引擎的改进避免了"基于减号导致的注释型注入")

3) "/* */"C风格的注释符,这种注释允许跨行注释(即允许在注释符中添加换行符,例如: /*..%0D%0A..*/)

mysql> SELECT 1+1;     # This comment continues to the end of line
mysql> SELECT 1+1;     -- This comment continues to the end of line
mysql> SELECT 1/* this is an in-line comment */  + 1;
mysql> SELECT 1+
/*
this is a
multiple-line comment
*/
1;

回到我们的注入点上来看看,我们使用mysql注释+CRLF来进行payload的构造(注意URL编码):

http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=0+div+1+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user

对其URL转义如下(注意换行符的解析):

0 div 1 union#foo*/*bar
select#foo
1,2,current_user

这句sql语句到了Mysql的解析引擎后会再次被解析为:

0 div 1 union select 1,2,current_user

可以看到,注释符之间进行了就近原则的交错组合,Mysql的Sql Parser则选择进行了忽略。

而ModSecurity CRS的规则如下:

注意到这个":replaceComments",我们知道,ModSecurity使用正则表达式来对Input Sql进行匹配检测,对Select、Union在敏感位置的出现都进行了拦截,但是ModSecurity有一个特点(或者叫优点),它会对输入进行"规范化",规范化的本意本来是防御"基于编码格式、解析顺序"的绕过的。

例如:

Mod可以抵抗这种形式的绕过:

SEL/**/ECT

在"规范化"之后,攻击者的本来目的就暴力在了Mod的检测下,这个时候再上规则就可以检测出来了,可以说,规范化是一个很好的防御思路。

但是这里却导致了另一种的"绕过"

问题的关键就在于ModSecurity对注释的理解和Mysql的解析引擎理解不同

(这似乎又回到了那个老问题: 同一个业务规则在不同的系统中的理解语义不同往往可能导致绕过)

:replaceComments
Unterminated comments will also be replaced with a space (ASCII 0x20). However, a standalone termination of a comment (*/) will not be acted upon.

也就是说,Mod会忽略前向半开注释并把后向半开注释当成单行注释(如果它没有找到后向半开的闭合注释时)

Mod的拦截日志中可以看到如下记录:

这样,在Mod看来,我们输入的Payload就变成了:

"0 div 1 union#foo* "

但是在Mysql看来,我们的sql语句其实是:

0 div 1 union select 1,2,current_user

防御方法:

1) 将原来的去除注释方法改为对SQL注释的匹配

#
# -=[ Detect SQL Comment Sequences ]=-
#
SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \
"(\/\*\!?|\*\/|\-\-[\s\r\n\v\f]|(?:--[^-]*-)|([^\-&])#.*[\s\r\n\v\f]|;?\\x00)" \
"phase:2,rev:'2.2.2',id:'981231',t:none,t:urlDecodeUni,block,msg:'SQL Comment Sequence Detected.',capture,logdata:'%{tx.0}',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.sql_injection_score=+1,setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"

但是这种方法从本质上又回到了"黑名单模式"的范畴中,有可能再次导致别的形式的绕过

2) 使用多行匹配(MultiMatch Action)+规范化方法(ReplaceComments)

SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "(?i:\buser_tables\b)" \
"phase:2,rev:'2.2.2',capture,multiMatch,t:none,t:urlDecodeUni,t:replaceComments,ctl:auditLogParts=+E,block,msg:'Blind SQL Injection Attack',id:'959918',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.

0×2:

目标应用系统: Cenzic Crack Me Bank

注入点: http://www.modsecurity.org/Kelev/php/accttransaction.php (POST)

注入Payload:

绕过分析:

这里采用了"碎片注入法(分段SQL注入)",或者是我们常说的"Split And Balance原则"。例如:

对于最简单的情况,可以使用字符串连接技术将较小的部分构造成一个字符串。不同的数据库使用不同的语法来构造字符串
oracle: 'selec'||'t'
sqlserver: 'selec'+'';
mysql: 'selec'+'t'
(这就是所谓的split and balance思想)
还要注意的是,加号和空格要先进行URL编码后再发送

这种技术的好处是可以将原本完整的Payload分成几段,利用ModSecurity对SQL语义的理解不全来进行规则绕过。常常用于进行"二值逻辑"的盲注推理。

回到我们的注入点上来看:

对于Mod来说,我们的攻击Payload为:

hUserId=22768&FromDate=a1%27+or&ToDate=%3C%3Eamount+and%27&sendbutton1=Get+Statement

而对于Mysql的解析引擎来说,它会自动去除、转换这些连接控制符,从而变成:

hUserId=22768&FromDate=a1%27+or&ToDate=<>amount and%27&sendbutton1=Get Statement

防御方法:

1) 这里有个概念叫"String Termination/Statement Ending Injection Testing"。攻击者在进行SQL注入检测的时候常常会使用一些"终止符",例如单引号、NULL等等,并通过观察页面是否报错来获知当前页面是否存在注入点。

为了防御这种注入,我们可以使用以下CRS规则:

#
# -=[ String Termination/Statement Ending Injection Testing ]=-
#
# Identifies common initial SQLi probing requests where attackers insert/append
# quote characters to the existing normal payload to see how the app/db responds.
#
SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \
"(?i:(\!\=|\&\&|\|\||>>|<<|>=|<=|<>|<=>|xor|rlike|regexp|isnull)|(?:not\s+between\s+0\s+and)|(?:is\s+null)|(like\s+null)|(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\))|(?:xor|<>|rlike(?:\s+binary)?)|(?:regexp\s+binary))" \
"phase:2,rev:'2.2.2',capture,t:none,t:urlDecodeUni,block,msg:'SQL Injection Attack: SQL Operator Detected',id:'981212',logdata:'%{TX.0}',severity:'2',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.notice_anomaly_score},setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"

2) 注意到我们的攻击Payload中一个Mysql逻辑运算符: "<>"。攻击者可以利用逻辑运算符进行"盲注推理"。例如,我们常见的传统盲注手段:

and (ascii(substring((select username from admin),1,1)))>97
(这种就是将逐个字符转成ASCII值然后用二分查找法进行猜测) UPDATE table SET views = '1' WHERE id = -2441 OR (ORD(MID((SELECTIFNULL(CAST(FirstName AS CHAR),0x20) FROM nowamagic.`tb2` ORDER BY id LIMIT 1,1),2,1))>112)#
(同样的思路,换了一个函数)

为了防御这种注入,我们可以使用以下CRS规则

#
# -=[ SQL Operators ]=-
#
SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \
"(?i:(\!\=|\&\&|\|\||>>|<<|>=|<=|<>|<=>|xor|rlike|regexp|isnull)|(?:not\s+between\s+0\s+and)|(?:is\s+null)|(like\s+null)|(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\))|(?:xor|<>|rlike(?:\s+binary)?)|(?:regexp\s+binary))" \
"phase:2,rev:'2.2.2',capture,t:none,t:urlDecodeUni,block,msg:'SQL Injection Attack: SQL Operator Detected',id:'981212',logdata:'%{TX.0}',severity:'2',tag:'WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.notice_anomaly_score},setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"

0×3:

目标应用系统: IBM demo.testfire.net site

注入点: http://www.modsecurity.org/bank/login.aspx (POST)

注入Payload:

这里使用了HPP(HTTP Parameter Pollution)注入技术,关于HPP,有很多相关的资料:

http://www.80sec.com/%E6%B5%85%E8%B0%88%E7%BB%95%E8%BF%87waf%E7%9A%84%E6%95%B0%E7%A7%8D%E6%96%B9%E6%B3%95.html

http://www.freebuf.com/articles/web/5908.html

http://hi.baidu.com/aullik5/item/860da508a90709843c42e2ca

http://hi.baidu.com/4b5f5f4b/item/abc28dda72c100f154347f36

https://www.owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf

回到我们的注入Payload上来,我们注意到after这个字段出现了3次,其中后2次的出现其实是产生了逗号的作用,以此来进行绕过。要注意的一点是,HPP攻击和具体的应用系统环境有很大关系,在不同的系统上表现不太一致:

https://www.trustwave.com/spiderlabs/advisories/TWSL2011-006.txt

防御方法:

我们可以采用以下的CRS规则来防御HPP攻击:

# -=[ Rules Logic }=-
# The ruleset below is not looking for attacks directly, but rather is a crude normalization
# function that mimics ASP.NET with regards to joining the payloads of parameters with the
# same name.  These rules will create a new TX:HPP_DATA variable that will hold this data.
# If you have enabled PARANOID_MODE, then this variable data will also be searched against
# attack filters.
#
# -=[ References ]=-
# http://tacticalwebappsec.blogspot.com/2009/05/http-parameter-pollution.html
#  
SecRule ARGS "^" "chain,phase:2,t:none,nolog,pass,capture,id:'900032',rev:'2.2.9',setvar:tx.%{matched_var_name}=+1"
  SecRule TX:/^ARGS:/ "@gt 1" "chain,t:none"
    SecRule MATCHED_VARS_NAMES "TX:(ARGS:.*)" "chain,capture,t:none,setvar:tx.hpp_names=%{tx.1}"
      SecRule ARGS ".*" "chain,t:none,capture,setvar:tx.arg_counter=+1,setvar:'tx.hppnamedata_%{tx.arg_counter}=%{matched_var_name}=%{tx.0}'"
        SecRule TX:/HPPNAMEDATA_/ "@contains %{tx.hpp_names}" "chain,setvar:tx.hpp_counter=+1,setvar:tx.hpp_counter_%{tx.hpp_counter}=%{matched_var}"
          SecRule TX:/HPP_COUNTER_/ "ARGS:(.*)?=(.*)" "capture,setvar:'tx.hpp_data=%{tx.hpp_data},%{tx.2}'"

0×4:

目标应用系统: Cenzic Crack Me Bank

注入点: http://www.modsecurity.org/Kelev/php/accttransaction.php (POST)

注入Payload:

思路分析:

这里采用了"半开注释符(Unterminated Comments)"+"Mysql注释符代码执行(MySQL Comment Extensions for conditional code execution)"技术来进行绕过

半开注释符我们之前说过了,是利用Mod的replaceComments来进行敏感关键字的绕过。而"Mysql注释符代码执行"则是Mysql的一个运行机制。

Mysql的官方文档如下:

MySQL Server supports some variants of C-style comments. These enable you to write code that includes MySQL extensions, but is still portable, by using comments of the following form:
(Mysql允许C风格的注释符,并允许在其中写入Mysql扩展,即插入可执行sql代码)
/*! MySQL-specific code */

Mysql的Paerser引擎会自动解析这种格式中的sql代码,同时其他的数据库(例如MSSQL、ORACLE会自动忽略这些注释),也就是说,这是Mysql特有的特性:

select 1 union/*! select */version();
select 1 union/*!32302 select */version();

防御方法:

和 0×1 一样,采用使用多行匹配(MultiMatch Action)+规范化方法(ReplaceComments)

0×5:

目标应用系统: IBM demo.testfire.net site

注入点: http://www.modsecurity.org/bank/login.aspx (COOKIE)

注入Payload:

注入分析:

注入点并没有什么特别的,关键在与这里采用了COOKIE注入

防御方法:

关于这个COOKIE注入,我想延伸几点想法:

  1. 在注入点的选择中,HTTP中的任何字段、任何位置都"有可能"产生SQL注入,这里只能说有可能,因为是否能否产生注入,和具体的应用系统的环境有关,即应用系统会使用哪些字段带入数据进行执行

  2. "GPCS"的作用:

    在php.ini中有一项配置: variables_order = "GPCS"(具体的顺序和字符和具体你的配置有关)

如果在php.ini中开启了"register_globals"这个选项,则PHP会按照"$GET"、"$POST"、"$COOKIE"、"SERVER"的顺序来把这些全局数据中国的子键抽取出来,注册到本地变量的的符号表中,即全局变量本地化。这个顺序很重要,这往往是很多本地变量覆盖漏洞利用的关键

3.  HTTP中的任意位置都有可能产生SQL注入,看下面的例子:

http://sebug.net/vuldb/ssvid-8427

Create New Admin Exploit FOR php168 v4.0SP

这个例子中,注入点发生在"X-FORWARDED-FOR"这个字段中,这本来是应用系统用来做记录登录用户的IP、代理IP的业务功能,但是因为没有过滤严格,导致了注入的发生

0×6:

目标应用系统: Acunetix Acuart Site

注入点: http://www.modsecurity.org/testphp.vulnweb.com/listproducts.php?artist=1'

注入Payload:

http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=%40%40new%20union%23sqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsql%0Aselect%201,2,database%23sqlmap%0A%28%29

Payload分析:

这里采用了"Mysql注释(MySQL Comment )"+"换行绕过(New Line trick )"的组合方法来进行Mod的绕过(本质上是对Mod所使用的正则表达式的绕过)

在Mod看来,我们的Payload如下:

http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=@@new union#sqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsqlmapsql
select 1,2,database#sqlmap
()

然而,当这段SQL代码进入Mysql的解析引擎的时候,Mysql看到的是这样的形式:

artist=@@new union select 1,2,database()

防御方法:

我们知道,SQL(Structure Query Language)是一种及其灵活的命令式语言,各个元素之间的组合可以有很多种,采用正则REGEX的方法来进行匹配常常无法做到精确指导,为了解决这个问题,我们有两种思路

1) 采用高阶的SQL解析方法,例如AST:

http://www.cnblogs.com/LittleHann/p/3495602.html

2) 改进正则,采用敏感关键字匹配的方法

SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \
"([\~\!\@\#\$\%\^\&\*\(\)\-\+\=\{\}\[\]\|\:\;\"\'\´\’\‘\`\<\>].*){4,}" \
"phase:2,t:none,t:urlDecodeUni,block,id:'981173',rev:'2.2.1',msg:'Restricted SQL Character Anomaly Detection Alert - Total # of special characters exceeded',capture,logdata:'%{tx.1}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.sql_injection_score=+1,setvar:'tx.msg=%{rule.msg}',setvar:tx.%{rule.id}-WEB_ATTACK/RESTRICTED_SQLI_CHARS-%{matched_var_name}=%{tx.0}"

0×7:

目标应用系统: Acunetix Acuart Site

注入点: http://www.modsecurity.org/testphp.vulnweb.com/listproducts.php?artist=1'

注入Payload:

Payload分析:

这里采用了"Mysql错误回显"+"Tab键分隔绕过"的组合方法来进行Mod的绕过,这里的关键点是没有使用传统的空格来进行"Split And Balance"。

这里要提的是黑名单思想,对"Split And Balance"的防御如果采用黑名单容易产生绕过:

https://docs.google.com/document/d/1rO_LCBKJY0puvRhPhAfTD2iNVPfR4e9KiKDpDE2enMI/edit?pli=1#Allowed_Intermediary_Character_30801873723976314

如果一定要采用黑名单,则必须进行严格的代码审计和测试,保证黑名单的完整性

例如,在Mysql中允许的分隔符为:
09
0A
0B
0C
0D
A0

防御方法:

采用完整的"准空格分隔符"黑名单CRS

SecRule REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \
"(?i:(?:,.*[)\da-f(\"|'|`|´|’|‘)](\"|'|`|´|’|‘)(?:(\"|'|`|´|’|‘).*(\"|'|`|´|’|‘)|\Z|[^(\"|'|`|´|’|‘)]+))|(?:\Wselect.+\W*from)|((?:select|create|rename|truncate|load|alter|delete|update|insert|desc)\s*\(\s*space\s*\())" \
"phase:2,capture,multiMatch,t:none,t:urlDecodeUni,t:replaceComments,block,msg:'Detects MySQL comment-/space-obfuscated injections and backtick termination',id:'981257',tag:'WEB_ATTACK/SQLI',tag:'WEB_ATTACK/ID',logdata:'%{TX.0}',severity:'2',setvar:'tx.msg=%{rule.id}-%{rule.msg}',setvar:tx.anomaly_score=+5,setvar:'tx.%{tx.msg}-WEB_ATTACK/SQLI-%{matched_var_name}=%{tx.0}',setvar:'tx.%{tx.msg}-WEB_ATTACK/ID-%{matched_var_name}=%{tx.0}'

3. 总结


Blacklist filtering is not enough — 不要依赖黑名单机制

应该使用多种方法进行纵深防御

https://www.trustwave.com/application-security/

对输入验证采用安全模型,包括规范化、数据类型,数据格式,数据长度

https://www.trustwave.com/web-application-firewall/

WAF作为一个防御手段,从某种程序上来说只是增加了攻击者的攻击成本,并不能从根本上解决注入的发生,要解决注入漏洞的产生,保护敏感数据,必须多管齐下,从应用系统、WAF、数据库防火墙的角度去思考

ModSecurity SQL注入攻击 – 深度绕过技术挑战的更多相关文章

  1. ModSecurity SQL注入攻击

    ModSecurity是 一个入侵探测与阻止的引擎,它主要是用于Web应用程序所以也可以叫做Web应用程序防火墙.它可以作为Apache Web服务器的一个模块或单独的应用程序来运行.ModSecur ...

  2. PHP的SQL注入攻击的技术实现以及预防措施

    最近在折腾 PHP + MYSQL 的编程.了解了一些 PHP SQL 注入攻击的知识,总结一下经验.在我看来,引发 SQL 注入攻击的主要原因,是因为以下两点原因: 1. php 配置文件 php. ...

  3. 2017-2018-2 20179205《网络攻防技术与实践》第十一周作业 SQL注入攻击与实践

    <网络攻防技术与实践>第十一周作业 SQL注入攻击与实践 1.研究缓冲区溢出的原理,至少针对两种数据库进行差异化研究 缓冲区溢出原理   在计算机内部,输入数据通常被存放在一个临时空间内, ...

  4. 【web渗透技术】渗透攻防Web篇-SQL注入攻击初级

    [web渗透技术]渗透攻防Web篇-SQL注入攻击初级 前言不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的S ...

  5. 实例讲解 SQL 注入攻击

    这是一篇讲解SQL注入的实例文章,一步一步跟着作者脚步探索如何注入成功,展现了一次完整的渗透流程,值得一读.翻译水平有限,见谅! 一位客户让我们针对只有他们企业员工和顾客能使用的企业内网进行渗透测试. ...

  6. 防止SQL注入攻击的一些方法小结

    SQL注入攻击的危害性很大.在讲解其防止办法之前,数据库管理员有必要先了解一下其攻击的原理.这有利于管理员采取有针对性的防治措施. 一. SQL注入攻击的简单示例. statement := &quo ...

  7. SQL注入攻击

    SQL注入攻击是黑客对数据库进行攻击的常用手段之一.随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候, ...

  8. SQL注入攻击的种类和防范手段

    观察近来的一些安全事件及其后果,安全专家们已经得到一个结论,这些威胁主要是通过SQL注入造成的.虽然前面有许多文章讨论了SQL注入,但今天所讨论的内容也许可帮助你检查自己的服务器,并采取相应防范措施. ...

  9. SQL注入攻击三部曲之高级篇

    SQL注入攻击三部曲之高级篇 经过了入门篇和进阶篇的学习,相信诸位想要破解一般的网站是没有什么问题了,但是先别得意.正所谓学海无涯,技术的进步也是没有止境的.SQL注入是一个看起来简单,但是变数很多的 ...

随机推荐

  1. python 获取当前文件夹下所有文件名

    os 模块下有两个函数: os.walk() os.listdir() 1 # -*- coding: utf-8 -*- 2 3 import os 4 5 def file_name(file_d ...

  2. hdu 1238 Substrings(kmp+暴力枚举)

    Problem Description You are given a number of case-sensitive strings of alphabetic characters, find ...

  3. 算法练习:求字符串的最长重复子串(Java实现)

    1. 求字符串的最长重复子串 例如:aaaaaaaaabbbbcccaaassscvvv这里面的最长重复子串为aaaaaaaaa 算法思路:算法时间复杂度(O(n)) 1. 将这一个字符串先转成cha ...

  4. hdu 2516(Fibonacci博弈博弈)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2516 Problem Description 1堆石子有n个,两人轮流取.先取者第1次可以取任意多个, ...

  5. Developing JSF applications with Spring Boot

    Developing JSF applications with Spring Boot Spring Boot can leverage any type of applications, not ...

  6. 基于Jenkins,docker实现自动化部署(持续交互)

      前言 随着业务的增长,需求也开始增多,每个需求的大小,开发周期,发布时间都不一致.基于微服务的系统架构,功能的叠加,对应的服务的数量也在增加,大小功能的快速迭代,更加要求部署的快速化,智能化.因此 ...

  7. Windows下使用Diskpart格式化U盘

    步骤 进入Diskpartdiskpart 列出所有的磁盘list disk 选择磁盘select disk 清楚clean 创建主分区creat partition parimary 激活当前分区a ...

  8. react-native中的TextInput

    TextInput是一个允许用户输入文本的基础组件.它有一个名为onChangeText的属性,此属性接受一个函数, 而此函数会在文本变化时被调用.另外还有一个名为onSubmitEditing的属性 ...

  9. 逻辑回归 代价函数J关于系数theta求导

    J=-y*loga-(1-y)*log(1-a) 梯度下降,求dJ/d_theta_j

  10. 将分支代码合并到master和将master代码合并到dev

    两种合并分支的方法: 都保证在合到的那个分支上面:A合并到B,即保证当前在B分支上. A merge B是把A中的改动放到B分支上,B merge A是把B中的改动merge到A中,例如把master ...