Pages

Monday, 23 May 2022

Linux透明代理在红队渗透中的应用

 本篇文章,主要是记录工作中想让外网打点和内网渗透的场景进行透明代理的体验。

0x00 前言

决定写这篇文章是我解决了所有问题以后决定记录一下这个过程所写的,因此可能会忽略很多细节上的东西。

  • 问题一:打点的时候经常会被WAF封禁IP怎么办?
  • 问题二:内网的时候只想代理部分目的地址怎么办?

我想大部分人解决问题一的方案就是不断切换出口IP,使得出口地址一直改变,避免被封,而解决问题二的方案可能就是Proxifier或者Proxycap

Proxifier是一款能够实现系统全局代理的软件,它支持的代理类型有:Http、Https、Socks4a、Socks5.

在使用Windows渗透的过程中,我经常使用Proxifier来实现进程单位的代理进行内网渗透,利用好rules就能避免系统全局流量被导入代理,流量流入内网从而暴露自己的一些信息。

以上两个问题在Windows下不是问题,我之前经常使用Kali Linux来进行渗透,自从更新版本以后,它设置系统代理需要自己写PAC文件,这一点增加了一点点学习门槛,并且好像不是那么好用。最近我使用Arch Linux已经有段时间了,并且把它安装在了我的工作机、家庭电脑上,我非常喜欢这个操作系统和这个操作系统的生态。

因此我不得不开始完全适应更多在Linux上渗透的场景,这也让我收获颇多,这篇文章就记录一下我如何学习自己搭建透明代理实现愉快的工作环境。

0x01 透明代理

什么是透明代理?

透明代理的意思是客户端根本不需要知道有代理服务器的存在,它改变你的request fields(报文),并会传送真实IP,多用于路由器的NAT转发中。

为什么要用到透明代理?

因为这样能够让我的机器“身处”在内网中,也能让我的机器在“世界上的任何角落里”。

大家都知道,在Linux下常规的内网渗透需要使用一些如:proxychains的工具实现指定的进程访问内网的资源,相当于给程序套了一层代理。

它的实现原理如下:

ProxyChains is a UNIX program, that hooks network-related libc functions in dynamically linked programs via a preloaded DLL and redirects the connections through SOCKS4a/5 or HTTP proxies.

它的缺点却是每个命令必须要在前面加上proxychains,这样Bash shell有时候可能不会正常工作给我们进行参数提示。

我要做的就是使用iptables实现透明代理,让我的机器所有与目标地址相关的流量都导入socks5代理端口。

题外话一,关闭proxychains的输出信息可以将/etc/proxychains.conf文件中的quiet_mode前面的#去除。

 
题外话二,设置metasploit全局代理的方法:
 

可以将metasploit全局变量proxies的值进行设置来使得后续所有的流量都经过代理发出,这样能够达到内网穿透的效果。

图中演示了2层代理的设置

0x02 Linux下的iptables防火墙

iptables是一个用户空间实用程序,它允许系统管理员配置Linux内核防火墙的IP数据包过滤器规则,这些规则实现为不同的Netfilter模块。筛选器组织在不同的表中,这些表包含有关如何处理网络流量数据包的规则链。当前,不同的内核模块和程序用于不同的协议。iptables适用于IPv4,ip6tables适用于IPv6,arptables适用于ARP,而ebtables适用于以太网帧。

学习iptables有一点门槛,需要对表、规则链、动作等关系有一定的了解,这里不继续铺垫,可以自行搜索关于iptables的文章。

流量导入Socks代理

通过将规则插入到NAT表的PREROUTING链中,可以轻松地重定向传入流量。

例如:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

所有访问eth0网卡80端口的流量,都会被重定向到8080端口。

它不同于端口转发,REDIRECT--dport端口并不会被iptables进行监听。

0x03 实现简单的透明代理

redsocks是一个能够重定向socks代理的一款开源软件,它允许我们在系统上监听一个端口,与远程socks端口进行转换,并且支持socks5认证,这一点非常赞。后来发现还有新的redsocks一些还在维护,但旧版已经足够满足我的需要了,就没有下载。

redsocks安装

安装必备库:

  • ArchLinux : yaourt -S --noconfirm redsocks-git
  • Debian : apt install gcc libevent-dev
  • CentOS : yum install libevent-devel git gcc

编译代码:

git clone https://github.com/darkk/redsocks
cd redsocks
make
  1. 安装完毕后,当前目录会生成redsocks二进制可执行文件,把它拷贝到环境变量目录下即可,例如:/usr/bin/redsocks

  2. 将配置文件redsocks.conf拷贝至/etc/redsocks.conf

