├── .gitattributes ├── .gitignore ├── README.md └── litchi_ctf ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── classpath ├── mvnw ├── mvnw.cmd ├── my_ctf.sql ├── pom.xml └── src ├── main ├── java │ └── com │ │ └── litchi │ │ └── litchi_ctf │ │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ │ ├── LitchiCtfApplication.java │ │ ├── config │ │ ├── CsrfConfig.java │ │ ├── DruidConfig.java │ │ ├── KaptchaConfig.java │ │ └── ShiroConfig.java │ │ ├── controller │ │ ├── AdminChallengeController.java │ │ ├── AdminController.java │ │ ├── AdminEditController.java │ │ ├── ChallengeController.java │ │ ├── FileController.java │ │ ├── KaptchaController.java │ │ ├── LoginController.java │ │ ├── NoticeController.java │ │ ├── RankController.java │ │ ├── RegisterController.java │ │ ├── SignoutController.java │ │ └── indexController.java │ │ ├── mapper │ │ ├── Challengemapper.java │ │ ├── Noticemapper.java │ │ ├── Rankmapper.java │ │ ├── Solvemapper.java │ │ └── Usermapper.java │ │ ├── pojo │ │ ├── Challenge.java │ │ ├── ChallengeList.java │ │ ├── ChallengeType.java │ │ ├── Notice.java │ │ ├── RankList.java │ │ └── User.java │ │ ├── realm │ │ └── UserRealm.java │ │ ├── service │ │ ├── ChallengeService.java │ │ ├── NoticeService.java │ │ ├── RankService.java │ │ ├── SolveService.java │ │ ├── StorageService.java │ │ ├── UserService.java │ │ └── serviceImpl │ │ │ ├── ChallengeServiceImpl.java │ │ │ ├── NoticeServiceImpl.java │ │ │ ├── RankServiceImpl.java │ │ │ ├── SolveServiceImpl.java │ │ │ ├── StorageServiceImpl.java │ │ │ └── UserServiceImpl.java │ │ └── util │ │ ├── TypeChallengeResultHandler.java │ │ └── csrf │ │ ├── CSRFHandlerInterceptor.java │ │ ├── CSRFRequestDataValueProcessor.java │ │ └── CSRFTokenManager.java └── resources │ ├── application.yml │ ├── ehcache-shiro.xml │ ├── static │ ├── css │ │ ├── material-dashboard.css │ │ └── material-kit.min.css │ ├── img │ │ └── bg7.jpg │ └── js │ │ ├── bg-wordChange.js │ │ ├── bootstrap-material-design.min.js │ │ ├── chartist.min.js │ │ ├── jquery.min.js │ │ ├── litchi.js │ │ ├── material-dashboard.min.js │ │ ├── perfect-scrollbar.jquery.min.js │ │ ├── popper.min.js │ │ └── validate.js │ └── templates │ ├── Challenge.html │ ├── addChallenge.html │ ├── addNotice.html │ ├── challengeDetail.html │ ├── challengeList.html │ ├── error.html │ ├── footer.html │ ├── head.html │ ├── home.html │ ├── index.html │ ├── indexhead.html │ ├── js.html │ ├── login.html │ ├── navbar.html │ ├── notice.html │ ├── noticeList.html │ ├── rank.html │ └── register.html └── test └── java └── com └── litchi └── litchi_ctf ├── LitchiCtfApplicationTests.java ├── dataSource.java ├── mapper ├── ChallengemapperTest.java ├── SolvemapperTest.java └── UsermapperTest.java └── service └── serviceImpl ├── RankServiceImplTest.java ├── SolveServiceImplTest.java └── UserServiceImplTest.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | *.js linguist-language=java 4 | *.css linguist-language=java 5 | *.html linguist-language=java 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LitctfPlatform 2 | 一个基于SpringBoot的CTF平台 3 | 4 | v1.00 demo:http://39.105.29.134:8080/home 5 | 6 | 本平台主要用于开发学习,使用的轮子包括 7 | 8 | Thymeleaf 模版引擎 9 | 10 | SpringBoot 11 | 12 | Mybatis 13 | 14 | Shiro权限控制 15 | 16 | Druid数据源 17 | 18 | Kaptcha验证码 19 | 20 | 数据库采用Mysql 21 | 22 | > 如何使用 23 | 24 | 需要新建数据库my_ctf,将my_ctf.sql文件导入,生成对应的表及视图,之后运行程序便可以成功启动 25 | -------------------------------------------------------------------------------- /litchi_ctf/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /litchi_ctf/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Litch1-v/LitctfPlatform/962f1d69ef7baddbd071d08976fbe1985e065917/litchi_ctf/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /litchi_ctf/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip 2 | -------------------------------------------------------------------------------- /litchi_ctf/classpath: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Litch1-v/LitctfPlatform/962f1d69ef7baddbd071d08976fbe1985e065917/litchi_ctf/classpath -------------------------------------------------------------------------------- /litchi_ctf/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /litchi_ctf/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /litchi_ctf/my_ctf.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat Premium Data Transfer 3 | 4 | Source Server : localhost_3306 5 | Source Server Type : MySQL 6 | Source Server Version : 50720 7 | Source Host : localhost:3306 8 | Source Schema : my_ctf 9 | 10 | Target Server Type : MySQL 11 | Target Server Version : 50720 12 | File Encoding : 65001 13 | 14 | Date: 24/12/2018 22:52:48 15 | */ 16 | 17 | SET NAMES utf8mb4; 18 | SET FOREIGN_KEY_CHECKS = 0; 19 | 20 | -- ---------------------------- 21 | -- Table structure for challenge 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `challenge`; 24 | CREATE TABLE `challenge` ( 25 | `title` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 26 | `cid` int(11) NOT NULL AUTO_INCREMENT, 27 | `flag` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 28 | `type` int(11) NOT NULL, 29 | `link` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 30 | `description` tinytext CHARACTER SET utf8 COLLATE utf8_general_ci NULL, 31 | `solved_number` int(11) NOT NULL DEFAULT 0, 32 | PRIMARY KEY (`cid`) USING BTREE 33 | ) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 34 | 35 | -- ---------------------------- 36 | -- Table structure for notice 37 | -- ---------------------------- 38 | DROP TABLE IF EXISTS `notice`; 39 | CREATE TABLE `notice` ( 40 | `nid` int(11) NOT NULL AUTO_INCREMENT, 41 | `date` datetime(0) NULL DEFAULT NULL, 42 | `description` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 43 | PRIMARY KEY (`nid`) USING BTREE 44 | ) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 45 | 46 | -- ---------------------------- 47 | -- Table structure for solve 48 | -- ---------------------------- 49 | DROP TABLE IF EXISTS `solve`; 50 | CREATE TABLE `solve` ( 51 | `uid` int(11) NOT NULL, 52 | `cid` int(11) NOT NULL 53 | ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 54 | 55 | -- ---------------------------- 56 | -- Table structure for user 57 | -- ---------------------------- 58 | DROP TABLE IF EXISTS `user`; 59 | CREATE TABLE `user` ( 60 | `uid` int(11) NOT NULL AUTO_INCREMENT, 61 | `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 62 | `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 63 | `class_number` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 64 | `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, 65 | `role` int(11) NOT NULL DEFAULT 2, 66 | `true_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, 67 | `solved_number` int(11) NULL DEFAULT 0, 68 | PRIMARY KEY (`uid`) USING BTREE, 69 | UNIQUE INDEX `username`(`username`) USING BTREE 70 | ) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; 71 | 72 | SET FOREIGN_KEY_CHECKS = 1; 73 | 74 | DROP VIEW IF EXISTS `rankview`; 75 | CREATE VIEW `rankview` AS SELECT solved_number rid,solved_number,count(*) user_number from user GROUP BY solved_number ; 76 | -------------------------------------------------------------------------------- /litchi_ctf/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.Litchi 7 | litchi_ctf 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | litchi_ctf 12 | CTF_of_Litchi 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter-parent 17 | 2.1.4.RELEASE 18 | 19 | 20 | 21 | 22 | UTF-8 23 | UTF-8 24 | 1.8 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-thymeleaf 31 | 32 | 33 | com.github.penggle 34 | kaptcha 35 | 2.3.2 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-web 40 | 41 | 42 | org.mybatis.spring.boot 43 | mybatis-spring-boot-starter 44 | 1.3.2 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-cache 49 | 50 | 51 | org.projectlombok 52 | lombok 53 | 1.16.18 54 | provided 55 | 56 | 57 | mysql 58 | mysql-connector-java 59 | runtime 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-test 64 | test 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-configuration-processor 69 | true 70 | 71 | 72 | com.alibaba 73 | druid-spring-boot-starter 74 | 1.1.10 75 | 76 | 77 | org.apache.shiro 78 | shiro-spring-boot-web-starter 79 | 1.4.0 80 | 81 | 82 | 83 | org.apache.shiro 84 | shiro-ehcache 85 | 1.4.0 86 | 87 | 88 | org.apache.commons 89 | commons-lang3 90 | 3.8.1 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | org.springframework.boot 99 | spring-boot-maven-plugin 100 | 101 | 102 | org.apache.maven.plugins 103 | maven-surefire-plugin 104 | 2.20.1 105 | 106 | 107 | true 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "java", 9 | "name": "Debug (Launch) - Current File", 10 | "request": "launch", 11 | "mainClass": "${file}" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.classpath": true, 4 | "**/.project": true, 5 | "**/.settings": true, 6 | "**/.factorypath": true 7 | } 8 | } -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/LitchiCtfApplication.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | import org.springframework.transaction.annotation.EnableTransactionManagement; 8 | 9 | @EnableTransactionManagement 10 | @EnableCaching 11 | @SpringBootApplication() 12 | public class LitchiCtfApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(LitchiCtfApplication.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/config/CsrfConfig.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.config; 2 | 3 | import com.litchi.litchi_ctf.util.csrf.CSRFHandlerInterceptor; 4 | import com.litchi.litchi_ctf.util.csrf.CSRFRequestDataValueProcessor; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 10 | import org.springframework.web.servlet.support.RequestDataValueProcessor; 11 | 12 | @Configuration 13 | public class CsrfConfig implements WebMvcConfigurer { 14 | @Autowired 15 | private CSRFHandlerInterceptor csrfHandlerInterceptor; 16 | @Override 17 | public void addInterceptors(InterceptorRegistry registry) { 18 | registry.addInterceptor(csrfHandlerInterceptor); 19 | } 20 | @Bean(name = "requestDataValueProcessor") 21 | public RequestDataValueProcessor registerDataValueProcessor(){ 22 | return new CSRFRequestDataValueProcessor(); 23 | } 24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/config/DruidConfig.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; 5 | import com.alibaba.druid.support.http.StatViewServlet; 6 | import com.alibaba.druid.support.http.WebStatFilter; 7 | import com.alibaba.druid.wall.WallFilterMBean; 8 | import org.springframework.boot.context.properties.ConfigurationProperties; 9 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 10 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.context.annotation.Primary; 14 | import org.springframework.stereotype.Component; 15 | 16 | import javax.sql.DataSource; 17 | import java.util.Arrays; 18 | import java.util.HashMap; 19 | import java.util.Map; 20 | 21 | /** 22 | * 配置druid,配置管理后台的servlet 23 | * ServletRegistration和web监控的filter 24 | */ 25 | @Configuration 26 | public class DruidConfig { 27 | /** 28 | * 使用ConfigurationProperties将配置中的datasource与datasource绑定起来 29 | * @return Druid类型的DataSource 30 | */ 31 | @Bean 32 | @ConfigurationProperties(prefix = "spring.datasource") 33 | public DataSource druid(){ 34 | return DruidDataSourceBuilder.create().build(); 35 | } 36 | 37 | 38 | @Bean 39 | public ServletRegistrationBean statViewServlet(){ 40 | ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*"); 41 | Map initParams = new HashMap<>(); 42 | initParams.put("loginUsername","admin"); 43 | initParams.put("loginPassword","123456"); 44 | bean.setInitParameters(initParams); 45 | return bean; 46 | } 47 | 48 | @Bean 49 | public FilterRegistrationBean webStatFilter(){ 50 | FilterRegistrationBean bean = new FilterRegistrationBean(new WebStatFilter()); 51 | Map initParams = new HashMap<>(); 52 | initParams.put("exclusions","*.js,*.css,/druid/*"); 53 | bean.setInitParameters(initParams); 54 | bean.setUrlPatterns(Arrays.asList("/*")); 55 | return bean; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/config/KaptchaConfig.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.config; 2 | 3 | import com.google.code.kaptcha.impl.DefaultKaptcha; 4 | import com.google.code.kaptcha.util.Config; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.Properties; 9 | @Component 10 | public class KaptchaConfig { 11 | @Bean 12 | public DefaultKaptcha getDefaultKaptcha() { 13 | com.google.code.kaptcha.impl.DefaultKaptcha defaultKaptcha = new com.google.code.kaptcha.impl.DefaultKaptcha(); 14 | Properties properties = new Properties(); 15 | // 图片边框 16 | properties.setProperty("kaptcha.border", "no"); 17 | // 字体颜色 18 | properties.setProperty("kaptcha.textproducer.font.color", "black"); 19 | // 图片宽 20 | properties.setProperty("kaptcha.image.width", "80"); 21 | // 图片高 22 | properties.setProperty("kaptcha.image.height", "40"); 23 | // 字体大小 24 | properties.setProperty("kaptcha.textproducer.font.size", "30"); 25 | // session key 26 | properties.setProperty("kaptcha.session.key", "code"); 27 | // 验证码长度 28 | properties.setProperty("kaptcha.textproducer.char.string","0123456789"); 29 | properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise"); 30 | properties.setProperty("kaptcha.textproducer.char.length", "4"); 31 | // 字体 32 | properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑"); 33 | Config config = new Config(properties); 34 | defaultKaptcha.setConfig(config); 35 | return defaultKaptcha; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/config/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.config; 2 | 3 | import com.litchi.litchi_ctf.realm.UserRealm; 4 | import org.apache.shiro.cache.ehcache.EhCacheManager; 5 | import org.apache.shiro.spring.LifecycleBeanPostProcessor; 6 | import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; 7 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 8 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 9 | import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import java.util.LinkedHashMap; 13 | import java.util.Map; 14 | 15 | import static org.apache.shiro.web.filter.mgt.DefaultFilter.anon; 16 | 17 | @Configuration 18 | public class ShiroConfig{ 19 | @Bean 20 | public EhCacheManager getEhCacheManager() { 21 | EhCacheManager em = new EhCacheManager(); 22 | em.setCacheManagerConfigFile("classpath:ehcache-shiro.xml"); 23 | return em; 24 | } 25 | @Bean(name = "lifecycleBeanPostProcessor") 26 | public LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { 27 | return new LifecycleBeanPostProcessor(); 28 | } 29 | 30 | @Bean 31 | public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { 32 | DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); 33 | autoProxyCreator.setProxyTargetClass(true); 34 | return autoProxyCreator; 35 | } 36 | 37 | @Bean(name = "userRealm") 38 | public UserRealm userRealm(EhCacheManager cacheManager) { 39 | UserRealm userRealm = new UserRealm(); 40 | userRealm.setCacheManager(cacheManager); 41 | return userRealm; 42 | } 43 | 44 | @Bean(name = "securityManager") 45 | public DefaultWebSecurityManager getDefaultWebSecurityManager(UserRealm userRealm) { 46 | DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager(); 47 | defaultWebSecurityManager.setRealm(userRealm); 48 | defaultWebSecurityManager.setCacheManager(getEhCacheManager()); 49 | return defaultWebSecurityManager; 50 | } 51 | 52 | @Bean 53 | public AuthorizationAttributeSourceAdvisor getAuthorizationAttributeSourceAdvisor( 54 | DefaultWebSecurityManager securityManager) { 55 | AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor(); 56 | advisor.setSecurityManager(securityManager); 57 | return advisor; 58 | } 59 | 60 | /** 61 | * ShiroFilter 62 | * @param securityManager 安全管理器 63 | * @return ShiroFilterFactoryBean 64 | */ 65 | @Bean(name = "shiroFilter") 66 | public ShiroFilterFactoryBean getShiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { 67 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 68 | shiroFilterFactoryBean.setSecurityManager(securityManager); 69 | shiroFilterFactoryBean.setLoginUrl("/home"); 70 | shiroFilterFactoryBean.setSuccessUrl("/index"); 71 | loadShiroFilterChain(shiroFilterFactoryBean); 72 | return shiroFilterFactoryBean; 73 | } 74 | 75 | /** 76 | * 根据自己的业务需求配置 77 | * 顺序会影响配置,授权访问除了上述之外所有的页面,应该放在最后 78 | * filterChainDefinitionMap.put("/**","authc"); 79 | */ 80 | private void loadShiroFilterChain(ShiroFilterFactoryBean shiroFilterFactoryBean) { 81 | Map filterChainDefinitionMap = new LinkedHashMap<>(); 82 | // 需要验证的写 authc 不需要的写 anon 83 | filterChainDefinitionMap.put("/css/**","anon"); 84 | filterChainDefinitionMap.put("/js/**","anon"); 85 | filterChainDefinitionMap.put("/img/**","anon"); 86 | filterChainDefinitionMap.put("/druid/**","anon"); 87 | filterChainDefinitionMap.put("/defaultKaptcha","anon"); 88 | filterChainDefinitionMap.put("/login", "anon"); 89 | filterChainDefinitionMap.put("/home","anon"); 90 | filterChainDefinitionMap.put("/register", "anon"); 91 | filterChainDefinitionMap.put("/file/**","anon"); 92 | filterChainDefinitionMap.put("/admin/**","authc,roles[admin]"); 93 | filterChainDefinitionMap.put("/**","authc"); 94 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/AdminChallengeController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import com.litchi.litchi_ctf.service.ChallengeService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.PathVariable; 11 | import org.springframework.web.servlet.ModelAndView; 12 | 13 | import javax.servlet.http.HttpSession; 14 | 15 | @Controller 16 | @Slf4j 17 | public class AdminChallengeController { 18 | @Autowired 19 | private ChallengeService challengeService; 20 | @GetMapping("/admin/challenge/{id}") 21 | public ModelAndView getChallengeDetail(@PathVariable(name = "id") int cid, HttpSession session){ 22 | ModelAndView mv=new ModelAndView("challengeDetail"); 23 | User user=(User)session.getAttribute("uid"); 24 | Challenge challenge=challengeService.getChallengeById(cid); 25 | mv.addObject("challenge",challenge); 26 | mv.addObject("user",user); 27 | return mv; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/AdminController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.Notice; 5 | import com.litchi.litchi_ctf.pojo.User; 6 | import com.litchi.litchi_ctf.service.ChallengeService; 7 | import com.litchi.litchi_ctf.service.NoticeService; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.servlet.ModelAndView; 13 | 14 | import javax.servlet.http.HttpSession; 15 | import java.util.LinkedList; 16 | import java.util.List; 17 | import java.util.concurrent.ConcurrentHashMap; 18 | 19 | @Controller 20 | @Slf4j 21 | public class AdminController { 22 | @Autowired 23 | private ChallengeService challengeService; 24 | @Autowired 25 | private NoticeService noticeService; 26 | 27 | @GetMapping("/admin/index") 28 | public ModelAndView getAdminIndex(HttpSession session){ 29 | ModelAndView mv=new ModelAndView("redirect:/admin/challengelist"); 30 | return mv; 31 | } 32 | @GetMapping("/admin/notice") 33 | public ModelAndView getAdminNotice(HttpSession session){ 34 | ModelAndView mv=new ModelAndView("addNotice"); 35 | User user=(User)session.getAttribute("user"); 36 | mv.addObject("user",user); 37 | return mv; 38 | } 39 | @GetMapping("/admin/challengelist") 40 | public ModelAndView getChallengeList(HttpSession session){ 41 | ModelAndView mv=new ModelAndView("challengeList"); 42 | User user=(User)session.getAttribute("user"); 43 | mv.addObject("user",user); 44 | ConcurrentHashMap> typeChallengeMap=challengeService.listAllChallenges().getChallengeListMap(); 45 | List allChallengesList=new LinkedList<>(); 46 | typeChallengeMap.values().forEach(typeChallengeList->allChallengesList.addAll(typeChallengeList)); 47 | mv.addObject("allChallengeList",allChallengesList); 48 | return mv; 49 | } 50 | @GetMapping("/admin/addchallenge") 51 | public ModelAndView getAddChallenge(HttpSession session){ 52 | ModelAndView mv=new ModelAndView("addChallenge"); 53 | User user=(User)session.getAttribute("user"); 54 | mv.addObject("user",user); 55 | return mv; 56 | } 57 | @GetMapping("/admin/noticelist") 58 | public ModelAndView getNoticeList(HttpSession session){ 59 | ModelAndView mv=new ModelAndView("noticeList"); 60 | User user=(User)session.getAttribute("user"); 61 | mv.addObject("user",user); 62 | List noticeList=noticeService.getNoticeList(); 63 | mv.addObject("noticeList",noticeList); 64 | return mv; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/AdminEditController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import com.litchi.litchi_ctf.service.ChallengeService; 6 | import com.litchi.litchi_ctf.service.NoticeService; 7 | import org.apache.commons.logging.LogFactory; 8 | import org.apache.shiro.session.Session; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.stereotype.Controller; 13 | import org.springframework.transaction.annotation.Transactional; 14 | import org.springframework.web.bind.annotation.GetMapping; 15 | import org.springframework.web.bind.annotation.PathVariable; 16 | import org.springframework.web.bind.annotation.PostMapping; 17 | import org.springframework.web.servlet.ModelAndView; 18 | import org.springframework.web.servlet.mvc.support.RedirectAttributes; 19 | 20 | import javax.servlet.http.HttpSession; 21 | 22 | @Controller 23 | public class AdminEditController { 24 | private static final Logger log= LoggerFactory.getLogger(AdminEditController.class); 25 | @Autowired 26 | private NoticeService noticeService; 27 | @Autowired 28 | private ChallengeService challengeService; 29 | @PostMapping("/admin/addChallenge") 30 | public ModelAndView addChalleng(HttpSession session,String msg, Challenge challenge){ 31 | ModelAndView mv= new ModelAndView("addChallenge"); 32 | User user=(User)session.getAttribute("user"); 33 | try { 34 | challengeService.addChallenge(challenge); 35 | msg="您已经成功添加题目"+challenge.getTitle(); 36 | log.info("成功添加题目"+challenge.getTitle()); 37 | } 38 | catch (Exception e){ 39 | System.out.println(e.getMessage()); 40 | msg="添加题目失败"; 41 | log.error("添加失败"+e.getStackTrace().toString()); 42 | } 43 | mv.addObject("user",user); 44 | mv.addObject("msg",msg); 45 | return mv; 46 | } 47 | @PostMapping("/admin/editChallenge") 48 | public ModelAndView editChalleng(HttpSession session,String msg, Challenge challenge,RedirectAttributes redirectAttributes){ 49 | ModelAndView mv= new ModelAndView("redirect:/admin/challengelist"); 50 | User user=(User)session.getAttribute("user"); 51 | mv.addObject("user",user); 52 | try { 53 | challengeService.saveChallenge(challenge); 54 | msg="您已经成功修改题目"+challenge.getTitle(); 55 | log.info("修改题目"+challenge.toString()); 56 | } 57 | catch (Exception e){ 58 | msg="修改题目失败"; 59 | log.error("修改失败"+e.getStackTrace().toString()); 60 | } 61 | redirectAttributes.addFlashAttribute("msg",msg); 62 | return mv; 63 | } 64 | @PostMapping("/admin/editNotice") 65 | public ModelAndView editNotice(String msg,String description){ 66 | ModelAndView mv=new ModelAndView("addNotice"); 67 | try { 68 | noticeService.saveNotice(description); 69 | msg="您已经成功发布通知"; 70 | }catch (Exception e){ 71 | msg="发布通知失败"; 72 | } 73 | mv.addObject("msg",msg); 74 | return mv; 75 | } 76 | @GetMapping("/admin/deleteChallenge/{cid}") 77 | public ModelAndView deleteChallenge(String msg, @PathVariable(name = "cid") int cid, RedirectAttributes redirectAttributes){ 78 | try { 79 | challengeService.deleteChallenge(cid); 80 | 81 | msg="您已经成功删除"+cid; 82 | }catch (Exception e){ 83 | msg="删除失败"; 84 | } 85 | redirectAttributes.addFlashAttribute("msg",msg); 86 | ModelAndView mv=new ModelAndView("redirect:/admin/challengelist"); 87 | return mv; 88 | } 89 | @GetMapping("/admin/deleteNotice/{nid}") 90 | public ModelAndView deleteNotice(String msg, @PathVariable(name = "nid") int nid, RedirectAttributes redirectAttributes){ 91 | try { 92 | noticeService.deleteNotice(nid); 93 | msg="您已经成功删除"+nid; 94 | }catch (Exception e){ 95 | msg="删除失败"; 96 | } 97 | redirectAttributes.addFlashAttribute("msg",msg); 98 | ModelAndView mv=new ModelAndView("redirect:/admin/noticelist"); 99 | return mv; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/ChallengeController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.ChallengeType; 5 | import com.litchi.litchi_ctf.pojo.User; 6 | import com.litchi.litchi_ctf.service.ChallengeService; 7 | import com.litchi.litchi_ctf.service.SolveService; 8 | import lombok.extern.slf4j.Slf4j; 9 | import org.apache.commons.lang3.RandomUtils; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.transaction.annotation.Transactional; 13 | import org.springframework.web.bind.annotation.GetMapping; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.servlet.ModelAndView; 16 | 17 | import javax.servlet.http.HttpSession; 18 | import java.util.List; 19 | import java.util.concurrent.ConcurrentHashMap; 20 | 21 | @Slf4j 22 | @Controller 23 | public class ChallengeController { 24 | @Autowired 25 | private ChallengeService challengeService; 26 | @Autowired 27 | private SolveService solveService; 28 | @GetMapping("/challenge") 29 | public ModelAndView getChanllenge(HttpSession session) { 30 | ModelAndView mv=new ModelAndView("Challenge"); 31 | User user=(User) session.getAttribute("user"); 32 | mv.addObject("user",user); 33 | ConcurrentHashMap> typeChallengeMap=challengeService.listAllChallenges().getChallengeListMap(); 34 | for (ChallengeType value : ChallengeType.values()) { 35 | mv.addObject(value.name()+"_SOLVED",user.getSolvedChallenge().get(value.getTypecode())); 36 | } 37 | mv.addObject("typeChallengeMap",typeChallengeMap); 38 | return mv; 39 | } 40 | @PostMapping("/challenge") 41 | @Transactional(rollbackFor = Exception.class) 42 | public ModelAndView postChallenge(String vrifycode,int cid, String flag, String msg,HttpSession session){ 43 | Challenge challenge=challengeService.getChallengeById(cid); 44 | String kaptchaId=(String) session.getAttribute("vrifyCode"); 45 | User user=(User) session.getAttribute("user"); 46 | if (!vrifycode.equals(kaptchaId)){ 47 | msg="对不起,您的验证码有误"; 48 | ModelAndView mv=getChanllenge(session); 49 | mv.addObject("msg",msg); 50 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 51 | return mv; 52 | } 53 | if (challenge.getFlag().equals(flag)){ 54 | List typeSolvedChallenge=user.getSolvedChallenge().get(challenge.getType()); 55 | if (!typeSolvedChallenge.contains(cid)) { 56 | try { 57 | //需要将解决的问题存入,在数据库层面操作,还需要在内存层面操作 58 | solveService.saveNewSolved(challenge, user); 59 | solveService.addOneSolvedNumber(cid); 60 | user.setSolvedNumber(user.getSolvedNumber()+1); 61 | solveService.addOneUserSolvedNumber(user.getUid()); 62 | typeSolvedChallenge.add(cid); 63 | } 64 | catch (Exception e){ 65 | msg="发生未知错误,请重试或者联系管理员"; 66 | ModelAndView mv=getChanllenge(session); 67 | mv.addObject("msg",msg); 68 | return mv; 69 | } 70 | msg="太强了,您成功做出了这道题"; 71 | } 72 | else { 73 | msg="这题您已经做过了,换换别题吧"; 74 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 75 | } 76 | ModelAndView mv=getChanllenge(session); 77 | mv.addObject("msg",msg); 78 | return mv; 79 | } 80 | else{ 81 | ModelAndView mv=getChanllenge(session); 82 | msg="对不起,您答错了"; 83 | mv.addObject("msg",msg); 84 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 85 | return mv; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/FileController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.User; 4 | import com.litchi.litchi_ctf.service.StorageService; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.core.io.Resource; 9 | import org.springframework.http.HttpHeaders; 10 | import org.springframework.http.ResponseEntity; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.GetMapping; 13 | import org.springframework.web.bind.annotation.PathVariable; 14 | import org.springframework.web.bind.annotation.PostMapping; 15 | import org.springframework.web.bind.annotation.ResponseBody; 16 | import org.springframework.web.multipart.MultipartFile; 17 | import org.springframework.web.servlet.ModelAndView; 18 | 19 | import javax.servlet.http.HttpSession; 20 | import java.io.*; 21 | 22 | @Controller 23 | public class FileController { 24 | private final static Logger log= LoggerFactory.getLogger(FileController.class); 25 | @Autowired 26 | private StorageService storageService; 27 | @GetMapping("/file/{filename:.+}") 28 | @ResponseBody 29 | public ResponseEntity getFile(@PathVariable String filename){ 30 | Resource file = storageService.loadAsResource(filename); 31 | return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, 32 | "attachment; filename=\"" + file.getFilename() + "\"").body(file); 33 | 34 | } 35 | @PostMapping("/admin/uploadFile") 36 | public ModelAndView adminPostFile(String msg,HttpSession session, MultipartFile file)throws IOException { 37 | ModelAndView mv=new ModelAndView("addChallenge"); 38 | User user=(User)session.getAttribute("user"); 39 | mv.addObject("user",user); 40 | try { 41 | storageService.init(); 42 | storageService.store(file); 43 | msg="您已经成功上传文件"+file.getOriginalFilename()+"路径为/file/"+file.getOriginalFilename(); 44 | log.info("上传文件"+file.getOriginalFilename()); 45 | } 46 | catch (Exception e){ 47 | msg="上传失败"; 48 | log.error("上传错误",e); 49 | } 50 | mv.addObject("msg",msg); 51 | return mv; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/KaptchaController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.google.code.kaptcha.impl.DefaultKaptcha; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | 9 | import javax.imageio.ImageIO; 10 | import javax.servlet.ServletOutputStream; 11 | import javax.servlet.http.HttpServletRequest; 12 | import javax.servlet.http.HttpServletResponse; 13 | import java.awt.image.BufferedImage; 14 | import java.io.ByteArrayOutputStream; 15 | @Slf4j 16 | @Controller 17 | public class KaptchaController { 18 | @Autowired 19 | private DefaultKaptcha defaultKaptcha; 20 | @RequestMapping("/defaultKaptcha") 21 | public void getKaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception{ 22 | byte[] captchaChallengeAsJpeg = null; 23 | ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); 24 | try { 25 | //生产验证码字符串并保存到session中 26 | String createText = defaultKaptcha.createText(); 27 | request.getSession().setAttribute("vrifyCode", createText); 28 | //使用生产的验证码字符串返回一个BufferedImage对象并转为byte写入到byte数组中 29 | BufferedImage challenge = defaultKaptcha.createImage(createText); 30 | ImageIO.write(challenge, "jpg", jpegOutputStream); 31 | } catch (IllegalArgumentException e) { 32 | response.sendError(HttpServletResponse.SC_NOT_FOUND); 33 | return; 34 | } 35 | 36 | //定义response输出类型为image/jpeg类型,使用response输出流输出图片的byte数组 37 | captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); 38 | response.setHeader("Cache-Control", "no-store"); 39 | response.setHeader("Pragma", "no-cache"); 40 | response.setDateHeader("Expires", 0); 41 | response.setContentType("image/jpeg"); 42 | ServletOutputStream responseOutputStream = 43 | response.getOutputStream(); 44 | responseOutputStream.write(captchaChallengeAsJpeg); 45 | responseOutputStream.flush(); 46 | responseOutputStream.close(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.google.code.kaptcha.impl.DefaultKaptcha; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import com.litchi.litchi_ctf.service.UserService; 6 | import org.apache.commons.lang3.RandomUtils; 7 | import org.apache.shiro.SecurityUtils; 8 | import org.apache.shiro.authc.IncorrectCredentialsException; 9 | import org.apache.shiro.authc.UnknownAccountException; 10 | import org.apache.shiro.authc.UsernamePasswordToken; 11 | import org.apache.shiro.subject.Subject; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Controller; 16 | import org.springframework.web.bind.annotation.GetMapping; 17 | import org.springframework.web.bind.annotation.PostMapping; 18 | 19 | import javax.servlet.http.HttpSession; 20 | import java.util.Map; 21 | 22 | /** 23 | * @author 牛奶冻荔枝 24 | * @date 2018/10/8 25 | * 登录控制器,完成登录逻辑的校验 26 | */ 27 | @Controller 28 | public class LoginController { 29 | @Autowired 30 | private UserService userService; 31 | private static final Logger log = LoggerFactory.getLogger(LoginController.class); 32 | @Autowired 33 | private DefaultKaptcha defaultKaptcha; 34 | @GetMapping("/home") 35 | public String home(){ 36 | return "home"; 37 | } 38 | @GetMapping(value = "/") 39 | public String index() { 40 | return "redirect:/index"; 41 | } 42 | 43 | @GetMapping("/login") 44 | public String getLogin(){ 45 | Subject sub=SecurityUtils.getSubject(); 46 | if (sub.isAuthenticated()&&sub.getSession().getAttribute("USER_SESSION")!=null){ 47 | return "redirect:/index"; 48 | } 49 | else{ 50 | return "login"; 51 | } 52 | } 53 | @PostMapping(value = "/login") 54 | public String doLogin(String vrifycode,String username, String password, HttpSession session, Map messageMap) { 55 | String kaptchaId=(String) session.getAttribute("vrifyCode"); 56 | if (!(vrifycode.equals(kaptchaId))){ 57 | messageMap.put("msg","您输入的验证码有误"); 58 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 59 | return "login"; 60 | } 61 | Subject sub = SecurityUtils.getSubject(); 62 | UsernamePasswordToken token = new UsernamePasswordToken(username, password); 63 | try { 64 | sub.login(token); 65 | } catch (UnknownAccountException e) { 66 | log.error("对用户[{}]进行登录验证,验证未通过,用户不存在", username); 67 | messageMap.put("msg","您登录的用户不存在"); 68 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 69 | token.clear(); 70 | return "login"; 71 | } catch (IncorrectCredentialsException e){ 72 | log.error("对用户[{}]进行登录验证,验证未通过,密码不正确",username); 73 | messageMap.put("msg","您的密码错误,请重新登录"); 74 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 75 | token.clear(); 76 | return "login"; 77 | } 78 | User user=(User)sub.getSession().getAttribute("USER_SESSION"); 79 | user=userService.getUserById(user.getUid()); 80 | log.info("用户[{}]成功登陆",username); 81 | session.setAttribute("user",user); 82 | return "redirect:/index"; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/NoticeController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.Notice; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import com.litchi.litchi_ctf.service.NoticeService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.servlet.ModelAndView; 11 | 12 | import javax.servlet.http.HttpSession; 13 | import java.util.List; 14 | @Slf4j 15 | @Controller 16 | public class NoticeController { 17 | @Autowired 18 | private NoticeService noticeService; 19 | @GetMapping("/notice") 20 | public ModelAndView getNotice(HttpSession session){ 21 | ModelAndView mv=new ModelAndView("notice"); 22 | User user=(User)session.getAttribute("user"); 23 | mv.addObject("user",user); 24 | List< Notice > noticeList=noticeService.getNoticeList(); 25 | mv.addObject("noticeList",noticeList); 26 | return mv; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/RankController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.User; 4 | import com.litchi.litchi_ctf.service.RankService; 5 | import com.litchi.litchi_ctf.service.SolveService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.servlet.ModelAndView; 11 | 12 | import javax.servlet.http.HttpSession; 13 | import java.util.List; 14 | @Slf4j 15 | @Controller 16 | public class RankController { 17 | @Autowired 18 | private SolveService solveService; 19 | @Autowired 20 | private RankService rankService; 21 | @GetMapping("/rank") 22 | public ModelAndView getRank(HttpSession session){ 23 | ModelAndView mv=new ModelAndView("rank"); 24 | User user=(User)session.getAttribute("user"); 25 | mv.addObject("user",user); 26 | List userRankList=rankService.getUserRankList(); 27 | mv.addObject("userRankList",userRankList); 28 | return mv; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/RegisterController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.User; 4 | import com.litchi.litchi_ctf.service.UserService; 5 | import org.apache.commons.lang3.RandomUtils; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.dao.DuplicateKeyException; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.web.bind.annotation.GetMapping; 12 | import org.springframework.web.bind.annotation.PostMapping; 13 | 14 | import javax.servlet.http.HttpSession; 15 | import java.util.Map; 16 | 17 | /** 18 | * @author 牛奶冻荔枝 19 | * @date 2017/10/8 20 | * 21 | */ 22 | @Controller 23 | public class RegisterController { 24 | private static final Logger log= LoggerFactory.getLogger(RegisterController.class); 25 | @Autowired 26 | private UserService userService; 27 | @PostMapping(value = "/register") 28 | public String register(HttpSession session, String vrifycode, User user, Map map){ 29 | String kaptchaId=(String) session.getAttribute("vrifyCode"); 30 | if (!vrifycode.equals(kaptchaId)){ 31 | map.put("msg","您输入的验证码有误"); 32 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 33 | return "register"; 34 | } 35 | try { 36 | userService.insertUser(user); 37 | }catch (DuplicateKeyException e){ 38 | map.put("msg","您输入的用户名已经存在"); 39 | session.setAttribute("vrifyCode", RandomUtils.nextInt(10000,99999)); 40 | return "register"; 41 | } 42 | log.info("用户[{}]已经成功注册",user.getUsername()); 43 | map.put("msg","您已经成功注册,前往登录页面登录"); 44 | return "register"; 45 | } 46 | @GetMapping(value = "/register") 47 | public String getRegister(){ 48 | return "register"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/SignoutController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.User; 4 | import org.apache.shiro.SecurityUtils; 5 | import org.apache.shiro.subject.Subject; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | 11 | @Controller 12 | public class SignoutController { 13 | private static final Logger log= LoggerFactory.getLogger(SignoutController.class); 14 | @GetMapping("/sign_out") 15 | public String signOut(User user){ 16 | Subject subject= SecurityUtils.getSubject(); 17 | if (subject.isAuthenticated()){ 18 | subject.logout(); 19 | log.info("用户[{}]登出",user.getUsername()); 20 | 21 | } 22 | return "redirect:/home"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/controller/indexController.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.controller; 2 | 3 | import com.litchi.litchi_ctf.pojo.ChallengeType; 4 | import com.litchi.litchi_ctf.pojo.Notice; 5 | import com.litchi.litchi_ctf.pojo.User; 6 | import com.litchi.litchi_ctf.service.*; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.web.bind.annotation.GetMapping; 11 | import org.springframework.web.servlet.ModelAndView; 12 | 13 | import javax.servlet.http.HttpSession; 14 | import java.util.LinkedList; 15 | import java.util.List; 16 | @Slf4j 17 | @Controller 18 | public class indexController { 19 | @Autowired 20 | private HttpSession session; 21 | @Autowired 22 | private UserService userService; 23 | @Autowired 24 | private SolveService solveService; 25 | @Autowired 26 | private RankService rankService; 27 | @Autowired 28 | private NoticeService noticeService; 29 | @Autowired 30 | private ChallengeService challengeService; 31 | @GetMapping("/index") 32 | public ModelAndView getindex(){ 33 | ModelAndView mv=new ModelAndView(); 34 | //刷新用户状态 35 | User user=userService.getUserById(((User)session.getAttribute("user")).getUid()); 36 | session.setAttribute("user",user); 37 | //getTopFiveUserList 38 | List userRankList=rankService.getUserRankList(); 39 | List topFive; 40 | if (userRankList.size()>=5){ 41 | topFive=userRankList.subList(0,5); 42 | } 43 | else { 44 | topFive=userRankList; 45 | } 46 | List noticeList=noticeService.getNoticeList(); 47 | List lastNoticeList=new LinkedList<>(); 48 | if (noticeList.size()>=3){ 49 | lastNoticeList=noticeList.subList(0,3); 50 | } 51 | else { 52 | lastNoticeList=noticeList; 53 | } 54 | //取出用户各个类型题目的解题总数 55 | int[] countSolved=new int[7]; 56 | for (int i = 1; i <7; i++) { 57 | countSolved[i]=user.getSolvedChallenge().get(i).size(); 58 | mv.addObject(ChallengeType.values()[i-1].name(),countSolved[i]); 59 | } 60 | int userNumber=userService.getUserNumber(); 61 | mv.addObject("userNumber",userNumber); 62 | mv.addObject("lastNoticeList",lastNoticeList); 63 | mv.addObject("rank",rankService.getUserRankByUid(user.getUid())); 64 | mv.addObject("user",user); 65 | mv.addObject("topFive",topFive); 66 | mv.setViewName("index"); 67 | return mv; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/mapper/Challengemapper.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import org.apache.ibatis.annotations.*; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.List; 8 | 9 | @Mapper 10 | public interface Challengemapper { 11 | @Select("Select title,cid,flag,type,link,description,solved_number From challenge where type=#{type}") 12 | public List listChallengesByType(int type); 13 | @Select("Select title,cid,flag,type,link,description,solved_number From challenge where cid=#{cid}") 14 | public Challenge getChallengeById(int cid); 15 | @Select("Select title,cid,flag,type,link,description,solved_number From challenge") 16 | public List listAllChallenges(); 17 | @Update("UPDATE challenge set title=#{title},flag=#{flag},description=#{description},link=#{link} WHERE cid=#{cid}") 18 | public int updateChallenge(Challenge challenge); 19 | @Delete("DELETE FROM challenge where cid =#{cid}") 20 | public int deleteChallengeById(int cid); 21 | @Insert("Insert into challenge(title,flag,description,link,type) values (#{title},#{flag},#{description},#{link},#{type})") 22 | public int insertChallenge(Challenge challenge); 23 | @Select("SELECT count(*) from challenge") 24 | public int countChallengesNumber(); 25 | } 26 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/mapper/Noticemapper.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import com.litchi.litchi_ctf.pojo.Notice; 4 | import org.apache.ibatis.annotations.*; 5 | 6 | import java.util.List; 7 | 8 | @Mapper 9 | public interface Noticemapper { 10 | /** 11 | * @return 返回按时间排序后的通知列表(最新的排在最前面) 12 | */ 13 | @Select("SELECT nid,date,description FROM notice ORDER BY date DESC") 14 | public List listAllNotices(); 15 | @Insert("INSERT INTO notice(date,description) values (CURRENT_TIME,#{description})") 16 | public int insertNotice(String description); 17 | @Delete("Delete from notice where nid=#{nid}") 18 | public int deleteNotice(int nid); 19 | } 20 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/mapper/Rankmapper.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import com.litchi.litchi_ctf.pojo.RankList; 4 | import org.apache.ibatis.annotations.Mapper; 5 | import org.apache.ibatis.annotations.Select; 6 | 7 | @Mapper 8 | public interface Rankmapper { 9 | @Select("SELECT uid FROM(SELECT uid FROM solve GROUP BY uid ORDER BY count(cid) DESC) a union (select uid from user)") 10 | public int[] getRanklist(); 11 | @Select("SELECT user_number from rank order by rid") 12 | public int[] listCountSolvedUserNumber(); 13 | @Select("SELECT solved_number,user_number from rankview ORDER BY solved_number desc") 14 | RankList[] countUserNumberOfSolvedNumber(); 15 | } 16 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/mapper/Solvemapper.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import org.apache.ibatis.annotations.*; 4 | import org.apache.ibatis.session.ResultHandler; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | *Type类型解释:Web-1 Pwn-2 Misc-3 Cypto-4 Code-5 Re-6 10 | */ 11 | @Mapper 12 | public interface Solvemapper { 13 | 14 | @Select("SELECT cid,type FROM challenge where cid in(SELECT cid FROM solve where uid=#{uid})") 15 | @ResultType(Map.class) 16 | void listTypeGroupSolvedByUserId(@Param("uid")Integer uid,ResultHandler resultHandler); 17 | @Insert("Insert into solve(cid,uid) values(#{cid},#{uid})") 18 | int insertNewSolve(@Param("cid") int cid,@Param("uid") int uid); 19 | @Update("UPDATE challenge set solved_number=solved_number+1 where cid=#{cid}") 20 | int addOneSolvedNumber(int cid); 21 | @Update("UPDATE user set solved_number=solved_number+1 where uid=#{uid}") 22 | int addOneUserSolvedNumber(int uid); 23 | @Delete("DELETE from solve where cid=#{cid}") 24 | int deleteSolvedByCid(int cid); 25 | } 26 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/mapper/Usermapper.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import org.apache.ibatis.annotations.Insert; 6 | import org.apache.ibatis.annotations.Mapper; 7 | import org.apache.ibatis.annotations.Select; 8 | import org.apache.ibatis.annotations.Update; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * 用户dao,使用mybatis 14 | */ 15 | 16 | @Mapper 17 | public interface Usermapper { 18 | @Select("Select uid,username,password,class_number,email,role,true_name,solved_number from user where username=#{username}") 19 | public User getUserByUsername(String username); 20 | @Select("Select uid,username,password,class_number,email,role,true_name,solved_number from user where uid=#{uid}") 21 | public User getUserById(Integer uid); 22 | @Insert("Insert into user(username,true_name,password,class_number,email) values (#{username},#{trueName},#{password},#{classNumber}" + 23 | ",#{email})") 24 | public Integer insertUser(User user); 25 | @Select("SELECT count(uid) FROM user") 26 | public int SelectUserNumber(); 27 | @Select("SELECT solved_number from user where uid=#{uid}") 28 | public Integer getUserSolvedNumberById(Integer id); 29 | @Select("SELECT uid,username,password,class_number,email,role,true_name,solved_number from user order by solved_number desc") 30 | public List listUsersDescOrderBySolvedNumber(); 31 | @Update("UPDATE user set solved_number=solved_number-1 where uid in (SELECT uid from solve where cid=#{cid})") 32 | int updateSolvedNumberCauseByChallengeDelete(int cid); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/pojo/Challenge.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.pojo; 2 | public class Challenge { 3 | private Integer cid; 4 | private String flag; 5 | private String title; 6 | private Integer type; 7 | private String description; 8 | private int solvedNumber; 9 | private String link; 10 | 11 | public void setCid(Integer cid) { 12 | this.cid = cid; 13 | } 14 | 15 | public String getDescription() { 16 | return description; 17 | } 18 | 19 | public void setDescription(String description) { 20 | this.description = description; 21 | } 22 | 23 | public String getLink() { 24 | return link; 25 | } 26 | 27 | public void setLink(String link) { 28 | this.link = link; 29 | } 30 | 31 | public Integer getCid() { 32 | return cid; 33 | } 34 | 35 | public void setId(Integer id) { 36 | this.cid = cid; 37 | } 38 | 39 | public String getFlag() { 40 | return flag; 41 | } 42 | 43 | public void setFlag(String flag) { 44 | this.flag = flag; 45 | } 46 | 47 | public String getTitle() { 48 | return title; 49 | } 50 | 51 | public void setTitle(String title) { 52 | this.title = title; 53 | } 54 | 55 | public Integer getType() { 56 | return type; 57 | } 58 | 59 | public void setType(Integer type) { 60 | this.type = type; 61 | } 62 | 63 | public int getSolvedNumber() { 64 | return solvedNumber; 65 | } 66 | 67 | public void setSolvedNumber(int solvedNumber) { 68 | this.solvedNumber = solvedNumber; 69 | } 70 | 71 | @Override 72 | public String toString() { 73 | return "Challenge{" + 74 | "cid=" + cid + 75 | ", flag='" + flag + '\'' + 76 | ", title='" + title + '\'' + 77 | ", type=" + type + 78 | ", description='" + description + '\'' + 79 | ", solvedNumber=" + solvedNumber + 80 | ", link='" + link + '\'' + 81 | '}'; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/pojo/ChallengeList.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.pojo; 2 | 3 | import java.util.LinkedList; 4 | import java.util.List; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | 7 | public class ChallengeList { 8 | 9 | private static ChallengeList challengeList=new ChallengeList(); 10 | private ConcurrentHashMap> challengeListMap=new ConcurrentHashMap<>(); 11 | 12 | private ChallengeList(){ 13 | } 14 | public static ChallengeList getInstance() { 15 | return challengeList; 16 | } 17 | 18 | public ConcurrentHashMap> getChallengeListMap() { 19 | return challengeListMap; 20 | } 21 | 22 | public void setChallengeListMap(ConcurrentHashMap> challengeListMap) { 23 | this.challengeListMap = challengeListMap; 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/pojo/ChallengeType.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.pojo; 2 | public enum ChallengeType { 3 | /** 4 | * 对应六种CTF比赛赛题 5 | */ 6 | WEB(1), 7 | PWN(2), 8 | MISC(3), 9 | CYPTO(4), 10 | CODE(5), 11 | RE(6); 12 | private int typecode; 13 | ChallengeType(int typecode){ 14 | this.typecode=typecode; 15 | } 16 | 17 | public int getTypecode() { 18 | return typecode; 19 | } 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/pojo/Notice.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.pojo; 2 | 3 | import java.util.Date; 4 | 5 | public class Notice { 6 | public int getNid() { 7 | return nid; 8 | } 9 | 10 | public void setNid(int nid) { 11 | this.nid = nid; 12 | } 13 | 14 | private int nid; 15 | private String description; 16 | private Date date; 17 | 18 | public String getDescription() { 19 | return description; 20 | } 21 | 22 | public void setDescription(String description) { 23 | this.description = description; 24 | } 25 | 26 | public Date getDate() { 27 | return date; 28 | } 29 | 30 | public void setDate(Date date) { 31 | this.date = date; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/pojo/RankList.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.pojo; 2 | 3 | public class RankList { 4 | private Integer solvedNumber; 5 | private Integer userNumber; 6 | 7 | public Integer getSolvedNumber() { 8 | return solvedNumber; 9 | } 10 | 11 | public void setSolvedNumber(Integer solvedNumber) { 12 | this.solvedNumber = solvedNumber; 13 | } 14 | 15 | public Integer getUserNumber() { 16 | return userNumber; 17 | } 18 | 19 | public void setUserNumber(Integer userNumber) { 20 | this.userNumber = userNumber; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/pojo/User.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.pojo; 2 | import java.util.HashMap; 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * @param solvedChallenge 对应的是一个键为类型码, 8 | * 值为一个该类型解题id链表的hashmap 9 | */ 10 | public class User { 11 | private Integer uid; 12 | private String username; 13 | private String password; 14 | private String classNumber; 15 | private String email; 16 | private String role; 17 | private String trueName; 18 | 19 | public Integer getSolvedNumber() { 20 | return solvedNumber; 21 | } 22 | 23 | public void setSolvedNumber(Integer solvedNumber) { 24 | this.solvedNumber = solvedNumber; 25 | } 26 | 27 | private Integer solvedNumber; 28 | private Map> solvedChallenge=new HashMap<>(); 29 | 30 | public Integer getUid() { 31 | return uid; 32 | } 33 | 34 | public void setUid(Integer uid) { 35 | this.uid = uid; 36 | } 37 | 38 | public String getUsername() { 39 | return username; 40 | } 41 | 42 | public void setUsername(String username) { 43 | this.username = username; 44 | } 45 | 46 | public String getPassword() { 47 | return password; 48 | } 49 | 50 | public void setPassword(String password) { 51 | this.password = password; 52 | } 53 | 54 | public String getClassNumber() { 55 | return classNumber; 56 | } 57 | 58 | public void setClassNumber(String classNumber) { 59 | this.classNumber = classNumber; 60 | } 61 | 62 | public String getEmail() { 63 | return email; 64 | } 65 | 66 | public void setEmail(String email) { 67 | this.email = email; 68 | } 69 | 70 | public String getRole() { 71 | return role; 72 | } 73 | 74 | public void setRole(String role) { 75 | this.role = role; 76 | } 77 | 78 | public String getTrueName() { 79 | return trueName; 80 | } 81 | 82 | public void setTrueName(String trueName) { 83 | this.trueName = trueName; 84 | } 85 | 86 | public Map> getSolvedChallenge() { 87 | return solvedChallenge; 88 | } 89 | 90 | public void setSolvedChallenge(Map> solvedChallenge) { 91 | this.solvedChallenge = solvedChallenge; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/realm/UserRealm.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.realm; 2 | 3 | import com.litchi.litchi_ctf.mapper.Usermapper; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import org.apache.shiro.SecurityUtils; 6 | import org.apache.shiro.authc.*; 7 | import org.apache.shiro.authz.AuthorizationInfo; 8 | import org.apache.shiro.authz.SimpleAuthorizationInfo; 9 | import org.apache.shiro.realm.AuthorizingRealm; 10 | import org.apache.shiro.session.Session; 11 | import org.apache.shiro.subject.PrincipalCollection; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | 14 | import java.util.HashSet; 15 | import java.util.Optional; 16 | import java.util.Set; 17 | 18 | 19 | /** 20 | * @author 牛奶冻荔枝 21 | * 一个用户角色类,用于shiro框架的校验 22 | */ 23 | public class UserRealm extends AuthorizingRealm { 24 | @Autowired 25 | private Usermapper usermapper; 26 | 27 | @Override 28 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) 29 | throws AuthenticationException { 30 | String principal = (String) token.getPrincipal(); 31 | //使用Optional来解决nullException的问题,这里的usermapper.getUserByUsername 32 | User user = Optional.ofNullable(usermapper.getUserByUsername(principal)).orElseThrow(UnknownAccountException::new); 33 | SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(principal, user.getPassword(), getName()); 34 | Session session = SecurityUtils.getSubject().getSession(); 35 | session.setAttribute("USER_SESSION", user); 36 | return authenticationInfo; 37 | } 38 | 39 | @Override 40 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) { 41 | Session session = SecurityUtils.getSubject().getSession(); 42 | User user = (User) session.getAttribute("USER_SESSION"); 43 | // 权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission) 44 | SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); 45 | // 用户的角色集合 46 | Set roles = new HashSet<>(); 47 | String[] roleList={"admin","normal"}; 48 | roles.add(roleList[Integer.parseInt(user.getRole())-1]); 49 | info.setRoles(roles); 50 | return info; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/ChallengeService.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.ChallengeList; 5 | 6 | public interface ChallengeService { 7 | ChallengeList listAllChallenges(); 8 | Challenge getChallengeById(int cid); 9 | int saveChallenge(Challenge challenge); 10 | void deleteChallenge(int cid); 11 | int addChallenge(Challenge challenge); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/NoticeService.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service; 2 | 3 | import com.litchi.litchi_ctf.pojo.Notice; 4 | 5 | import java.util.List; 6 | 7 | public interface NoticeService { 8 | int saveNotice(String description); 9 | int deleteNotice(int nid); 10 | List getNoticeList(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/RankService.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service; 2 | 3 | import com.litchi.litchi_ctf.pojo.User; 4 | 5 | import java.util.List; 6 | 7 | public interface RankService { 8 | List getUserRankList(); 9 | int getUserRankByUid(int uid); 10 | } 11 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/SolveService.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | 6 | public interface SolveService { 7 | void saveNewSolved(Challenge challenge,User user); 8 | int addOneSolvedNumber(int cid); 9 | int addOneUserSolvedNumber(int uid); 10 | } 11 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/StorageService.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service; 2 | 3 | import org.springframework.core.io.Resource; 4 | import org.springframework.web.multipart.MultipartFile; 5 | 6 | import java.nio.file.Path; 7 | import java.util.stream.Stream; 8 | 9 | public interface StorageService { 10 | void init(); 11 | 12 | void store(MultipartFile file); 13 | 14 | Stream loadAll(); 15 | 16 | Path load(String filename); 17 | 18 | Resource loadAsResource(String filename); 19 | 20 | void deleteAll(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service; 2 | 3 | import com.litchi.litchi_ctf.pojo.User; 4 | 5 | 6 | public interface UserService { 7 | User getUserById(Integer id); 8 | Integer insertUser(User user); 9 | Integer getUserNumber(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/serviceImpl/ChallengeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.mapper.Challengemapper; 4 | import com.litchi.litchi_ctf.mapper.Solvemapper; 5 | import com.litchi.litchi_ctf.mapper.Usermapper; 6 | import com.litchi.litchi_ctf.pojo.Challenge; 7 | import com.litchi.litchi_ctf.pojo.ChallengeList; 8 | import com.litchi.litchi_ctf.pojo.ChallengeType; 9 | import com.litchi.litchi_ctf.service.ChallengeService; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | import org.springframework.transaction.annotation.Transactional; 13 | 14 | @Service("ChallengeService") 15 | public class ChallengeServiceImpl implements ChallengeService { 16 | @Autowired 17 | private Challengemapper challengemapper; 18 | @Autowired 19 | private Usermapper usermapper; 20 | @Autowired 21 | private Solvemapper solvemapper; 22 | @Autowired 23 | private ChallengeService challengeService; 24 | @Override 25 | public ChallengeList listAllChallenges() { 26 | ChallengeList challengeList = ChallengeList.getInstance(); 27 | for (ChallengeType value : ChallengeType.values()) { 28 | challengeList.getChallengeListMap().put(value.getTypecode(), challengemapper.listChallengesByType(value.getTypecode())); 29 | } 30 | return challengeList; 31 | } 32 | 33 | @Override 34 | public Challenge getChallengeById(int cid) { 35 | return challengemapper.getChallengeById(cid); 36 | } 37 | 38 | @Override 39 | public int saveChallenge(Challenge challenge) { 40 | return challengemapper.updateChallenge(challenge); 41 | } 42 | 43 | /** 44 | * @param cid 需要删除的题目,删除之后,需要将题目从TypeChallengeMap中移除 45 | * 从数据库移除相关题目信息,将做过这道题的人的solvedNumber-1; 46 | *由于排名界面是视图,所以不需要更改rankview 47 | */ 48 | @Override 49 | @Transactional(rollbackFor = Exception.class) 50 | public void deleteChallenge(int cid) { 51 | Challenge challengeWantToDelete=challengemapper.getChallengeById(cid); 52 | challengemapper.deleteChallengeById(cid); 53 | challengeService.listAllChallenges().getChallengeListMap().get(challengeWantToDelete.getType()).remove(challengeWantToDelete); 54 | usermapper.updateSolvedNumberCauseByChallengeDelete(cid); 55 | solvemapper.deleteSolvedByCid(cid); 56 | } 57 | 58 | @Override 59 | public int addChallenge(Challenge challenge) { 60 | challengeService.listAllChallenges().getChallengeListMap().get(challenge.getType()).add(challenge); 61 | return challengemapper.insertChallenge(challenge); 62 | 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/serviceImpl/NoticeServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.mapper.Noticemapper; 4 | import com.litchi.litchi_ctf.pojo.Notice; 5 | import com.litchi.litchi_ctf.service.NoticeService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import java.util.List; 10 | 11 | @Service("NoticeService") 12 | public class NoticeServiceImpl implements NoticeService { 13 | @Autowired 14 | private Noticemapper noticemapper; 15 | @Override 16 | public int saveNotice(String description) { 17 | return noticemapper.insertNotice(description); 18 | } 19 | @Override 20 | public int deleteNotice(int nid) { 21 | return noticemapper.deleteNotice(nid); 22 | } 23 | @Override 24 | public List getNoticeList() { 25 | return noticemapper.listAllNotices(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/serviceImpl/RankServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | 4 | import com.litchi.litchi_ctf.mapper.Challengemapper; 5 | import com.litchi.litchi_ctf.mapper.Rankmapper; 6 | import com.litchi.litchi_ctf.mapper.Usermapper; 7 | import com.litchi.litchi_ctf.pojo.RankList; 8 | import com.litchi.litchi_ctf.pojo.User; 9 | import com.litchi.litchi_ctf.service.RankService; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.List; 16 | 17 | @Service(value = "RankService") 18 | public class RankServiceImpl implements RankService{ 19 | private static final Logger log= LoggerFactory.getLogger(RankServiceImpl.class); 20 | @Autowired 21 | private Usermapper usermapper; 22 | @Autowired 23 | private Rankmapper rankmapper; 24 | @Autowired 25 | private Challengemapper challengemapper; 26 | @Override 27 | public int getUserRankByUid(int uid) { 28 | Integer solvedNumber=usermapper.getUserSolvedNumberById(uid); 29 | RankList[] countUserNumberOfSolvedNumberList=rankmapper.countUserNumberOfSolvedNumber(); 30 | int countAmountUser=0; 31 | for (RankList rankList : countUserNumberOfSolvedNumberList) { 32 | if (rankList.getSolvedNumber()<=solvedNumber){ 33 | break; 34 | } 35 | else { 36 | countAmountUser=+rankList.getUserNumber(); 37 | } 38 | } 39 | return countAmountUser+1; 40 | } 41 | 42 | @Override 43 | public List getUserRankList() { 44 | return usermapper.listUsersDescOrderBySolvedNumber(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/serviceImpl/SolveServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.mapper.Challengemapper; 4 | import com.litchi.litchi_ctf.mapper.Solvemapper; 5 | import com.litchi.litchi_ctf.pojo.Challenge; 6 | import com.litchi.litchi_ctf.pojo.User; 7 | import com.litchi.litchi_ctf.service.SolveService; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | @Service(value = "SolveService") 12 | public class SolveServiceImpl implements SolveService { 13 | 14 | @Autowired 15 | private Challengemapper challengemapper; 16 | @Autowired 17 | private Solvemapper solvemapper; 18 | 19 | 20 | @Override 21 | public void saveNewSolved(Challenge challenge,User user) { 22 | solvemapper.insertNewSolve(challenge.getCid(),user.getUid()); 23 | } 24 | 25 | @Override 26 | public int addOneSolvedNumber(int cid) { 27 | return solvemapper.addOneSolvedNumber(cid); 28 | } 29 | 30 | @Override 31 | public int addOneUserSolvedNumber(int uid) { 32 | return solvemapper.addOneUserSolvedNumber(uid); 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/serviceImpl/StorageServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.service.StorageService; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.core.io.Resource; 6 | import org.springframework.core.io.UrlResource; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.util.FileSystemUtils; 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import java.io.IOException; 12 | import java.net.MalformedURLException; 13 | import java.nio.file.Files; 14 | import java.nio.file.Path; 15 | import java.nio.file.Paths; 16 | import java.util.stream.Stream; 17 | 18 | @Service(value = "StorageService") 19 | public class StorageServiceImpl implements StorageService{ 20 | @Value("${litchi.file-location}") 21 | private static String fileLocation="./"; 22 | // 文件保存的路径 23 | private final Path rootLocation = Paths.get(fileLocation); 24 | 25 | @Override 26 | public void init() { 27 | // 初始化目录, 保证目录存在 28 | try { 29 | if (!Files.exists(rootLocation)) { 30 | Files.createDirectory(rootLocation); 31 | } 32 | } catch (IOException e) { 33 | throw new RuntimeException("Could not initialize storage", e); 34 | } 35 | } 36 | 37 | @Override 38 | public void store(MultipartFile file) { 39 | 40 | // 将文件保存到目录中 41 | try { 42 | if (file.isEmpty()) { 43 | throw new RuntimeException("Failed to store empty file" + file.getOriginalFilename()); 44 | } 45 | String dstFile = file.getOriginalFilename(); 46 | Files.copy(file.getInputStream(), this.rootLocation.resolve(dstFile)); 47 | } catch (IOException e) { 48 | throw new RuntimeException("Failed to store file" + file.getOriginalFilename(), e); 49 | } 50 | } 51 | 52 | @Override 53 | public Stream loadAll() { 54 | // 遍历目录下的文件 55 | try { 56 | return Files.walk(this.rootLocation, 1) 57 | .filter(path -> !path.equals(this.rootLocation)) 58 | .map(path -> this.rootLocation.relativize(path)); 59 | } catch (IOException e) { 60 | throw new RuntimeException("Failed to read stored files", e); 61 | } 62 | } 63 | 64 | @Override 65 | public Path load(String filename) { 66 | // 读取指定文件的路径 67 | return rootLocation.resolve(filename); 68 | } 69 | 70 | @Override 71 | public Resource loadAsResource(String filename) { 72 | // 读取指定路径的内容 73 | try { 74 | Path file = load(filename); 75 | Resource resource = new UrlResource(file.toUri()); 76 | if (resource.exists() || resource.isReadable()) { 77 | return resource; 78 | } else { 79 | throw new RuntimeException("Could not read file:" + filename); 80 | 81 | } 82 | } catch (MalformedURLException e) { 83 | throw new RuntimeException("Could not read file:" + filename, e); 84 | } 85 | } 86 | 87 | @Override 88 | public void deleteAll() { 89 | // 删除目录 90 | FileSystemUtils.deleteRecursively(rootLocation.toFile()); 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/service/serviceImpl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | 4 | import com.litchi.litchi_ctf.mapper.Solvemapper; 5 | import com.litchi.litchi_ctf.mapper.Usermapper; 6 | import com.litchi.litchi_ctf.pojo.User; 7 | import com.litchi.litchi_ctf.service.UserService; 8 | import com.litchi.litchi_ctf.util.TypeChallengeResultHandler; 9 | import org.apache.ibatis.session.ResultHandler; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.List; 14 | import java.util.Map; 15 | 16 | @Service(value = "UserService") 17 | public class UserServiceImpl implements UserService{ 18 | @Autowired 19 | private Usermapper usermapper; 20 | @Autowired 21 | private Solvemapper solvemapper; 22 | /** 23 | * 24 | * @param id 25 | * @return 完整的user信息,包括其各种类型的题目的解题情况 26 | */ 27 | @Override 28 | public User getUserById(Integer id) { 29 | User user=usermapper.getUserById(id); 30 | ResultHandler resultHandler=new TypeChallengeResultHandler(); 31 | solvemapper.listTypeGroupSolvedByUserId(id,resultHandler); 32 | Map> typeSolvedChallenges=((TypeChallengeResultHandler) resultHandler).getResults(); 33 | user.setSolvedChallenge(typeSolvedChallenges); 34 | return user; 35 | } 36 | 37 | /** 38 | * @param user 插入的用户 39 | * @return 改变的行数 40 | */ 41 | @Override 42 | public Integer insertUser(User user) { 43 | return usermapper.insertUser(user); 44 | } 45 | 46 | @Override 47 | public Integer getUserNumber() { 48 | return usermapper.SelectUserNumber(); 49 | } 50 | 51 | 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/util/TypeChallengeResultHandler.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.util; 2 | 3 | import com.litchi.litchi_ctf.pojo.ChallengeType; 4 | import org.apache.ibatis.session.ResultContext; 5 | import org.apache.ibatis.session.ResultHandler; 6 | 7 | import java.util.HashMap; 8 | import java.util.LinkedList; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public class TypeChallengeResultHandler implements ResultHandler { 13 | private Map> results=new HashMap<>(); 14 | public TypeChallengeResultHandler(){ 15 | List webList=new LinkedList<>(); 16 | List pwnList=new LinkedList<>(); 17 | List miscList=new LinkedList<>(); 18 | List cyptoList=new LinkedList<>(); 19 | List codeList=new LinkedList<>(); 20 | List reList=new LinkedList<>(); 21 | this.results.put(ChallengeType.WEB.getTypecode(),webList); 22 | this.results.put(ChallengeType.PWN.getTypecode(),pwnList); 23 | this.results.put(ChallengeType.MISC.getTypecode(),miscList); 24 | this.results.put(ChallengeType.CYPTO.getTypecode(),cyptoList); 25 | this.results.put(ChallengeType.CODE.getTypecode(),codeList); 26 | this.results.put(ChallengeType.RE.getTypecode(),reList); 27 | } 28 | @Override 29 | public void handleResult(ResultContext resultContext) { 30 | 31 | Map resultObject=(Map)resultContext.getResultObject(); 32 | results.get((Integer) resultObject.get("type")).add((Integer) resultObject.get("cid")); 33 | } 34 | 35 | public Map> getResults() { 36 | return results; 37 | } 38 | 39 | public void setResults(Map> results) { 40 | this.results = results; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/util/csrf/CSRFHandlerInterceptor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.litchi.litchi_ctf.util.csrf; 5 | 6 | import org.springframework.stereotype.Component; 7 | import org.springframework.web.servlet.HandlerInterceptor; 8 | import org.springframework.web.servlet.ModelAndView; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import javax.servlet.http.HttpSession; 13 | 14 | /** 15 | * Request预处理器,先过滤csrf然后才允许访问对应controller 16 | * 17 | * @author Jarvis 18 | * @date 2016年4月7日 19 | */ 20 | @Component 21 | public class CSRFHandlerInterceptor implements HandlerInterceptor{ 22 | 23 | @Override 24 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 25 | throws Exception { 26 | 27 | if (!request.getMethod().equalsIgnoreCase("POST")) { 28 | return true; 29 | } else { 30 | if (request.getServletPath().equals("/admin/fileUpload")){ 31 | return true; 32 | } 33 | HttpSession session = request.getSession(); 34 | String sessionToken = CSRFTokenManager.getCurrentSessionToken(session); 35 | if (sessionToken==null) { 36 | response.sendError(HttpServletResponse.SC_FORBIDDEN, "CSRF Token Expired!!"); 37 | return false; 38 | } 39 | String requestToken = CSRFTokenManager.getTokenFromRequest(request); 40 | CSRFTokenManager.createNewTokenForSession(request.getSession()); 41 | if (requestToken!=null && sessionToken.equals(requestToken)) { 42 | return true; 43 | } else { 44 | response.sendError(HttpServletResponse.SC_FORBIDDEN, "Bad or missing CSRF value !!"); 45 | return false; 46 | } 47 | } 48 | //return false; 49 | } 50 | 51 | @Override 52 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 53 | ModelAndView modelAndView) throws Exception { 54 | // TODO Auto-generated method stub 55 | 56 | } 57 | 58 | @Override 59 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 60 | throws Exception { 61 | // TODO Auto-generated method stub 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/util/csrf/CSRFRequestDataValueProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.litchi.litchi_ctf.util.csrf; 5 | 6 | import org.springframework.web.servlet.support.RequestDataValueProcessor; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * 过滤CSRF请求 14 | * 15 | * @author Jarvis 16 | * @date 2016年4月7日 17 | */ 18 | 19 | public class CSRFRequestDataValueProcessor implements RequestDataValueProcessor{ 20 | 21 | @Override 22 | public String processAction(HttpServletRequest request, String action, String httpMethod) { 23 | return action; 24 | } 25 | 26 | @Override 27 | public String processFormFieldValue(HttpServletRequest request, String name, String value, String type) { 28 | 29 | return value; 30 | } 31 | 32 | @Override 33 | public Map getExtraHiddenFields(HttpServletRequest request) { 34 | Map hiddenFields = new HashMap(); 35 | hiddenFields.put(CSRFTokenManager.CSRF_PARAM_NAME, CSRFTokenManager.createNewTokenForSession(request.getSession())); 36 | return hiddenFields; 37 | } 38 | 39 | @Override 40 | public String processUrl(HttpServletRequest request, String url) { 41 | return url; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/java/com/litchi/litchi_ctf/util/csrf/CSRFTokenManager.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.litchi.litchi_ctf.util.csrf; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpSession; 8 | import java.util.UUID; 9 | 10 | /** 11 | * CSRF Token管理 12 | * 13 | */ 14 | final class CSRFTokenManager { 15 | /** 16 | * The token parameter name 17 | */ 18 | static final String CSRF_PARAM_NAME = "litchi_csrf_token"; 19 | 20 | /** 21 | * The location on the session which stores the token 22 | */ 23 | private final static String CSRF_TOKEN_FOR_SESSION_ATTR_NAME = CSRFTokenManager.class.getName() + ".tokenval"; 24 | 25 | static String createNewTokenForSession(HttpSession session) { 26 | String token = null; 27 | // I cannot allow more than one token on a session - in the case of two requests trying to 28 | // init the token concurrently 29 | synchronized (session) { 30 | token = (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME); 31 | if (null==token) { 32 | token=UUID.randomUUID().toString(); 33 | session.setAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME, token); 34 | } 35 | } 36 | return token; 37 | } 38 | 39 | /** 40 | * Extracts the token value from the session 41 | * @param request 42 | * @return 43 | */ 44 | static String getTokenFromRequest(HttpServletRequest request) { 45 | return request.getParameter(CSRF_PARAM_NAME); 46 | } 47 | 48 | static String getCurrentSessionToken(HttpSession session) { 49 | return (String) session.getAttribute(CSRF_TOKEN_FOR_SESSION_ATTR_NAME); 50 | } 51 | 52 | private CSRFTokenManager() {}; 53 | } 54 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | #数据库的配置 3 | datasource: 4 | url: jdbc:mysql://localhost:3306/my_ctf?serverTimezone=GMT%2B8 5 | username: root 6 | password: 7 | druid: 8 | #初始化时建立物理连接的个数 9 | initial-size: 5 10 | # 最大连接池数量 11 | max-active: 30 12 | # 最小连接池数量 13 | min-idle: 5 14 | # 获取连接时最大等待时间,单位毫秒 15 | max-wait: 60000 16 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 17 | time-between-eviction-runs-millis: 60000 18 | # 连接保持空闲而不被驱逐的最小时间 19 | min-evictable-idle-time-millis: 300000 20 | # 用来检测连接是否有效的sql,要求是一个查询语句 21 | validation-query: SELECT 1 FROM DUAL 22 | # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 23 | test-while-idle: true 24 | # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 25 | test-on-borrow: false 26 | # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 27 | test-on-return: false 28 | # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。 29 | pool-prepared-statements: false 30 | # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。 31 | max-pool-prepared-statement-per-connection-size: 0 32 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计 33 | filters: [wall,stat] 34 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 35 | connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=50 36 | type: com.alibaba.druid.pool.DruidDataSource 37 | mybatis: 38 | configuration: 39 | map-underscore-to-camel-case: true 40 | server: 41 | port: 8083 42 | litchi: 43 | file-location: "./" 44 | 45 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/ehcache-shiro.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/static/img/bg7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Litch1-v/LitctfPlatform/962f1d69ef7baddbd071d08976fbe1985e065917/litchi_ctf/src/main/resources/static/img/bg7.jpg -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/static/js/bg-wordChange.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | 3 | $.fn.typer = function(options){ 4 | 5 | var defaults = $.extend({ 6 | search: '', 7 | replace: [], 8 | speed: 50, 9 | delay: 2000 10 | }, options); 11 | 12 | var bintext = function(length){ 13 | var text = ''; 14 | for(var $i = 0; $i<=length;$i++) { 15 | text = text + Math.floor(Math.random() * 2) 16 | } 17 | return text; 18 | }; 19 | 20 | this.each(function(){ 21 | 22 | var $this = $(this); 23 | var $text = $this.data('text'); 24 | var position = 0; 25 | 26 | var indexOf = $text.indexOf( defaults.search ); 27 | var normal = $text.substr(0, indexOf); 28 | var changer = $text.substr(indexOf, $text.length); 29 | 30 | defaults.replace.push(changer); 31 | 32 | var interval = setInterval(function(){ 33 | var $bintext = ''; 34 | 35 | if( position == indexOf ) { 36 | 37 | $bintext = bintext(changer.length-1); 38 | 39 | $this.html( $text.substr(0, normal.length) ); 40 | $this.append('' + $bintext + '') 41 | 42 | } else if( position > indexOf ) { 43 | 44 | 45 | $bintext = bintext($text.length-1); 46 | 47 | $this.delay(defaults.speed).find('span').html( 48 | changer.substring(0, position - indexOf) + 49 | $bintext.substring(position, ($bintext.length)) 50 | ); 51 | 52 | } else if( position < indexOf ) { 53 | 54 | $bintext = bintext($text.length-1); 55 | 56 | $this.delay(defaults.speed).html( 57 | normal.substring(0, position) + 58 | $bintext.substring(position, ($bintext.length)) 59 | ); 60 | 61 | } 62 | 63 | if( position < $text.length ) { 64 | position++; 65 | } else { 66 | clearInterval(interval); 67 | 68 | var index = 0; 69 | setInterval(function(){ 70 | 71 | var position = 0; 72 | var newText = defaults.replace[index]; 73 | 74 | var changeInterval = setInterval(function(){ 75 | 76 | var $bintext = ''; 77 | for(var $i = 0; $i<=newText.length-1;$i++) { 78 | $bintext = $bintext + Math.floor(Math.random() * 2) 79 | } 80 | 81 | $this.delay(defaults.speed).find('span').html( 82 | newText.substring(0, position) + 83 | $bintext.substring(position, ($bintext.length)) 84 | ); 85 | 86 | if( position < $text.length ) { 87 | position++; 88 | } else { 89 | clearInterval(changeInterval); 90 | } 91 | 92 | }, defaults.speed); 93 | 94 | if( index < defaults.replace.length-1 ) { 95 | index++; 96 | } else { 97 | index = 0; 98 | } 99 | }, defaults.delay) 100 | 101 | 102 | } 103 | }, defaults.speed) 104 | 105 | }); 106 | 107 | } 108 | 109 | 110 | 111 | })(jQuery) 112 | 113 | $(function(){ 114 | $('#slogan').typer({ 115 | search: 'BUPTer', 116 | replace: ['EFFORTer', 'SECURITYer'] 117 | }) 118 | }) -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/static/js/litchi.js: -------------------------------------------------------------------------------- 1 | litchi = { 2 | /**/ 103 | } -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/static/js/material-dashboard.min.js: -------------------------------------------------------------------------------- 1 | isWindows = -1 < navigator.platform.indexOf("Win"), isWindows ? ($(".sidebar .sidebar-wrapper, .main-panel").perfectScrollbar(), $("html").addClass("perfect-scrollbar-on")) : $("html").addClass("perfect-scrollbar-off"); 2 | var breakCards = !0, searchVisible = 0, transparent = !0, transparentDemo = !0, fixedTop = !1, mobile_menu_visible = 0, 3 | mobile_menu_initialized = !1, toggle_initialized = !1, bootstrap_nav_initialized = !1, seq = 0, delays = 80, 4 | durations = 500, seq2 = 0, delays2 = 80, durations2 = 500; 5 | 6 | function debounce(i, n, t) { 7 | var r; 8 | return function () { 9 | var e = this, a = arguments; 10 | clearTimeout(r), r = setTimeout(function () { 11 | r = null, t || i.apply(e, a) 12 | }, n), t && !r && i.apply(e, a) 13 | } 14 | } 15 | 16 | $(document).ready(function () { 17 | $("body").bootstrapMaterialDesign(), $sidebar = $(".sidebar"), md.initSidebarsCheck(), window_width = $(window).width(), md.checkSidebarImage(), 0 != $(".selectpicker").length && $(".selectpicker").selectpicker(), $('[rel="tooltip"]').tooltip(), $(".form-control").on("focus", function () { 18 | $(this).parent(".input-group").addClass("input-group-focus") 19 | }).on("blur", function () { 20 | $(this).parent(".input-group").removeClass("input-group-focus") 21 | }), $('input[type="checkbox"][required="true"], input[type="radio"][required="true"]').on("click", function () { 22 | $(this).hasClass("error") && $(this).closest("div").removeClass("has-error") 23 | }) 24 | }), $(document).on("click", ".navbar-toggler", function () { 25 | if ($toggle = $(this), 1 == mobile_menu_visible) $("html").removeClass("nav-open"), $(".close-layer").remove(), setTimeout(function () { 26 | $toggle.removeClass("toggled") 27 | }, 400), mobile_menu_visible = 0; else { 28 | setTimeout(function () { 29 | $toggle.addClass("toggled") 30 | }, 430); 31 | var e = $('
'); 32 | 0 != $("body").find(".main-panel").length ? e.appendTo(".main-panel") : $("body").hasClass("off-canvas-sidebar") && e.appendTo(".wrapper-full-page"), setTimeout(function () { 33 | e.addClass("visible") 34 | }, 100), e.click(function () { 35 | $("html").removeClass("nav-open"), mobile_menu_visible = 0, e.removeClass("visible"), setTimeout(function () { 36 | e.remove(), $toggle.removeClass("toggled") 37 | }, 400) 38 | }), $("html").addClass("nav-open"), mobile_menu_visible = 1 39 | } 40 | }), $(window).resize(function () { 41 | md.initSidebarsCheck(), seq = seq2 = 0, setTimeout(function () { 42 | md.initDashboardPageCharts() 43 | }, 500) 44 | }), md = { 45 | misc: {navbar_menu_visible: 0, active_collapse: !0, disabled_collapse_init: 0}, 46 | checkSidebarImage: function () { 47 | $sidebar = $(".sidebar"), image_src = $sidebar.data("image"), void 0 !== image_src && (sidebar_container = ' 203 | 210 |
211 | 212 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/addChallenge.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 |

