session会话机制介绍如下

http是无状态协议。服务器靠cookie和session来记住用户。$_SESSION 和 $_GET等一样,是超全局变量。

后台脚本里面会写: session() start 。会话开始。所以,当浏览器访问一个页面时,session机制就开始了。这个时候机制会生成一个PHPSESSID. 存放在cookie当中,当在这个网站post,get 请求数据的时候,会带着这个ID。这个ID是随机的,是由PHP决定的。在注册时,这个PHPSSID可能和注册时间,毫秒,用户名,密码哈希值等有关,所以爆破碰撞PHPSSID难度很大。

在服务器后台,会创建一个以PHPSSID命名文件,里面会储存用户的信息。服务器根据用户发送过来的PHPSSID,读取文件里面的信息。

上面的和这道题没有太大关系。

题目源码打包地址: 120.27.32.227/www.zip

这是一道代码审计。

下面是相关代码示例。

<?php
define("DB_NAME", "xian");
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWD", "");
define("DSN", "mysql:host=".DB_HOST.";dbname=".DB_NAME);
ini_set("display_errors", "On");
error_reporting(0);
foreach (array('_COOKIE','_POST','_GET') as $_request)
{
foreach ($$_request as $_key=>$_value)
{
$$_key= $_value;
}
}
session_start();
?>

这是common.php里面的代码,连接数据库,取出超全局变量里面的变量和值,根据顺序,先取出cookie,再试post和get。++如果这些变量里面有重名的变量,根据先后顺序,get具有决定性。接着就是SESSION会话机制开始++。由于$_SESSION也是一个超全局变量,如果碰到和前面那三个有重名的,$_SESSION具有决定性。

下面看do_register.php。

<?php
include_once("common.php");
$dbh = new PDO(DSN, DB_USER, DB_PASSWD);
$sql = "select * from user where username = :username";
$sth = $dbh->prepare($sql);
$sth->execute(array(':username'=>$username));
$res = $sth->fetch(PDO::FETCH_ASSOC);
if($res !== false) {
header("Location: error.php?msg=username%20has%20been%20used!");
die();
}
$sql = "insert into user (username, password, role) values(:username, :password, 1)";
$sth = $dbh->prepare($sql);
$res = $sth->execute(array(':username'=>$username, ':password'=>$password));
if($res === false) {
header("Location: error.php?msg=register%20error!");
die();
} $sql = "select * from user where username = :username and password = :password";
$sth = $dbh->prepare($sql);
$sth->execute(array(':username'=>$username, ':password' => $password));
$res = $sth->fetch(PDO::FETCH_ASSOC);
if($res === false) {
header("Location: error.php?msg=register%20error!");
die();
}
$userinfo["id"] = $res["id"];
$userinfo["username"] = $username;
$userinfo["password"] = $password;
$_SESSION["userinfo"] = $userinfo;
$userinfo["role"] = $res["role"];
header("Location: index.php");
?>

看这段代码的最后几行,是直接把userinfo的信息写进了session里面。下面再看do_changepassword.php。

<?php
include_once("common.php");
if(!isset($_SESSION["userinfo"])) {
header("Location: login.php");
die();
}
$userinfo = $_SESSION["userinfo"];
if($old_pass = $userinfo['password']) {
if($userinfo["id"] == 1) {
echo "flag{xxx}";
die();
}
$dbh = new PDO(DSN, DB_USER, DB_PASSWD);
$sql = "update user set password = :password where id=:id";
$sth = $dbh->prepare($sql);
$res = $sth->execute((array(':password'=>$new_pass, ':id'=>$userinfo['id'])));
var_dump $new_pass;
echo "<br>";
var_dump $userinfo['id']; if($res === false) {
header("Location: error.php?msg=changepass%20error!");
die();
} $userinfo["password"] = $new_pass;
$_SESSION['userinfo'] = $userinfo; header("Location: index.php");
} else {
header("Location: error.php?msg=invalid%20old%20pass!");
die();
}
?>

这里看到,要得到flag,id必须为1。

所以正常来说,我们会想到在超全局变量里面传入参数userinfo['id']=1。

这是一个数组,所以我们请求应该这么写。 http://localhost/do_changepass.php?userinfo[id]=1

但是并没有用,因为$_SESSION这个超全局变量里面有和这个重名的,最后这个变量的值是由session决定的。

所以,这题,只要在post,get,cookie这三个里面传入和session里面重名的变量,都会被session给覆盖,也就是传入参数数组的方式行不通。

解这题的正确姿势,还是要用到“php是最好的语言这个特性”---弱类型。

所以这道题,在register的时候,传入参数,userinfo=1 。然后访问do_changepass ,改密码,就出flag了。解释如下。

传入参数 userinfo=1, 在register页面,

$userinfo["id"] = $res["id"];
$userinfo["username"] = $username;
$userinfo["password"] = $password;
$_SESSION["userinfo"] = $userinfo;
$userinfo["role"] = $res["role"];
header("Location: index.php");

这几行代码之前,session为空。所以这里调用的userinfo 是我们传进去的参数,而我们传进去的参数是一个字符串 , $userinfo["id"]

会把我们的字符串先转化为字符数组,但是是一个数字索引数组 。里面没有id这个键,所以 $userinf["id"] 就与 userinfo[0] 等同。我们的userinfo就变成了userinfo="$rs["id"]"。只改变了第一个字符。接下来的变量赋值,都只改变了第一个字符。所以最后第一个字符是由 $res["role"]决定的,值为1。