配置redsocks代理服务器

/etc/redsocks.conf第61行-62行是设置Socks5服务器IP和端口的:

// `ip' and `port' are IP and tcp-port of proxy-server
// You can also use hostname instead of IP, only one (random)
// address of multihomed host will be used.
ip=***;
port=***;

配置redsocks启动身份:

为了避免启用端口流量重定向后数据发生回环问题,需要用iptables根据UID进行过滤redsocks的出口流量。

添加redsocks组与redsocks用户:

groupadd redsocks
useradd -g redsocks redsocks

/etc/redsocks.conf的启动用户名和用户组进行更改:

user = redsocks;
group = redsocks;

对应的防火墙规则:

iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner redsocks  -j REDSOCKS

这么做是为了把除了redsocks用户产生的流量全部经过REDSOCKS链。

0x04 打点模式-配置代理链

创建自定义规则链

iptables -t nat -N REDSOCKS 
# 建立REDSOCKS链
iptables -t nat -A PREROUTING -p tcp -j REDSOCKS 
# 将所有的TCP流量经过REDSOCKS链
iptables -t nat -A REDSOCKS -d <SOCKS_API_SERVER> -j RETURN 
# 放行获取Socks代理的API服务器
iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN 
# 放行内网地址
iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN 
# 放行内网地址
iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN 
# 放行内网地址
iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN 
# 放行内网地址
iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN 
# 放行内网地址
iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-port 31338 
# 将所有的TCP流量在经过REDSOCKS链后,全部重定向到31338端口。
iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner redsocks  -j REDSOCKS
# 将准备流出的流量除了redsocks产生的以外,全部经过REDSOCKS链

建立一个独立的链是为了方便的清空和新建,并且还不会污染内置链的规则。

31338是redsocks的默认端口。

启动redsocks

sudo /usr/bin/redsocks -c /etc/redsocks.conf

启动redsocks后,进程的所属者会被自动更改为redsocks。

这时访问公网查看出口IP,会变成Socks5代理服务器的出口IP,实现打点模式的透明代理。

0x05 内网模式-配置代理链

内网与打点模式不同,主要是实现指定IP地址范围的代理,打点是“放哪些”,内网是“要哪些”。

iptables -t nat -N REDSOCKS
iptables -t nat -F REDSOCKS # 清空

iptables -t nat -A PREROUTING -p tcp -j REDSOCKS
iptables -t nat -A REDSOCKS -p tcp -d 10.0.0.0/8 -j REDIRECT --to-port 31338
iptables -t nat -A REDSOCKS -p tcp -d 172.0.0.0/8 -j REDIRECT --to-port 31338
iptables -t nat -A REDSOCKS -p tcp -d 192.168.0.0/16 -j REDIRECT --to-port 31338
iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner $redsocks_user  -j REDSOCKS

以上防火墙规则是将以下目的地址的流量全部导入redsoks:

  • 10.0.0.0/8
  • 172.0.0.0/8
  • 192.168.0.0/16

如果要添加专网的地址,可以手动添加:

iptables -t nat -A REDSOCKS -p tcp -d XXX.XXX.XX.XX/XX -j REDIRECT --to-port 31338

启用以上防火墙规则后,我可以不需要使用proxychains,直接可以用nmap探测端口,自定义的工具也能够像在内网一样工作,本机开的虚拟机切换到NAT模式也能够“身处”内网。

0x06 自动化实现

#!/bin/bash
redsocks_bin_path="/usr/bin/redsocks"
redsocks_config_file_path="/etc/redsocks.conf"
socks_api_url='*****'
shell_log_path="/tmp/socks-switch.log"
# ssh port
ssh_port="22"
redsocks_user="redsocks"

socks_loging(){
    current_time=$(date +"%Y-%m-%d %H:%M:%S");
    echo "[*] "$current_time ": " $1 >> $shell_log_path
    echo "[*] "$current_time ": " $1
}


change_socks(){
    local socks_ip=$1;
    local socks_port=$2;
    socks_loging "Change Socks: $1, Port: $2";
    # 61行是Socks IP
    sed -i '61d' $redsocks_config_file_path
    sed -i "61i\        ip=$socks_ip;"  $redsocks_config_file_path

    # 62行是Socks Port
    sed -i '62d' $redsocks_config_file_path
    sed -i "62i\        port=$socks_port;"  $redsocks_config_file_path
    pkill redsocks
    socks_loging "Run redsocks...."
    $redsocks_bin_path -c $redsocks_config_file_path
}