编辑题目

50 |

在这里可以添加题目

51 |
52 |
53 |
54 |
55 |
56 |
57 | 58 | 59 |
60 |
61 |
62 |
63 | 64 | 65 |
66 |
67 |
68 |
69 |
70 |
71 | 72 | 73 |
74 |
75 |
76 |
77 | 78 | 79 |
80 |
81 |
82 |
83 |
84 |
85 | 86 | 87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | 96 | 97 | 98 |
99 |
100 |
101 | 102 | 103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | 120 |
121 | 122 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/addNotice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 |

发布通知

50 |

在这里可以发布通知

51 |
52 |
53 |
54 |
55 |
56 |
57 | 58 | 59 |
60 |
61 |
62 |
63 | 64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | 80 |
81 | 82 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/challengeDetail.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 |

编辑题目

50 |

在这里可以添加题目

51 |
52 |
53 |
54 |
55 |
56 |
57 | 58 | 59 |
60 |
61 |
62 |
63 | 64 | 65 |
66 |
67 |
68 |
69 | 70 | 71 |
72 |
73 |
74 |
75 |
76 |
77 | 78 | 79 |
80 |
81 |
82 |
83 | 84 | 85 |
86 |
87 |
88 |
89 |
90 |
91 | 92 | 93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | 102 | 103 | 104 |
105 |
106 |
107 | 108 | 109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | 122 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/challengeList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 | 43 | 69 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |

