Scan.php 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | Author: Michael_xu <gengxiaoxu@5kcrm.com>
  4. // +----------------------------------------------------------------------
  5. namespace com;
  6. use think\Request;
  7. class Scan {
  8. private $webscan_switch = 1;
  9. //提交方式拦截(1开启拦截,0关闭拦截,post,get,cookie,referre选择需要拦截的方式)
  10. private $webscan_post = 1;
  11. private $webscan_get = 1;
  12. private $webscan_cookie = 1;
  13. private $webscan_referre = 1;
  14. private $webscan_white_directory = 'admin';
  15. private $webscan_white_url = array('index.php' => 'm=admin');
  16. //get拦截规则
  17. private $getfilter = "<[^>]*?=[^>]*?&#[^>]*?>|iframe|\\b(alert\\(|confirm\\(|expression\\(|prompt\\()|<[^>]*?\\b(onerror|onmousemove|ondblclick|onmousedown|onmouseup|onmouseout|onscroll|onfocus|onsubmit|onblur|onchange|onload|onclick|onmouseover)\\b[^>]*?>|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*object\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|INTO.+?FILE|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
  18. //post拦截规则
  19. private $postfilter = "<[^>]*?=[^>]*?&#[^>]*?>|iframe|\\b(alert\\(|confirm\\(|expression\\(|prompt\\()|<[^>]*?\\b(onerror|onmousemove|ondblclick|onmousedown|onmouseup|onmouseout|onscroll|onfocus|onsubmit|onblur|onchange|onload|onclick|onmouseover)\\b[^>]*?>|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*object\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|INTO.+?FILE|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
  20. //cookie拦截规则
  21. private $cookiefilter = "\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.+?\\*\\/|<\\s*script\\b|<\\s*object\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|INTO.+?FILE|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
  22. /**
  23. * 记录日志
  24. */
  25. public function webscan_slog($logs) {
  26. // var_dump(RUNTIME_PATH);die();
  27. $string = "\r\n================\r\n".implode("\r\n", $logs);
  28. file_put_contents(RUNTIME_PATH.'input_error.txt', $string, FILE_APPEND);
  29. }
  30. /**
  31. * 参数拆分
  32. */
  33. public function webscan_arr_foreach($arr) {
  34. static $str;
  35. if (!is_array($arr)) {
  36. return $arr;
  37. }
  38. foreach ($arr as $key => $val ) {
  39. if (is_array($val)) {
  40. $this->webscan_arr_foreach($val);
  41. } else {
  42. $str[] = $val;
  43. }
  44. }
  45. return implode($str);
  46. }
  47. /**
  48. * 获取ip
  49. */
  50. public function get_client_ip($type = 0) {
  51. $_SERVER = input('server.');
  52. $type = $type ? 1 : 0;
  53. static $ip = NULL;
  54. if ($ip !== NULL) return $ip[$type];
  55. if ($_SERVER['HTTP_X_REAL_IP']) {//nginx 代理模式下,获取客户端真实IP
  56. $ip=$_SERVER['HTTP_X_REAL_IP'];
  57. } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的ip
  58. $ip = $_SERVER['HTTP_CLIENT_IP'];
  59. } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
  60. $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
  61. $pos = array_search('unknown',$arr);
  62. if(false !== $pos) unset($arr[$pos]);
  63. $ip = trim($arr[0]);
  64. } elseif (isset($_SERVER['REMOTE_ADDR'])) {
  65. $ip = $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的ip地址
  66. } else {
  67. $ip = $_SERVER['REMOTE_ADDR'];
  68. }
  69. // IP地址合法验证
  70. $long = sprintf("%u",ip2long($ip));
  71. $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
  72. return $ip[$type];
  73. }
  74. /**
  75. * 攻击检查拦截
  76. */
  77. public function webscan_StopAttack($StrFiltKey, $StrFiltValue, $ArrFiltReq, $method) {
  78. $_SERVER = input('server.');
  79. // var_dump($_SERVER) ;die();
  80. $StrFiltValue = $this->webscan_arr_foreach($StrFiltValue);
  81. if (preg_match("/".$ArrFiltReq."/is",$StrFiltValue) == 1){
  82. $this->webscan_slog(array('ip' => $this->get_client_ip(),'time'=>strftime("%Y-%m-%d %H:%M:%S"),'page'=>$_SERVER["PHP_SELF"],'method'=>$method,'rkey'=>$StrFiltKey,'rdata'=>$StrFiltValue,'user_agent'=>$_SERVER['HTTP_USER_AGENT'],'request_url'=>$_SERVER["REQUEST_URI"]));
  83. header('Content-Type:application/json; charset=utf-8');
  84. exit(json_encode(['code'=>107,'error'=>'插入了被禁用的标签!']));
  85. }
  86. if (preg_match("/".$ArrFiltReq."/is",$StrFiltKey) == 1){
  87. $this->webscan_slog(array('ip' => $this->get_client_ip(),'time'=>strftime("%Y-%m-%d %H:%M:%S"),'page'=>$_SERVER["PHP_SELF"],'method'=>$method,'rkey'=>$StrFiltKey,'rdata'=>$StrFiltKey,'user_agent'=>$_SERVER['HTTP_USER_AGENT'],'request_url'=>$_SERVER["REQUEST_URI"]));
  88. header('Content-Type:application/json; charset=utf-8');
  89. exit(json_encode(['code'=>107,'error'=>'插入了被禁用的标签!']));
  90. }
  91. }
  92. public function webscan_Check() {
  93. $request = Request::instance();
  94. //var_dump(input('server.HTTP_REFERER'));die();
  95. //referer获取
  96. //$webscan_referer = empty(input('server.HTTP_REFERER')) ? array() : array('HTTP_REFERER'=>input('server.HTTP_REFERER'));
  97. return ;
  98. if ($this->webscan_switch) {
  99. if ($this->webscan_get) {
  100. foreach($request->get() as $key=>$value) {
  101. $this->webscan_StopAttack($key, $value, $this->getfilter, "GET");
  102. }
  103. }
  104. if ($this->webscan_post) {
  105. // $module = strtolower($request->module());
  106. // $un_strip_arr = array('knowledge','template');
  107. foreach ($request->post() as $key=>$value) {
  108. //过滤post数据 html标签
  109. // if (!in_array($module, $un_strip_arr)) {
  110. $request->param($key,'','strip_tags,strtolower');
  111. // }
  112. $this->webscan_StopAttack($key, $value, $this->postfilter, "POST");
  113. }
  114. }
  115. if ($this->webscan_cookie) {
  116. foreach($request->cookie() as $key=>$value) {
  117. $this->webscan_StopAttack($key, $value, $this->cookiefilter, "COOKIE");
  118. }
  119. }
  120. if ($this->webscan_referre) {
  121. foreach($webscan_referer as $key=>$value) {
  122. $this->webscan_StopAttack($key, $value, $this->postfilter, "REFERRER");
  123. }
  124. }
  125. }
  126. }
  127. }