start_pentest(){
    uninstall_iptables
    iptables -t nat -N REDSOCKS
    iptables -t nat -F REDSOCKS # 清空
    
    iptables -t nat -A PREROUTING -p tcp -j REDSOCKS
    iptables -t nat -A REDSOCKS -p tcp -d 10.0.0.0/8 -j REDIRECT --to-port 31338
    iptables -t nat -A REDSOCKS -p tcp -d 172.0.0.0/8 -j REDIRECT --to-port 31338
    iptables -t nat -A REDSOCKS -p tcp -d 192.168.0.0/16 -j REDIRECT --to-port 31338
    
    unset_iptables
    set_iptables
    local socks_ip=$1;
    local socks_port=$2;
    change_socks $socks_ip $socks_port
    socks_loging "Change Socks: $1, Port: $2";

}

install_iptables(){
    iptables -t nat -F OUTPUT
    iptables -t nat -F PREROUTING
    # 如果没有就新建一个
    local is_redsocks=`iptables -t nat -nL --line-number |grep REDSOCKS`
    if [ -z "$is_redsocks" ]; then
            iptables -t nat -N REDSOCKS
    fi
    iptables -t nat -F REDSOCKS # 清空
    iptables -t nat -A PREROUTING -p tcp -j REDSOCKS
    iptables -t nat -A REDSOCKS -p tcp --dport $ssh_port -j RETURN
    iptables -t nat -A REDSOCKS -d <SOCKS API Server> -j RETURN
    iptables -t nat -A REDSOCKS -d 10.0.0.0/8 -j RETURN
    iptables -t nat -A REDSOCKS -d 127.0.0.0/8 -j RETURN
    iptables -t nat -A REDSOCKS -d 169.254.0.0/16 -j RETURN
    iptables -t nat -A REDSOCKS -d 172.16.0.0/12 -j RETURN
    iptables -t nat -A REDSOCKS -d 192.168.0.0/16 -j RETURN
    iptables -t nat -A REDSOCKS -p tcp -j REDIRECT --to-port 31338
    socks_loging "Install Success!"
}


uninstall_iptables(){
    iptables -t nat -F OUTPUT
    iptables -t nat -F PREROUTING
    socks_loging "Uninstall iptables  ..."
    is_redsocks=`iptables -t nat -nvL REDSOCKS |wc -l`
    if [ "$is_redsocks"!="0" ]; then
            iptables -t nat -F REDSOCKS
            iptables -t nat -X REDSOCKS
    fi
}


set_iptables(){
    iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner $redsocks_user  -j REDSOCKS
}

