天天看点

【Python安全攻防基础篇:模块和对象】女朋友完全不看源码,说是看不懂。我赶紧肝出一篇,还带她读了读dirmap的源码!

终于又到了一周一度的整理博客的时间了,博主平时课余时间看书,周末统一整理,坚持周更真是爱了爱了🐶~

今天要说的是python面向对象这一部分的内容,今天这是基础篇的第二篇,也是最后一篇。

说来基础篇还真是少呢,第一篇说了一下函数部分比较难理解的

闭包和装饰器

,今天说一下

模块、包、对象、类

这部分。当然中途还有很多东西也很重要啊。

  1. 基础语法:尤其是字符串、列表和字典的操作,以及循环、判断的使用
  2. 文件处理:主要是文件的读写
  3. 异常处理:因为我们前期写的顶多就是些小脚本,辅助渗透用,没必要了解太多异常处理

这三部分,有一点编程基础的,网上找篇博客随便看看就能懂,不会的等遇到了直接百度,也比我现在写篇博客节省时间,所以就没写,但是我肯定都看了,哈哈。

因为平时渗透过程中,我们经常会用到别人写的脚本,或者使用渗透测试框架时也需要自己动手写POC/EXP之类的,甚至以后可能会自己写一些python脚本,所以python的函数、对象等等这部分内容是非常重要的。

我希望今天这部分结束后,我们至少可以做到能读懂别人的脚本,于是我就去随便下了一个

dirmap

,等下在文章最后,大家和我一起读一下源码!

【Python安全攻防基础篇:模块和对象】女朋友完全不看源码,说是看不懂。我赶紧肝出一篇,还带她读了读dirmap的源码!

那废话不多说,开始今天的内容,包-> 模块-> 类-> 对象-> 方法,咦?为什么加个箭头呢?因为它们的关系确实如此:

  1. 模块:就是

    .py

    文件
  2. 包:就是一群

    .py

    文件所在的目录
  3. 类:狗就是一个类
  4. 对象:对象就是类的实例化,比如哈士奇、金毛、阿拉斯加
  5. 方法:实现具体逻辑的代码
【Python安全攻防基础篇:模块和对象】女朋友完全不看源码,说是看不懂。我赶紧肝出一篇,还带她读了读dirmap的源码!

如果一个目录下是一堆python文件,且其中有一个

__init__.py

的话,那这个目录就是包,且目录名称就是包名。

我们可以使用import导入包/模块:

# 导入包
import [包名1],[包名2]

# 导入模块
from [包名] import [模块名1],[模块名2]
           

模块

一个python文件就是一个模块,且文件名就是模块名。

我们可以使用import导入模块/函数

# 导入模块
import [模块名1],[模块名2]

# 导入函数
from [模块名] import [函数名1],[函数名2]
           

从类开始,就是代码层面的了,类具体定义如果不知道的建议学一门面向对象的语言,这玩意解释起来太多了,网上文章也太多了,我不想写。

放一段最基本的python代码,先抛开面向对象编程的思想:声明一个类,里边有个方法,用来打印一句话

# 先声明一个Test类
class Test():
    def print_test(self, perm):
        print(perm)

# 实例化一个test对象
test = Test()

# 调用print_test方法
test.print_test('白帽子续命指南')
           

执行结果

白帽子续命指南
           

对象

对象就是对类的实例化,具体语法格式如下:

# 对象名 = 类名()
test = Test()
           

方法

就是实现具体功能的代码

在类里边写它的主要逻辑,注意写的时候要加上self参数,这个必须加(除了类方法和静态方法,这两个不讨论)。语法格式为:

class Test():
    def print_test(self, perm):
        print(perm)
           

创建一个实例对象之后,可以调用,调用格式:

# 对象名.方法名(参数)
test.ptint_test('白帽子续命指南')
           

除此之外,方法也分很多种,比如带下划线的,还有类方法、静态方法等等,这里不细说,遇到了再去百度。简单说三种:

  1. 前边有两个下划线的:私有的,只有类自己可以访问,连子类都不能访问
  2. 前边有一个下划线的:保护变量,只有类和子类能访问,言外之意就是不能import
  3. 左右各两个下划线的:系统的

继承

继承就是子类和父类那一块的,语法格式为:

# 父类
class Cat():
    pass
class Animal():
    pass

# 子类
class Kitty(Cat, Animal):
    pass
           

这样,Kitty这个类就继承了Cat和Animal这两个类的所有属性和方法(属性就是变量)。

重写

重写就是继承一个父类后,对父类中某个方法重新写一下。

语法上保证方法名和参数列表都一样,就OK了:

# 父类
class Cat():
    def print_cat(self):
        print('喵~')
class Animal():
    def print_live(self):
        print('活的')