题目

77 |

这里是题目列表

78 |
79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 |
ID题目名称删除题目编辑题目
P1umer
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | 106 | 112 |
113 | 114 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 404 - 页面找不到了 7 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
又一个极简的错误页面很抱歉!当前页面找不到了
原因一:你敲错了网址
原因二:你想搞事情,但是没成功
如果刷新页面没能解决问题,你可以联系管理员反馈
28 |
29 | 30 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LitchiCTF 6 | 7 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 19 | 34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |

公告

50 |

训练有关公告都会发布在这里噢

51 |
52 |
53 |
54 | 55 | 这里是纵哥粉丝一号 56 | 57 | 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |

大佬

67 |

快来膜拜大佬吧

68 |
69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
ID用户名真实姓名
P1umer100
84 |
85 |
86 |
87 |
88 |
89 |
90 |

统计

91 |

注册人数

92 |
93 |
94 |
113
95 |
96 |
97 |
98 |
99 |

排名

100 |

你的排名

101 |
102 |
103 |
5
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |

你已经解决的挑战总数

116 |

冲鸭!!!

117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 127 | 134 |
135 | 136 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/indexhead.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | LitchiCTF 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 25 | 75 |
76 | 77 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/navbar.html: -------------------------------------------------------------------------------- 1 | 2 | 33 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/notice.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 74 |
75 |
76 |
77 |
78 |
79 |

