汇编工具:http://www.ollydbg.de/
数据库管理工具破解教程:https://www.jianshu.com/p/e6665db44328
解密解码工具:http://ctf.ssleye.com/
攻击工具:http://www.ctftools.com/down/
攻防博客:
https://www.hackjie.com/blog
攻防平台
https://adworld.xctf.org.cn/task
lsof -i TCP:3307
关闭SELinux:
setenforce 0
开启SELinux:
setenforce 1
栈溢出:栈溢出的原理是覆盖函数的返回地。函数调用过程中,函数的返回地址保存在栈里面。所以栈溢出的思路就是把栈里面的返回地址覆盖,然后替换成攻击者想要的地址。因为栈是往下增加的,先进入栈的地址反而要大,这种机制更方便的提供了漏洞产生的可能性。
缓冲区溢出的危害:缓冲区溢出攻击,可以导致程序运行失败、系统关机、重新启动,或者执行攻击者的指令,比如非法提升权限。
缓冲区漏洞对应函数:C/C++语言中像strcpy函数还有strcat()、sprintf()、vsprintf()、gets()、scanf() 以及在循环内的getc()、fgetc()、getchar()等这些常见的函数都会造成缓冲区溢出漏洞。
mybatis中的#和$的区别:
1、#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
如:where username=#{username},如果传入的值是111,那么解析成sql时的值为where username="111", 如果传入的值是id,则解析成的sql为where username="id".
2、$将传入的数据直接显示生成在sql中。
如:where username=${username},如果传入的值是111,那么解析成sql时的值为where username=111;
如果传入的值是;drop table user;,则解析成的sql为:select id, username, password, role from user where username=;drop table user;
3、#方式能够很大程度防止sql注入,$方式无法防止Sql注入。
4、$方式一般用于传入数据库对象,例如传入表名.
5、一般能用#的就别用$,若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。
6、在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。
【结论】在编写MyBatis的映射语句时,尽量采用“#{xxx}”这样的格式。若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止SQL注入攻击。
根据数据库返回内容是否回显,可以将 SQL注入分为可回显注入和不可回显注入。从名字可以看到,可回显注入意思是数据库返回的结果可以在网页前端看到。不可回显是无法看到数据库反馈结果,需要通过其他手段判断(如时间延迟等)。
可回显的注入
可回显的注入包含联合查询注入和报错注入。下面分别介绍。
1. 联合查询注入
联合查询的名字来自他的查询方式关键字 UNION。在sql语言的语法中,通过关键字 union可以将联合查询结果输出。在可回显的注入中,通过联合查询我们可以查询出 数据库信息、数据表信息、数据字段信息等,是比较简单易学、容易理解和上手的注入方法。当一个网页代码有如下所示的查询片段,并将查询结果某种方式回显到界面时,可以进行SQL联合注入。
SELECT id FROM users WHERE user_id='$id'
在通常输入的位置,我们进行修改输入以下参数,
?id=-1'union+select+1+--+
因为单引号,闭合了前面的单引号,拼接后SQL查询语句就变成了如下
SELECT id FROM users WHERE user_id='-1'union select 1 --'
服务器对于加好进行了转义,在用户查询页面输出了不充分查询内容。在select语句后面,可以查询的内容很多,获取很多信息。通常需要染过一些特定字符。
2. 报错注入
报错注入的原理是利用数据库的某些机制,通过人为制造错误条件,将查询结果通过错误信心显示出来。MySQL中通常用到 updatexml、floor 和 exp 三个函数。
首先了解下updatexml()函数
UPDATEXML (XML_document, XPath_string, new_value);
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。
第三个参数:new_value,String格式,替换查找到的符合条件的数据 。
当我们输入一下语句时,
select name from user where id=1 and updatexml(1,concat('~',(select database()),'~'),3);
因为 updatexml的 第一个和第三个参数不满足 参数要求格式,导致concat 后括号的内容以报错形式展示出来。
基于floor函数的报错原理,较为复杂,读者可以参考 第四个连接。给几个爆破数据库的payload,
爆破数据库版本信息:
?id=1'+and(select 1 from(select count('),concat(select(select(select concat(0x7e,
version(),0x7e))from information_schema.tables limit 0,1),floor(rand(0)*2)x from
information_schema.tables group by x)a)%23
爆破当前用户:
?id=1'+and(select 1 from(select count('),concat(select (select(select concat(Ox7e,
user(),0x7e))from information_schema.tables limit 0,1),floor(rand(0)*2))x from
linformation_schema.tables group by x)a)%23
爆破当前使用的数据库:
?id=1'+and(select 1 from(select count("),concat(select(select(select concat(Ox7e,
database(),0x7e)from information schema.tables limit 0,1),floor(rand(0)*2)x from
information_schema.tables group by x)a)%23
基于exp函数报错的原因为溢出报错。
使用的payload 如下:
2id=1'and exp(-(select*from(select user())x))%23
不可回显的注入
不可回显的注入,通常是因开发者将报错信息屏蔽或者正确与否存在同样的回显导致的,有布尔盲注和基于时间盲注两种。下面分别介绍。
布尔盲注通常使用有些判断真假的语句来进行判定。通常在查询语句后面 添加 and 1=1和 and 1=2 。 因为 1=1 不影响运行,但是1=2为假,没有正常的回显。布尔盲注时通常用到的函数进行了一些总结
1.截取函数
substr() 函数是字符串截取函数,在盲注中我们一般逐位获取数据,这时候就需要使用subtr函数按位截取。使用方法∶substr(str,start,length)。这里的str为被截取的字符串,start为开始截取的位置,length为截substr()取的长度。在盲注时,我们一般只截取一位,如substruser(user(),1),这样可以从user函数返回数据的第一位开始的偏移位置截取一位,之后我们只要修改位置参数即可获取其他的数据
left()函数 是左截取函数,lef的用法为lef(sr,length)。这里的str是被截取的字符串,length为被截取的长度。在育注中可以使用len(user(),1)来左截取一位字符。但是,如果是lef(user(),2),则会将user()的前两位都截取出来,这样的话,我们需要在匹配输出的字符串之前增加前缀,把之前几次的结果添加到这次的结果之前。
right()函数 是右截取函数。使用方法与lef 函数类似,可以参考left函数的用法rightO
2.转换函数
ascii()函数 的作用是将字符串转换为ASCII码,这样我们就可以避免在Paylod中出现单引号。使用方法为ascii(char),这里的char为一个字符,在盲注中一般为单个字母。如果 char为一串字符串,则返回结果ascii()将是第一个字母的ASCII码。我们在使用中通常与substr函数相结合,如 asci(substr(user(),1,1),这样可以获得user()的第一位字符的 ASCII码
Hex()函数 可以将字符串的值转换为十六进制的值。在ascii函数被禁止时,或者是需要将二进制数据写人hex()文件时可以使用该函数,使用方法类似于 ascii函数
3.比较函数
if()函数 是盲注中经常使用的函数,if函数的作用与1=1和1=2的原理类似。如果我们要盲注的对象为假,则可以通过if的返回结果对页面进行控制。使用方法为if(cond,Ture_result,False_resut)其中,cond为判断条件,Ture_result为真时的返回结果,False_result为假时的返回结果。
时间盲注是当服务器拼接了我们注入的sql语句后,无论正确与否都会显示同样的回显。错误信息被过滤,可以通过页面响应时间进行按位判断数据。由于时间盲注的函数在数据库中进行,CTF比赛中为了避免服务器负载过高,时间盲注的题目比较少。
参考文献
1.SQL语句入门 https://blog.csdn.net/AtlanSI/article/details/84845002
2.CTF特训营:技术详解、解题方法与竞赛技巧 https://book.douban.com/subject/35120456/
3. updatexml()报错注入_qq_37873738的博客-CSDN博客_updatexml
4. floor()报错:https://www.cnblogs.com/sfriend/p/1