unset_iptables(){
    ids=`iptables -t nat -nL OUTPUT --line-number | grep REDSOCKS | awk '{print $1}'`
    if [ -z "$ids" ]; then
        socks_loging "No Set Iptables ..."
        return
    fi
    id_array=(${ids//\\n/ })
    socks_loging "REDSOCKS OUTPUT Chian ID : $id_array"
    for id in ${id_array[@]}
    do
        id=`echo $id|egrep -o "[0-9]{1,4}"`
        if [ $id!="" ]; then
            iptables -t nat -D OUTPUT $id
        fi
    done
}




if [ -z "$1" ]; then
    echo "[*] Usage : $0 <start | stop | clean | install | uninstall | change IP PORT | pentest IP PORT>
        $0 start : 启动redsocks,自动设置iptables
        $0 stop : 停止redsocks,自动清空iptables
        $0 clean : 清空iptables所有规则
        $0 install : 安装iptables规则
        $0 uninstall : 卸载iptables规则
        $0 change : 改变Socks的IP和端口
        $0 pentest : 开始内网渗透,传入Socks的IP和端口
    "
    exit 0
fi



if [ "$1" = "install" ]; then
    install_iptables
    exit 0
fi

if [ "$1" = "pentest" ]; then
    start_pentest $2 $3
    exit 0

使用方式:

  • 打点模式简单使用(每执行一次,向API拉取新的代理):

2020-11-13-22-04-21

sudo ./socks-switch.sh install
sudo ./socks-switch.sh start
  • 切换至内网模式使用:

2020-11-13-22-00-56

sudo ./socks-switch.sh uninstall
sudo ./socks-switch.sh pentest <Socks IP> <Socks Port>
  • 手动指定Socks的IP和端口(打点模式与内网模式兼容):
sudo ./socks-switch.sh change <Socks IP> <Socks Port>

0x06 树莓派实现6小时切换一次出口的WiFi

这个是我在熟悉透明代理后产生的想法,适合“团队作战”,尤其是Web渗透这块最消耗IP了,实验室的小伙伴大多也都是笔记本,因此想出了用树莓派实现6小时切换一次出口的WiFi,当然了,也能把穿透内网的Socks变成一个WiFi :)

更改redsocks监听地址

如果是多网卡需要把redsocks配置文件/etc/redsocks.conf的监听IP地址改为:0.0.0.0,不然在wlan0的流量转向eth0的时候,会找不到31338端口。

local_ip = 0.0.0.0;
local_port = 31338;

安装创建AP的工具

sudo apt-get install util-linux procps hostapd iproute2 iw haveged dnsmasq
sudo git clone https://github.com/oblique/create_ap
cd create_ap
sudo make install

创建WiFi:/usr/bin/create_ap -w 2 wlan0 eth0 <WiFi Name> <WiFi Pass>

-w 为启用WPA2

编写AP服务脚本

/usr/lib/systemd/system/创建wifi.service

[Unit]
Description=Create AP Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/create_ap -w 2 wlan0 eth0 <WiFi Name> <WiFi Pass> 
KillSignal=SIGINT
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

编写计划任务脚本

random-wifi.sh:

#!/bin/bash
cd /home/pi/socks-switch
systemctl stop wifi # 先停止WiFi
./socks-switch.sh clean # 清空规则
./socks-switch.sh install # 安装规则
./socks-switch.sh start # 启用规则
systemctl start wifi # 创建WiFi

sudo crontab -e进入root用户的计划任务编写:

* */6 * * * /home/pi/socks-switch/random-wifi.sh # 每隔六小时重置一次,并获取新的出口代理

待完善的缺点

比如在切换新的出口时,WiFi是关闭的,现在的客户端一般都是会自动寻找下一个WiFi自动连接的,如果工具正在扫描会导致真实出口IP被发现。

思路:在切换WiFi前,将wlan0网卡的流量全部DROP,这样WiFi也不需要重启。

0x07 总结

通过动手实践,解决了工作痛点,让技术的价值发挥出来更能收获成就感。

期间还实现了科学上网的透明代理,但是与工作无关,网络上已经大把帖子了,收获颇多,关于渗透还需要研究更多,看问题的角度也要多变.

from https://payloads.online/archivers/2020-11-13/1/ 

-----------------------------------------------------------------------------------------------------------------------------

Web正向代理的思考

本篇文章,主要是记录工作中遇到一个在不出网的机器上,构建正向代理尝试出的一个其他办法。

0x01 背景假设

获取Webshell后,但是机器不出网(DNS、TCP、UDP)等常规端口都进行了尝试。

不出网的解释:内部的Webshell服务器无法连接互联网。

尝试过的方案有:


那么,一般我们会尝试:

这种类型的工具往往都有一个特性:通过脚本帮助我们把HTTP协议转换成Socks,由于HTTP协议无状态,因此需要发送大量数据包。

但是这个场景以上方案都使用起来都不能给出一个很好的效果,因为网络延迟、系统卡顿等等问题,想要传递工具到服务器上变得困难。

0x02 尝试理解目标网络架构

这里我画了一个简单的架构图:

类似这种场景在企业种非常的常见,网络管理员应业务部门的要求,利用NAT端口映射的技术可以直接将DMZ区域的某台机器上的某个端口对外网开放。

这里我使用Docker搭建了一个简单的靶场:

对应的NAT 端口转发情况:

iptables -t nat -A PREROUTING -p tcp -d 172.17.0.2 --dport 8080 -j DNAT --to-destination 192.168.1.128:8080
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.128 --dport 8080 -j SNAT --to-source 192.168.1.129
iptables -t nat -A PREROUTING -p tcp -d 172.17.0.2 --dport 8080 -j DNAT --to-destination 192.168.1.125:8080
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.125 --dport 8080 -j SNAT --to-source 192.168.1.129
iptables -t nat -A PREROUTING -p tcp -d 172.17.0.2 --dport 8081 -j DNAT --to-destination 192.168.1.128:8081
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.128 --dport 8081 -j SNAT --to-source 192.168.1.129
iptables-save

如果攻击者访问172.17.0.2的8080端口,流量将会被转发到192.168.1.128上,那么设想一下,NAT规则在生产的场景中会不会产生规则滥用的情况?

我猜想有以下几种情况:

  1. 业务下线了,NAT规则没有来得及删除
  2. 某个规则指向的端口服务暂时停止了
  3. 网络管理员觉得流程麻烦,遂开放了一段端口,如:8080-8090

0x03 利用NAT规则实现内网漫游

理清楚网络结构后,可以开始寻找有用的NAT规则了,我总结了两个办法:

  1. 结束正在占用NAT端口的程序
  2. 寻找未被使用的NAT端口

如何判断目标正在使用这个NAT端口,我的办法是使用Nmap进行扫描。一些NAT规则大多数会采用相同端口映射的关系,比如:8080:8080。

2020-11-01-22-31-26

2020-11-01-22-32-56

通过信息收集,了解到内网IP端口是192.168.1.128。

映射关系:

这个时候扫描172.17.0.2查看开放状态:

2020-11-01-22-36-44

我为了模拟真实环境,还映射了其他端口:8081。

2020-11-01-22-38-21

真实场景下,如果是非映射端口,将会是filtered,这种的情况是数据包到达防火墙后就被DROP掉了。

2020-11-01-22-42-16

iptables -t nat -A PREROUTING -p tcp -d 172.17.0.2 --dport 8080 -j DNAT --to-destination 192.168.1.128:8080
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.128 --dport 8080 -j SNAT --to-source 192.168.1.129

iptables -t nat -A PREROUTING -p tcp -d 172.17.0.2 --dport 8080 -j DNAT --to-destination 192.168.1.125:8080
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.125 --dport 8080 -j SNAT --to-source 192.168.1.129

iptables -t nat -A PREROUTING -p tcp -d 172.17.0.2 --dport 8081 -j DNAT --to-destination 192.168.1.128:8081
iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.128 --dport 8081 -j SNAT --to-source 192.168.1.129
iptables -P INPUT DROP
iptables-save

2020-11-01-23-10-02

倘若在8081 closed情况下,我们可以直接nc监听起来进行测试:

2020-11-01-23-12-54

这个时候,内网的服务器监听了8081端口,成功的利用NAT规则使得我们可以直接正向连接到NC。

2020-11-01-23-14-06

如何利用?

我们可以将nc这个程序换成别的,比如:socks5的服务端程序,监听8081端口,如此一来就能够直接连接 socks5:172.17.0.2:8081作为内网的入口。

0x04 总结

本文主要在防火墙规则上做了一些思考,并且进行了环境的模拟搭建,与实战环境相同,因此得出以下结论:

  1. 通过分析NAT规则,能够构建一个稳定代理。
  2. 测试NAT只能使用端口监听工具,然后在外网进行连接测试。
  3. Filtered是DROP,ACCEPT是Open,未被使用Closed也是能够ACCEPT。
  4. 通过这种方案可以提升效率。
  5. 在非不得已的情况下,最好不要结束占用NAT端口的进程。

from https://payloads.online/archivers/2020-11-01/1/ 

---------------------------------------------------------------------------------

透明代理切换脚本,仅支持 Linux.

透明代理脚本

参考链接:https://payloads.online/archivers/2020-11-13/1/

一个支持打点切换出口IP和内网渗透透明代理的脚本。

优点:

  1. 防溯源
  2. 支持无限切换IP
  3. 能够应用于路由器

缺点:

  1. 依赖redsocks

使用规范

Packages

子命令

[*] Usage : ./socks-switch.sh <start | stop | clean | install | uninstall | change IP PORT | pentest IP PORT>
    ./socks-switch.sh start : 启动redsocks,自动设置iptables
    ./socks-switch.sh stop : 停止redsocks,自动清空iptables
    ./socks-switch.sh clean : 清空iptables所有规则
    ./socks-switch.sh install : 安装iptables规则
    ./socks-switch.sh uninstall : 卸载iptables规则
    ./socks-switch.sh change : 改变Socks的IP和端口
    ./socks-switch.sh pentest : 开始内网渗透,传入Socks的IP和端口

打点模式简单使用:

sudo ./socks-switch.sh install
sudo ./socks-switch.sh start

切换至内网模式使用:

sudo ./socks-switch.sh uninstall
sudo ./socks-switch.sh pentest 1.1.1.1 5566

手动指定Socks的IP和端口:

sudo ./socks-switch.sh change 2.2.2.2 7788

配置项

#!/bin/bash
redsocks_bin_path="/usr/bin/redsocks" # redsocks二进制文件路径
redsocks_config_file_path="/etc/redsocks.conf" # redsocks配置文件路径
socks_api_url='http://http.tiqu.alicdns.com/getip3?num=1&type=1&pro=&city=0&yys=0&port=2&time=2&ts=0&ys=0&cs=0&lb=1&sb=0&pb=4&mr=1&regions=&gm=4' # api接口,返回socks5:IP:端口
shell_log_path="/tmp/root-test-socks.log" # 日志文件
from https://github.com/Rvn0xsy/socks-switch 

 


No comments:

Post a Comment