关于本站 80 | 1、Flag格式是啥?
81 | Flag标准格式为LitCTF{可见字符},如果题目Flag非标准形式,会给出额外说明。
82 |
2、为啥我看到的网页很混乱……? 83 |
推荐使用Chrome浏览器或者火狐浏览器,以获得最佳的浏览效果,如果仍然有问题(前端写得太菜),请联系管理员
84 |
3、为啥我正常访问网站时,出现了不可名状的错误 85 |
可能是后端的问题(写得太菜),请联系管理员
86 |
4、忘记密码怎么办,怎么更改密码? 87 |
请联系管理员,既可修改密码

88 |
89 |
90 |
91 |
92 |

关于本站 93 | 本站是基于springboot搭建的CTF平台,使用的框架包括但不仅限于
94 | SpringMVC
95 | Thymeleaf
96 | Shiro
97 | Kaptcha
98 | Mybatis
99 | 前端参考:TSCTF ,MATERIAL-UI
100 | 本站的源码后续可能会开源在github上(代码写的太烂需要重构整理)
101 | 关于本次的开发总结也会记录后续也会记录在个人主页上(太懒还没写)
102 |

103 |
104 |
105 |

联系方式 106 | QQ:494678840@qq.com
107 | GitHub:https://github.com/buptchk
108 | 个人主页:http://litch1.club
109 | 邮箱:494678840@qq.com
110 |