# 子类
class Kitty(Cat, Animal):
    def print_live(self):
        print('死了')
        
test = Kitty()
test.print_live()
           

执行结果

死了
           

读源码

项目地址:https://gitee.com/c0ny10/dirmap

首先,下载好dirmap的源码后,进入到dirmap/中,看看都有什么。

.
├── LICENSE
├── README.md
├── README_EN.md
├── data
│   ├── crawl_mode_suffix.txt
│   ├── dict_mode_dict.txt
│   ├── dictmult
│   │   ├── BAK.min.txt
│   │   ├── BAK.txt
│   │   └── LEAKS.txt
│   ├── fuzz_mode_dir.txt
│   ├── fuzz_mode_ext.txt
│   ├── fuzzmult
│   │   ├── fuzz_mode_dir.txt
│   │   └── fuzz_mode_ext.txt
│   └── user_agents.txt
├── dirmap.conf
├── dirmap.py
├── doc
│   ├── blast_mode.png
│   ├── crawl_mode.png
│   ├── dict_mode.png
│   ├── dirmap.png
│   ├── donate.jpg
│   ├── fuzz_mode.png
│   └── recursive_scan.png
├── lib	# 想这个lib/下面有__init__.py,说明这个就是一个包啊
│   ├── __init__.py
│   ├── controller	# 这也是包
│   │   ├── __init__.py
│   │   ├── bruter.py	# 这就是所谓的模块
│   │   └── engine.py
│   ├── core
│   │   ├── __init__.py
│   │   ├── common.py
│   │   ├── data.py
│   │   ├── datatype.py
│   │   ├── enums.py
│   │   ├── option.py
│   │   └── setting.py
│   ├── parse
│   │   ├── __init__.py
│   │   └── cmdline.py
│   ├── plugins
│   │   ├── __init__.py
│   │   └── inspector.py
│   └── utils
│       ├── __init__.py
│       ├── config.py
│       └── console.py
├── requirement.txt
└── thirdlib
    ├── IPy
    │   ├── AUTHORS
    │   ├── COPYING
    │   ├── ChangeLog
    │   ├── IPy.py
    │   ├── MANIFEST.in
    │   ├── Makefile
    │   ├── README
    │   ├── example
    │   │   ├── confbuilder
    │   │   └── confbuilder.py
    │   ├── setup.py
    │   ├── test
    │   │   ├── test.rst
    │   │   ├── test_IPy.py
    │   │   └── test_fuzz.py
    │   └── test_doc.py
    └── colorama
        ├── __init__.py
        ├── ansi.py
        ├── ansitowin32.py
        ├── initialise.py
        ├── win32.py
        └── winterm.py

15 directories, 61 files

           

看到有一个

dirmap.py

的文件,查看这个文件内容。

把代码复制过来,然后我给加上中文注释(我的注释,为了区分,前边用两个#):

[email protected]-Air dirmap % vim dirmap.py 

## 以"#!"开头的,是用来指定python解释器的,这里是python3
## 如果不指定你就不能用"./dirmap.py"来执行了
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

## 这里是作者信息,没什么好说的
'''
@Author: xxlin
@LastEditors: xxlin
@Date: 2019-04-10 13:27:59
@LastEditTime: 2019-05-01 17:57:11
'''

## 导入了两个模块
import os
import sys

## 这里的gevent是第三方库
## 从gevent导入了一个monkey模块并调用了patch_all()方法
from gevent import monkey
monkey.patch_all()

## 这里用了好几个点来导入,明显是文件路径
## 我们知道python默认从当前目录开始搜,所以这个lib应该在dirmap.py的同级目录
from lib.controller.engine import run
from lib.core.common import banner, outputscreen, setPaths
from lib.core.data import cmdLineOptions, conf, paths
from lib.core.option import initOptions
from lib.parse.cmdline import cmdLineParser

## 这个main函数就是用来调用刚刚导入进来的方法
def main():
    """
    main fuction of dirmap 
    """

    # anyway output thr banner information
    banner() 

    # set paths of project 
    paths.ROOT_PATH = os.getcwd() 
    setPaths()
    
    # received command >> cmdLineOptions
    cmdLineOptions.update(cmdLineParser().__dict__)
    
    # loader script,target,working way(threads? gevent?),output_file from cmdLineOptions
    # and send it to conf
    initOptions(cmdLineOptions) 

    # run!
    run()

## 然后最后执行一下main函数
if __name__ == "__main__":
    main()

           

那这篇文章就是熟悉一下python代码,至少我们现在应该能做到两点:

  1. 能看懂目录结构
  2. 能看懂python代码

至于里边代码怎么写,怎么用渗透框架,怎么写POC,怎么写EXP,怎么写脚本,那是我们后边的内容,大家不要着急~