我们传入变量的时候,只传入一个字符,同样能出flag。

	if($userinfo["id"] == 1) {
echo "flag{xxx}";
die();
}

这里userinfo["id"]=userinf[0]=$res["role"]=1。

总结:这一道题考察了 变量覆盖,php弱类型:字符和数组的转化,变量重名。还有观察力。

session 会话机制以及变量覆盖的更多相关文章

  1. note.js之 Mongodb在Nodejs上的配置及session会话机制的实现

    上篇我们使用nodejs实现了一个express4的网站构建配置,但一个有面的网站怎么可以缺少一个数据库呢.现在较为流行的就是使用MONGODB来作为nodejs网站引用的数据库,可能它与nodejs ...

  2. java 浅谈web系统当中的cookie和session会话机制

    一 Cookie: 1. Cookie翻译为小甜饼,有一种特殊的味道.cookie主要用来在(浏览器)客户端做记号用的.Cookie不属于java,Cookie是一种通用的机制,属于HTTP协议的一部 ...

  3. 63.note.js之 Mongodb在Nodejs上的配置及session会话机制的实现

    转自:https://www.cnblogs.com/alvin_xp/p/4751784.html 1.第一步安装mongodb数据库,这直接官网下载,这里不介绍. 2.也可以使用npm实现直接下载 ...

  4. 【转】php中的会话机制(2)

    原文:https://segmentfault.com/a/1190000000468220 发现,在调用session_start()的时候, session_start() 里面应该是有调用类似 ...

  5. Cookie&Seesion会话 共享数据 工作流程 持久化 Servlet三个作用域 会话机制

    Day37 Cookie&Seesion会话 1.1.1 什么是cookie 当用户通过浏览器访问Web服务器时,服务器会给客户端发送一些信息,这些信息都保存在Cookie中.这样,当该浏览器 ...

  6. 使用HTML5 WebStorage API构建与.NET对应的会话机制

    HTML5的Web Storage API,我们也称为DOMStarage API,用于在Web请求之间持久化数据.在Web Starage API 出现之前,我们都是将客户端和服务端之间的交互数据存 ...

  7. 【Consul】Consul架构-Session会话

    Consul提供session会话机制--可以用于构建分布式锁,session可以绑定到节点.健康检查.KV数据.目的是提供颗粒锁--受 The Chubby LockService for Loos ...

  8. java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用)

    java web Session会话技术(原理图解+功能+与Cookie的区别+基本使用) 这是我关于会话技术的第二篇文章,对 Cookie有不了解的兄弟可以点击下方的Cookie跳转 Cookie链 ...

  9. Session会话保持机制的原理与Tomcat Session共享的几种实现方式(Session Cluster、memcached+MSM)

    一.Session的定义 在计算机科学中,特别是在网络中,session是两个或更多个通信设备之间或计算机和用户之间的临时和交互式信息交换.session在某个时间点建立,然后在之后的某一时间点拆除. ...

随机推荐

  1. 利用shell脚本[带注释的]部署单节点多实例es集群(docker版)

    文章目录 目录结构 install_docker_es.sh elasticsearch.yml.template 没事写写shell[我自己都不信,如果不是因为工作需要,我才不要写shell],努力 ...

  2. k8s集群节点ping不通其他主机的ip

    文章目录 排查过程 本地宿主机网络检查 pod网络检查 tcpdump检查网络 检查flannel网卡 检查宿主机网卡 iptables检查 解决方法 测试环境服务出现问题,服务一直报错认证超时,检查 ...

  3. 数据缓存Cache

    在MyBatis - 随笔分类 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中有关于Mybatis中Cache技术实现及应用介绍.Cache技术实现都是implements Cache ...

  4. [入门到吐槽系列] Webix 10分钟入门 二 表单Form的使用

    前言 继续接着上一篇的webix入门:https://www.cnblogs.com/zc22/p/15912342.html.今天完成剩下两个最重要的控件,表单和表格的使用.掌握了这两个,整个Web ...

  5. 你所不知道的 C# 10新特性

    我们很高兴地宣布 C# 10 作为 .NET 6 和 Visual Studio 2022 的一部分已经发布了.在这篇文章中,我们将介绍 C# 10 的许多新功能,这些功能使您的代码更漂亮.更具表现力 ...

  6. [自动化]ssh自动化免密访问配置

    ssh简介 SSH(Secure Shell)是一种通信加密协议,加密算法包括:RSA.DSA等 RSA:非对称加密算法,其安全性基于极其困难的大整数的分解(两个素数的乘积): DSA:也是非对称加密 ...

  7. Vue 源码解读(8)—— 编译器 之 解析(下)

    特殊说明 由于文章篇幅限制,所以将 Vue 源码解读(8)-- 编译器 之 解析 拆成了两篇文章,本篇是对 Vue 源码解读(8)-- 编译器 之 解析(上) 的一个补充,所以在阅读时请同时打开 Vu ...

  8. hadoop 无法访问50070

    windows无法访问hadoop web端口 windows hosts文件:C:\Windows\System32\drivers\etc centos防火墙没有关,关闭参考 hadoop cor ...

  9. oj教程--学习顺序

    1.数组 2.排序 3.递归 4.栈 5.队列 6.链表 7.二叉树 8.大数或高精度 9.枚举 10.搜索 11.字符串问题 12.贪心 13.最短路径 14.动态规划

  10. pyqt(二)

    二.文本和图片 1. 文本控件 文本控件是QLabel from PyQt5.QtWidgets import QWidget,QApplication,QLabel from PyQt5.QtCor ...