diff --git a/admin.php b/admin.php index 706506c..012c94a 100644 --- a/admin.php +++ b/admin.php @@ -58,22 +58,29 @@ require("auth.php"); - Copyright © 2015-2016 Powered by Firesun + Copyright © 2015-2016
Powered by Firesun
@@ -107,18 +114,19 @@ require("auth.php");

关于

-
+
+
+ + + -
- -
查找记录
@@ -157,6 +165,24 @@ require("auth.php");
+ +
+
+ + 确认
+
+
+ 您确认注销吗? +
+
+
+ + +
+
+
+
+
diff --git a/api.php b/api.php index cec20df..98dfa52 100644 --- a/api.php +++ b/api.php @@ -9,15 +9,17 @@ if(isset($_GET['cmd'])) { switch($_GET['cmd']) { + //所有记录包括详细信息 case 'list': echo json_encode(dirList()); break; - + + //只列出时间戳(索引id) case 'simplelist': - echo json_encode(dirSimpleList()); break; - + + //根据时间戳(索引id)获得单条信息 case 'get': if(isset($_GET['id'])&&preg_match('/^[0-9]{10}$/',$_GET['id'])) echo json_encode(loadInfo($_GET['id'])); @@ -25,6 +27,7 @@ if(isset($_GET['cmd'])) echo json_encode(false); break; + //根据时间戳(索引id)删除单条信息 case 'del': if(isset($_GET['id'])&&preg_match('/^[0-9]{10}$/',$_GET['id'])) echo json_encode(delInfo($_GET['id'])); @@ -32,11 +35,18 @@ if(isset($_GET['cmd'])) echo json_encode(false); break; + //清空记录 case 'clear': echo json_encode(clearInfo()); - break; + break; + + default: + echo json_encode(false); } } +else + echo json_encode(false); + function dirSimpleList() { $files = glob(DATA_PATH . '/*.php'); foreach ($files as &$file){ @@ -44,17 +54,17 @@ function dirSimpleList() { } return $files; } -function dirList() { +function dirList() { $list=array(); $files = glob(DATA_PATH . '/*.php'); arsort($files); foreach ($files as $file) { - $listinfo=array(); $filename=basename($file,".php"); $info=loadInfo($filename); $isChange=false; + //如果没有设置location,就查询qqwry.dat判断location if(!isset($info['location'])) { $info['location']=convertip($info['user_IP'],IPDATA_PATH); @@ -63,10 +73,8 @@ function dirList() { if($isChange) saveInfo(json_encode($info),$filename); - $list[]= $info; - } - + } return $list; -} +} ?> \ No newline at end of file diff --git a/auth.php b/auth.php index 763e4ee..e57d073 100644 --- a/auth.php +++ b/auth.php @@ -2,9 +2,12 @@ if(!defined('IN_XSS_PLATFORM')) { exit('Access Denied'); } + +//设置httponly ini_set("session.cookie_httponly", 1); session_start(); +//判断登陆情况,ip和useragent是否改变,改变则强制退出 if(!(isset($_SESSION['isLogin']) && $_SESSION['isLogin']===true && isset($_SESSION['user_IP']) &&$_SESSION['user_IP']!="" &&$_SESSION['user_IP']=== $_SERVER['REMOTE_ADDR'] &&isset($_SESSION['user_agent']) &&$_SESSION['user_agent']!="" &&$_SESSION['user_agent']=== $_SERVER['HTTP_USER_AGENT'] )) { $_SESSION['isLogin']=false; @@ -16,9 +19,8 @@ if(!(isset($_SESSION['isLogin']) && $_SESSION['isLogin']===true && isset($_SESSI exit(); } +//开启CSP header("Content-Security-Policy: default-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; frame-src 'none'"); header("X-Content-Security-Policy: default-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; frame-src 'none'"); header("X-WebKit-CSP: default-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; frame-src 'none'"); - - ?> \ No newline at end of file diff --git a/config.php b/config.php index 78a25f7..b8e00fe 100644 --- a/config.php +++ b/config.php @@ -2,11 +2,16 @@ if(!defined('IN_XSS_PLATFORM')) { exit('Access Denied'); } - -define('PASS', '2a05218c7aa0a6dbd370985d984627b8');//bluelotus +//默认密码bluelotus +define('PASS', '2a05218c7aa0a6dbd370985d984627b8'); +//记录,封禁ip列表存放位置 define('DATA_PATH', 'data'); +//开启对记录,封禁ip列表的AES加密 define('ENABLE_ENCRYPT', true); +//加密密码 define('ENCRYPT_PASS', "bluelotus"); +//是否启用KEEP_SESSION功能,需要外部定时访问keepsession.php define('KEEP_SESSION', true); +//ip数据库地址 define('IPDATA_PATH', "qqwry.dat"); ?> \ No newline at end of file diff --git a/dio.php b/dio.php index f6edd43..9dd4e71 100644 --- a/dio.php +++ b/dio.php @@ -5,6 +5,7 @@ if(!defined('IN_XSS_PLATFORM')) { require_once("config.php"); require_once("functions.php"); +//对记录的读写操作,无数据库,采用读写文件的方式,文件名即请求时的时间戳,同时也是记录的id function saveInfo($info,$filename) { $logFile = dirname( __FILE__ ).'/'.DATA_PATH.'/'.$filename.'.php'; diff --git a/functions.php b/functions.php index b6659d8..d78da81 100644 --- a/functions.php +++ b/functions.php @@ -4,6 +4,7 @@ if(!defined('IN_XSS_PLATFORM')) { } require_once("aes.php"); +//nginx无getallheaders函数 if (!function_exists('getallheaders')) { function getallheaders() { foreach ($_SERVER as $name => $value) { @@ -15,7 +16,7 @@ if (!function_exists('getallheaders')) { } } - +//判断该记录是否 function isKeepSession($info){ $keepsession=false; foreach($info['cookie_data'] as $k => $v) { @@ -33,8 +34,7 @@ function isKeepSession($info){ return $keepsession; } - - +//xss过滤 function stripStr($str){ if(get_magic_quotes_gpc()) $str=stripslashes($str); @@ -49,6 +49,7 @@ function stripArr($arr){ return $new_arr; } +//尝试base64解码 function tryBase64Decode($arr) { if(isset($arr)&&count($arr)>0) @@ -74,6 +75,7 @@ function tryBase64Decode($arr) return false; } +//判断string是否为base64编码(判断方法:解码后为可见字符串) function isBase64Formatted($str) { if(preg_match('/^[A-Za-z0-9+\/=]+$/',$str)) @@ -93,6 +95,7 @@ function decrypt($info,$encryptPass) return AESDecryptCtr($info,$encryptPass); } +//基于Discuz X3.1 function_misc.php function convertip($ip, $ipdatafile) { $ipaddr = '未知'; if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) { diff --git a/guide/mainpanel.png b/guide/mainpanel.png index 63e3bd2..b10639a 100644 Binary files a/guide/mainpanel.png and b/guide/mainpanel.png differ diff --git a/index.php b/index.php index 7dfa85a..5c17f47 100644 --- a/index.php +++ b/index.php @@ -19,6 +19,7 @@ $request_time = isset($_SERVER['REQUEST_TIME'])?$_SERVER['REQUEST_TIME']:time(); $headers_data =getallheaders(); +//如果提交的数据有base64编码的就解码 $get_data=$_GET; $decoded_get_data=tryBase64Decode($_GET); $post_data=$_POST; @@ -26,6 +27,7 @@ $decoded_post_data=tryBase64Decode($_POST); $cookie_data=$_COOKIE; $decoded_cookie_data=tryBase64Decode($_COOKIE); +//防xss过滤,对array要同时处理key与value $info['user_IP'] = stripStr($user_IP); $info['user_port'] = stripStr($user_port); $info['protocol'] = stripStr($protocol); @@ -46,6 +48,7 @@ $info['cookie_data'] = stripArr($cookie_data); if($decoded_cookie_data) $info['decoded_cookie_data'] = stripArr($decoded_cookie_data); +//判断是否keepsession(判断标准:get或者post或者cookie包含keepsession=1) $info['keepsession']=isKeepSession($info)?true:false; saveInfo(json_encode($info),$request_time); diff --git a/login.php b/login.php index 8877e1e..e74c3ea 100644 --- a/login.php +++ b/login.php @@ -5,18 +5,20 @@ header("Content-Security-Policy: default-src 'self'; object-src 'none'; frame-sr header("X-Content-Security-Policy: default-src 'self'; object-src 'none'; frame-src 'none'"); header("X-WebKit-CSP: default-src 'self'; object-src 'none'; frame-src 'none'"); +//设置httponly ini_set("session.cookie_httponly", 1); session_start(); require_once("config.php"); require_once("functions.php"); - +//判断是否登陆 if(isset($_SESSION['isLogin']) && $_SESSION['isLogin']===true) { header("Location: admin.php"); exit(); } +//判断ip是否在封禁列表中 $forbiddenIPList=loadForbiddenIPList(); $ip=$_SERVER['REMOTE_ADDR']; if(!isset($forbiddenIPList[$ip]) || $forbiddenIPList[$ip]<3) @@ -53,7 +55,8 @@ function loadForbiddenIPList() $logfile = DATA_PATH . '/forbiddenIPList.dat'; !file_exists( $logfile ) && @touch( $logfile ); $str = file_get_contents( $logfile ); - $str =decrypt($str,ENCRYPT_PASS); + if(ENABLE_ENCRYPT) + $str =decrypt($str,ENCRYPT_PASS); if($str!='') { $result=json_decode($str,true); @@ -70,7 +73,10 @@ function saveForbiddenIPList($forbiddenIPList) { $logfile = DATA_PATH . '/forbiddenIPList.dat'; !file_exists( $logfile ) && @touch( $logfile ); - @file_put_contents($logfile, encrypt(json_encode($forbiddenIPList),ENCRYPT_PASS)); + $str=json_encode($forbiddenIPList); + if(ENABLE_ENCRYPT) + $str = encrypt($str,ENCRYPT_PASS); + @file_put_contents($logfile, $str); } /* @@ -81,6 +87,7 @@ function checkPassword($p) { if(isset($_SESSION['firesunCheck'])&&isset($_POST['firesunCheck'])&&$_SESSION['firesunCheck']!=""&&$_POST['firesunCheck']===$_SESSION['firesunCheck']) { + //改了这个盐记得改login.js里的,两个要一致 $salt="!KTMdg#^^I6Z!deIVR#SgpAI6qTN7oVl"; $key=PASS; $key=md5($salt.$key.$_SESSION['firesunCheck'].$salt); @@ -92,6 +99,7 @@ function checkPassword($p) return false; } +//生成挑战应答的随机值 function generate_password( $length = 32 ) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $password = ""; diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..617b5fd --- /dev/null +++ b/logout.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/static/css/Fonts/icomoon.eot b/static/css/Fonts/icomoon.eot deleted file mode 100644 index 87a0ec5..0000000 Binary files a/static/css/Fonts/icomoon.eot and /dev/null differ diff --git a/static/css/Fonts/icomoon.svg b/static/css/Fonts/icomoon.svg deleted file mode 100644 index bf28776..0000000 --- a/static/css/Fonts/icomoon.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - \ No newline at end of file diff --git a/static/css/Fonts/icomoon.ttf b/static/css/Fonts/icomoon.ttf deleted file mode 100644 index 01872ef..0000000 Binary files a/static/css/Fonts/icomoon.ttf and /dev/null differ diff --git a/static/css/Fonts/icomoon.woff b/static/css/Fonts/icomoon.woff deleted file mode 100644 index 1570088..0000000 Binary files a/static/css/Fonts/icomoon.woff and /dev/null differ diff --git a/static/css/Site.css b/static/css/Site.css index 2c8fe5e..db59383 100644 --- a/static/css/Site.css +++ b/static/css/Site.css @@ -37,11 +37,11 @@ body, /* font */ @font-face { font-family: 'icomoon'; - src:url('Fonts/icomoon.eot?c8m22a'); - src:url('Fonts/icomoon.eot?#iefixc8m22a') format('embedded-opentype'), - url('Fonts/icomoon.woff?c8m22a') format('woff'), - url('Fonts/icomoon.ttf?c8m22a') format('truetype'), - url('Fonts/icomoon.svg?c8m22a#icomoon') format('svg'); + src:url('../fonts/icomoon.eot?c8m22a'); + src:url('../fonts/icomoon.eot?#iefixc8m22a') format('embedded-opentype'), + url('../fonts/icomoon.woff?c8m22a') format('woff'), + url('../fonts/icomoon.ttf?c8m22a') format('truetype'), + url('../fonts/icomoon.svg?c8m22a#icomoon') format('svg'); font-weight: normal; font-style: normal; } @@ -60,20 +60,20 @@ body, -moz-osx-font-smoothing: grayscale; } +.icon-logout:before { + content: "\e900"; +} .icon-info:before { - content: "\e600"; + content: "\e904"; } -.icon-faves:before { - content: "\e601"; +.icon-template:before { + content: "\e901"; } -.icon-star-empty:before { - content: "\e602"; +.icon-my-js:before { + content: "\e903"; } -.icon-chart-column:before { - content: "\e603"; -} -.icon-mobile:before { - content: "\e604"; +.icon-panel:before { + content: "\e902"; } .icon { @@ -146,12 +146,16 @@ body, } #rights { + width:100%; color: #848690; - font-size: 10px; + font-size: 12px; position: absolute; bottom: 10px; + text-align: center; + line-height: 120%; } + /* Toggle button */ #toggle-button { margin-top: 27px; @@ -197,4 +201,5 @@ body, -webkit-box-shadow: 1px 0 4px #ededee; box-shadow: 1px 0 4px #ededee; background-color: #fff; -} \ No newline at end of file +} + diff --git a/static/fonts/icomoon.eot b/static/fonts/icomoon.eot new file mode 100644 index 0000000..4528d43 Binary files /dev/null and b/static/fonts/icomoon.eot differ diff --git a/static/fonts/icomoon.svg b/static/fonts/icomoon.svg new file mode 100644 index 0000000..7f8ccf2 --- /dev/null +++ b/static/fonts/icomoon.svg @@ -0,0 +1,15 @@ + + + +Generated by IcoMoon + + + + + + + + + + + \ No newline at end of file diff --git a/static/fonts/icomoon.ttf b/static/fonts/icomoon.ttf new file mode 100644 index 0000000..fcfe0c1 Binary files /dev/null and b/static/fonts/icomoon.ttf differ diff --git a/static/fonts/icomoon.woff b/static/fonts/icomoon.woff new file mode 100644 index 0000000..2387aa0 Binary files /dev/null and b/static/fonts/icomoon.woff differ diff --git a/static/js/loadgrid.js b/static/js/loadgrid.js index 21d29ad..fbd9278 100644 --- a/static/js/loadgrid.js +++ b/static/js/loadgrid.js @@ -7,6 +7,7 @@ var interval = 1000; //向服务器获取记录的时间间隔,同时也是aja $(document).ready(function() { var self = this; + //数据源与datafields var source = { datatype: "json", datafields: [{ @@ -76,6 +77,7 @@ $(document).ready(function() { root: 'data', }; + //从接口获得数据后的处理,格式化时间与根据useragent判断客户端 var dataAdapter = new $.jqx.dataAdapter(source, { downloadComplete: function(data, status, xhr) { if (status == "success") { @@ -104,6 +106,7 @@ $(document).ready(function() { }, }); + //每行detail信息初始化 var initrowdetails = function(index, parentElement, gridElement, datarecord) { var tabsdiv = null; var information = null; @@ -119,7 +122,8 @@ $(document).ready(function() { post_grid = tabsdiv.find('.post_grid'); cookie_grid = tabsdiv.find('.cookie_grid'); headers_grid = tabsdiv.find('.headers_grid'); - //datarecord.client=datarecord.headers_data["User-Agent"]?get_client_info(datarecord.headers_data["User-Agent"]):"未知"; + + //GET表 var get_data = new Array(); for (key in datarecord.get_data) { var get_data_item = new Array(); @@ -193,6 +197,7 @@ $(document).ready(function() { ] }); + //POST表 var post_data = new Array(); for (key in datarecord.post_data) { var post_data_item = new Array(); @@ -269,6 +274,7 @@ $(document).ready(function() { ] }); + //COOKIE表 var cookie_data = new Array(); for (key in datarecord.cookie_data) { var cookie_data_item = new Array(); @@ -341,6 +347,7 @@ $(document).ready(function() { ] }); + //HTTP Headers表 var headers_data = new Array(); for (key in datarecord.headers_data) { var headers_data_item = new Array(); @@ -392,6 +399,8 @@ $(document).ready(function() { }, ] }); + + //其他信息 var container = $('
'); container.appendTo($(information)); var leftcolumn = $('
'); @@ -419,6 +428,7 @@ $(document).ready(function() { $(rightcolumn).append(uri_item); $(rightcolumn).append(client_item); + //tab大小调整 $(tabsdiv).jqxTabs({ width: '95%', height: '100%' @@ -426,16 +436,18 @@ $(document).ready(function() { } } + //主面板初始化 $("#panelGrid").jqxGrid({ pageable: true, + //如果需要autoresizecolumn,可以在这开启 ready: function() { //$('#panelGrid').jqxGrid('autoresizecolumn', 'request_date_and_time_string'); //$('#panelGrid').jqxGrid('autoresizecolumn', 'data_type'); //$('#panelGrid').jqxGrid('autoresizecolumn', 'user_IP'); }, + //最底下的状态栏初始化 pagerrenderer: function() { - var container = $("
"); var deleteButton = $("
删除
"); var clearButton = $("
清空
"); @@ -468,20 +480,15 @@ $(document).ready(function() { }); - // reload grid data. clearButton.click(function(event) { $('#clearConfirmWindow').jqxWindow('open'); $("#clearConfirmWindow").addClass('animated'); - //$("#panelGrid").jqxGrid({ - // source: getAdapter() - //}); }); + // search for a record. searchButton.click(function(event) { - //var offset = $("#panelGrid").offset(); $("#searchWindow").jqxWindow('open'); $("#searchWindow").addClass('animated'); - //$("#jqxwindow").jqxWindow('move', offset.left + 30, offset.top + 30); }); var pageElementsContainer = $("
"); @@ -524,8 +531,6 @@ $(document).ready(function() { }); return container; }, - - //selectionmode: 'multiplerowsextended', scrollmode: 'logical', sortable: true, pagesize: 25, @@ -677,6 +682,32 @@ $(document).ready(function() { } }); + //注销确认窗口 + $('#logoutConfirmWindow').jqxWindow({ + height: 100, + width: 270, + resizable: false, + okButton: $('#logoutConfirm_ok'), + cancelButton: $('#logoutConfirm_cancel'), + autoOpen: false, + }); + + $('#logoutConfirm_ok').jqxButton({ + width: '65px' + }); + $('#logoutConfirm_cancel').jqxButton({ + width: '65px' + }); + + $('#logoutConfirmWindow').on('close', + function(event) { + if (event.args.dialogResult.OK) { + window.location.href = "logout.php"; + } + }); + + + $('#failedWindow').jqxWindow({ height: 100, width: 270, @@ -697,6 +728,7 @@ $(document).ready(function() { width: 210, height: 180 }); + // create find and clear buttons. $("#findButton").jqxButton({ width: 70 @@ -704,6 +736,7 @@ $(document).ready(function() { $("#clearButton").jqxButton({ width: 70 }); + // find records that match a criteria. $("#dropdownlist").jqxDropDownList({ autoDropDownHeight: true, @@ -768,6 +801,12 @@ $(document).ready(function() { //$('#panelGrid').jqxGrid('autoresizecolumn', 'user_IP'); }); + $("#logout").click(function() { + $('#logoutConfirmWindow').jqxWindow('open'); + $("#logoutConfirmWindow").addClass('animated'); + + }); + //定时判断是否有新的记录 checkNewMessages(); setIntervalID = setInterval(checkNewMessages, interval);