通过解密f5的cookie信息获得服务器真实内网IP(转)

2017-07-27 09:18:08 15 13735 2


渗透测试过程中,经常会遇到目标服务器使用F5 LTM做负载均衡。 如果能获取到目标服务器的真实IP地址,会给后续渗透带来一定便利。
本文既是最近渗透遇到的一点点经验分享:
F5修改cookie机制
F5 LTM做负载均衡时,有多种机制实现会话保持。 其中用到很多的一种是通过修改cookie来实现的。具体说来,F5在获取到客户端第一次请求时,会使用set cookie头,给客户端埋入一个特定的cookie。
比如: Set-Cookie: BIGipServerpool_8.29_8030=487098378.24095.0000
后续再接到客户端请求时,F5会查看cookie里面的字段,判断应该交给后续哪台服务器。
作为传统大厂,F5当然不会傻到直接把服务器IP address写入到cookie里面。 F5很巧妙的把server的真实IP address做了两次编码,然后再插入cookie。
所以,只要依据解码流畅,解开487098378.24095.0000的内容,就拿到了server的真实IP address。
解码思路
首先,把第一小节的十进制数取出来,也即,487098378 第二,将其转为十六进制数1d08880a 第三,从后至前,以此取四位数出来,也即,0a;88;08;1d; 第四,依次把他们转为十进制数:10;136;8;29 最后,得到真实内网IP:10.136.8.29
总结
严格意义上说,只有内网的私有IP,对正面突破目标防线的帮助并不明显。 但是,当需要做内网渗透和漫游的时候,这一点信息还是有价值的。 再不济,写report的时候,如果实在没的可写的时候,还可以拿这点作为一个issue作为丰富report的素材。
附上解密的脚本:
python脚本:
BigIPF5-Decoder.py:
#!/usr/bin/env python
# example string: 110536896.20480.0000
import struct
import sys
if len(sys.argv) != 2:
print "Usage: %s encoded_string" % sys.argv[0]
exit(1)
encoded_string = sys.argv[1]
print "\n[*] String to decode: %s\n" % encoded_string
(host, port, end) = encoded_string.split('.')
(a, b, c, d) = [ord(i) for i in struct.pack("<I", int(host))]
(e) = [ord(e) for e in struct.pack("<H", int(port))]
port = "0x%02X%02X" % (e[0],e[1])


dusty@HackBox:~$ python BigIPF5-Decoder.py 185903296.21520.0000
String to decode: 185903296.21520.0000
Decoded Host and Port: 192.168.20.11:4180
perl解密脚本,f5_decode.pl:
#!/usr/bin/perl
use strict;
use warnings;
my ($ip,$port) = split(‘.’,$ARGV[0]);
#Convert to IP to hex
my $ip_hex = sprintf(“%x”,$ip);
#Prepend extra 0 if hex value is only 7 char
$ip_hex = “0”.”$ip_hex” if (length $ip_hex ==7);
#Decode hex to IP
my $d_ip = join (‘.’,map {hex $_} reverse ($ip_hex =~ m/../g));
#Decode hex to port
my $d_port = hex join(“”,reverse( sprintf(“%x”,$port) =~ m/../g) );
print “The persistence cookie decoded: $d_ip:$d_portn”;



Usage:  ./f5_decode.pl 335653056.20480.0000
其他tips:
1.另外有时遇到传shell上去之后有负载,其实可以通过设置cookie来只访问内网某台负载服务器,这就不用传多个文件了,特别适合弄于regeorg遇到负载的时候。
2.SSRF配合攻击内网的同段IP
3.通过设置COOKIES来指定负载会话
4.基于session的会话保持,这种也是现在比较常用的,weblogic的session复制机制,想apache这种可以通过插件来实现,不过在现在的分布式环境中都是用数据库或者内存数据库(redis、mongo、Memcached等),早期有一部分是用文件系统来实现,性能原因被抛弃了
5.还有一种就是基于四层的负载,基于IP+端口,这个现在貌似没人用,优点是性能好
参考连接:
https://penturalabs.wordpress.com/2011/03/29/how-to-decode-big-ip-f5-persistence-cookie-values/
http://packetpushers.net/encrypted-cookie-persistence/
https://threathunter.org/topic/5940c85d9c58e020408a79fe

关于作者

backlion31篇文章606篇回复

低调求技术提升!

评论15次