111 |
112 |
113 |
114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 |
内容日期
P1umer
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | 138 |
139 | 140 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/noticeList.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 | 43 | 69 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |

通知列表

77 |

这里是通知列表

78 |
79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
ID通知内容删除通知
P1umer
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | 104 | 110 |
111 | 112 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/rank.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |
6 | 41 |
42 | 43 | 69 | 70 |
71 |
72 |
73 |
74 |
75 |
76 |

排名

77 |

个人解题数排名

78 |
79 |
80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
排名用户名解题数
P1umer100
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 | 136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /litchi_ctf/src/main/resources/templates/register.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 25 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/LitchiCtfApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class LitchiCtfApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/dataSource.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf; 2 | 3 | 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | import javax.sql.DataSource; 11 | import java.sql.Connection; 12 | import java.sql.SQLException; 13 | 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | public class dataSource { 17 | @Autowired 18 | private DataSource dataSource; 19 | 20 | @Test 21 | public void contextLoad() throws SQLException { 22 | System.out.println(dataSource.getClass()); 23 | Connection connection=dataSource.getConnection(); 24 | System.out.println(connection); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/mapper/ChallengemapperTest.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | public class ChallengemapperTest { 12 | @Autowired 13 | private Challengemapper challengemapper; 14 | @Test 15 | public void selectChallengeById() { 16 | System.out.println(challengemapper.getChallengeById(3)); 17 | } 18 | } -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/mapper/SolvemapperTest.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import com.litchi.litchi_ctf.util.TypeChallengeResultHandler; 4 | import org.apache.ibatis.session.ResultHandler; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | @RunWith(SpringRunner.class) 11 | @SpringBootTest 12 | public class SolvemapperTest { 13 | @Autowired 14 | private Solvemapper solvemapper; 15 | 16 | @Test 17 | public void listTypeGroupSolvedByUserIdTest(){ 18 | ResultHandler resultHandler=new TypeChallengeResultHandler(); 19 | solvemapper.listTypeGroupSolvedByUserId(1,resultHandler); 20 | System.out.println(((TypeChallengeResultHandler) resultHandler).getResults().toString()); 21 | } 22 | } -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/mapper/UsermapperTest.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.mapper; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class UsermapperTest { 11 | @Autowired 12 | private Usermapper usermapper; 13 | @Autowired 14 | private Rankmapper rankmapper; 15 | @Test 16 | public void listUserOrderBySolvedNumberTest(){ 17 | usermapper.listUsersDescOrderBySolvedNumber().forEach(a->System.out.println(a.getUsername())); 18 | } 19 | @Test 20 | public void getMapOfUserNumberForSolvedNumber(){ 21 | System.out.println(rankmapper.countUserNumberOfSolvedNumber()); 22 | } 23 | } -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/service/serviceImpl/RankServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.service.RankService; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | 10 | import static org.junit.Assert.*; 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest 13 | public class RankServiceImplTest { 14 | @Autowired 15 | private RankService rankService; 16 | @Test 17 | public void getUserRankByUid() { 18 | System.out.println(rankService.getUserRankByUid(1)); 19 | } 20 | @Test 21 | public void getRankListTest(){ 22 | rankService.getUserRankList().forEach(a->System.out.println(a.getUsername())); 23 | } 24 | } -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/service/serviceImpl/SolveServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.pojo.Challenge; 4 | import com.litchi.litchi_ctf.pojo.User; 5 | import com.litchi.litchi_ctf.service.SolveService; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import static org.junit.Assert.*; 13 | @RunWith(SpringRunner.class) 14 | @SpringBootTest() 15 | public class SolveServiceImplTest { 16 | @Autowired 17 | private SolveService solveService; 18 | @Test 19 | public void solvedNumber() { 20 | 21 | } 22 | 23 | @Test 24 | public void solveChallenge() { 25 | } 26 | @Test 27 | public void insertSolve(){ 28 | Challenge challenge=new Challenge(); 29 | challenge.setCid(7); 30 | User user=new User(); 31 | user.setUid(10); 32 | //solveService.saveNewSolved(challenge,user); 33 | } 34 | } -------------------------------------------------------------------------------- /litchi_ctf/src/test/java/com/litchi/litchi_ctf/service/serviceImpl/UserServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.litchi.litchi_ctf.service.serviceImpl; 2 | 3 | import com.litchi.litchi_ctf.LitchiCtfApplicationTests; 4 | import com.litchi.litchi_ctf.pojo.Challenge; 5 | import com.litchi.litchi_ctf.pojo.User; 6 | import com.litchi.litchi_ctf.service.SolveService; 7 | import com.litchi.litchi_ctf.service.UserService; 8 | import org.junit.Before; 9 | import org.junit.Test; 10 | import org.junit.runner.RunWith; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.boot.test.context.SpringBootTest; 13 | import org.springframework.test.context.junit4.SpringRunner; 14 | 15 | import javax.xml.ws.Service; 16 | 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | import static org.junit.Assert.*; 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest() 23 | public class UserServiceImplTest { 24 | @Autowired 25 | private UserService userService; 26 | @Test 27 | public void main() { 28 | User user=userService.getUserById(1); 29 | List typeSolvedChallenge=user.getSolvedChallenge().get(2); 30 | System.out.println(typeSolvedChallenge.contains(3)); 31 | } 32 | 33 | } --------------------------------------------------------------------------------