要评论?请先  登录  或  注册
  • 15楼
    2017-7-29 09:09

    做VPN设备能获取IP吗

  • 14楼
    2017-7-28 11:10
    s3cj0y

    #!/usr/bin/perluse strict;use warnings;if ( $#ARGV < 0 ) { print "USAGE: bigipcookie.pl <node IP:port | cookie value>\n"; exit 1;}if ($ARGV =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):(\d+)$/) { my $ipEnc = $1 + ($2*256) + ($3 * (256**2)) + ($4 * (256**3)); my $portEnc = hex(join "", reverse ((sprintf "%04x", $5) =~ /../g)); print "$ipEnc.$portEnc.0000\n";}elsif ($ARGV =~ m/^(\d+)\.(\d+)\.0000$/){ # decode a cookie value my $ipEnc = $1; my $portEnc = $2; my $ip = join ".", map {hex} reverse ((sprintf "%08x", split /\./, $ipEnc) =~ /../g); my $portDec = hex(join "", reverse ((sprintf "%04x", $portEnc) =~ /../g)); print "$ip:$portDec\n";}else { print "USAGE: bigipcookie.pl <node IP:port | cookie value>\n"; exit 1;}再送你个,可以加密ip为f5的加密串,也可以解密cookie值为ip的小工具,来源github 某处,忘了

    1
    CF_HB

    https://github.com/jantman/misc-scripts

    2

    啊,对,就这个

  • 13楼
    2017-7-27 21:57

    python脚本的缩进没了

  • 12楼
    2017-7-27 17:55
    s3cj0y

    #!/usr/bin/perluse strict;use warnings;if ( $#ARGV < 0 ) { print "USAGE: bigipcookie.pl <node IP:port | cookie value>\n"; exit 1;}if ($ARGV =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):(\d+)$/) { my $ipEnc = $1 + ($2*256) + ($3 * (256**2)) + ($4 * (256**3)); my $portEnc = hex(join "", reverse ((sprintf "%04x", $5) =~ /../g)); print "$ipEnc.$portEnc.0000\n";}elsif ($ARGV =~ m/^(\d+)\.(\d+)\.0000$/){ # decode a cookie value my $ipEnc = $1; my $portEnc = $2; my $ip = join ".", map {hex} reverse ((sprintf "%08x", split /\./, $ipEnc) =~ /../g); my $portDec = hex(join "", reverse ((sprintf "%04x", $portEnc) =~ /../g)); print "$ip:$portDec\n";}else { print "USAGE: bigipcookie.pl <node IP:port | cookie value>\n"; exit 1;}再送你个,可以加密ip为f5的加密串,也可以解密cookie值为ip的小工具,来源github 某处,忘了

    1
  • 11楼
    2017-7-27 15:57

    开车的都是大神,能开车也能搞技术

  • 10楼
    2017-7-27 15:55

    #!/usr/bin/perl use strict; use warnings;  if ( $#ARGV < 0 ) {     print "USAGE: bigipcookie.pl <node IP:port | cookie value>\n";     exit 1; }  if ($ARGV[0] =~ m/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3}):(\d+)$/) {     my $ipEnc = $1 + ($2*256) + ($3 * (256**2)) + ($4 * (256**3));     my $portEnc = hex(join "", reverse ((sprintf "%04x", $5) =~ /../g));     print "$ipEnc.$portEnc.0000\n"; } elsif ($ARGV[0] =~ m/^(\d+)\.(\d+)\.0000$/){     # decode a cookie value     my $ipEnc = $1;     my $portEnc = $2;     my $ip = join ".", map {hex} reverse ((sprintf "%08x", split /\./, $ipEnc) =~ /../g);     my $portDec = hex(join "", reverse ((sprintf "%04x", $portEnc) =~ /../g));     print "$ip:$portDec\n"; } else {     print "USAGE: bigipcookie.pl <node IP:port | cookie value>\n";     exit 1; }
    再送你个,可以加密ip为f5的加密串,也可以解密cookie值为ip的小工具,来源github 某处,忘了

  • 9楼
    2017-7-27 15:21

    小奥表示不服

  • 8楼
    2017-7-27 14:18

    看起来不错,LZ有没有测试一下

  • 7楼
    2017-7-27 13:39

    只能获取真实内网IP 没什么用

  • 6楼
    2017-7-27 13:25
    CF_HB

    use auxiliary/gather/f5_bigip_cookie_disclosure

    1

    表哥好

  • 5楼
    2017-7-27 13:09

    感觉没什么用啊

  • 4楼
    2017-7-27 11:12

    use auxiliary/gather/f5_bigip_cookie_disclosure

  • 3楼
    2017-7-27 10:17
    Acat123

    msf有这个利用模块的

    1

    表哥。求连接。

  • 2楼
    2017-7-27 10:15

    msf有这个利用模块的

  • 1楼
    2017-7-27 09:24

    但是获取不了外网IP有点尴尬