Allow remote connection to this computer using WinAPI - winapi

I need to set Allow remote connections to this computer on, so I want to know If I can enable it by using WinAPI.
Does anyone know If this can be done with any function?

for this you need set next registry keys:
HKLM\System\CurrentControlSet\Control\Terminal Server\fDenyTSConnections = 0
HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\UserAuthentication = (IsDlgButtonChecked() == BST_CHECKED)
HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\SecurityLayer = 0 or 1 or 2
if radio-button not selected you need set only
HKLM\System\CurrentControlSet\Control\Terminal Server\fDenyTSConnections = 1
also you need enable "#FirewallAPI.dll,-28752" Firewall group by next code:
HRESULT EnableFirewallRule(PCWSTR cgroup, VARIANT_BOOL enable)
{
if (BSTR group = SysAllocString(cgroup))
{
INetFwPolicy2* pNetFwPolicy2;
HRESULT hr = CoCreateInstance(__uuidof(NetFwPolicy2), 0, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pNetFwPolicy2));
if (!FAILED(hr))
{
hr = pNetFwPolicy2->EnableRuleGroup(NET_FW_PROFILE2_ALL, group, enable);
pNetFwPolicy2->Release();
}
SysFreeString(group);
return hr;
}
else return E_OUTOFMEMORY;
}
EnableFirewallRule(L"#FirewallAPI.dll,-28752", VARIANT_TRUE);
yes, this not documented properly. however can found some info about this.
are radio button (Allow remote connections to this computer) selected depended only from fDenyTSConnections ( 0 or 1 (!= 0) ) - you can test it by changing value in regedit and reopen System Properties/Remote dialog
some proof on the MSND - Using Remote Desktop
A value of 0 for the fDenyTSConnections registry value means that
Remote Desktop is enabled on the system, while a value of 1 means that
Remote Desktop is disabled. If you later decide you want to disable
Remote Desktop on your Server Core installation, type cscript
%windir%\system32\scregedit.wsf /ar 1 at a command prompt.
UserAuthentication - [0 or 1 ] control Network Level Authentication checkbox (1 checked, 0 - unchecked) (again you can changing value in regedit and reopen System Properties/Remote dialog - or check/uncheck this this box and view in regedit)
In the Properties pane, click the box to the right of the
UserAuthentication setting and type 1 to require Network Level Authentication, as shown here.
SecurityLayer - [0 or 1 or 2] - look the Table 6-1 The SecurityLayer Setting Values
and the last for firewall (this is begin from vista)
In the Properties pane, type C:\Windows\system32\netsh advfirewall
-firewall set rule group="Remote Desktop" new enable=yes
so we need enable rule group="Remote Desktop"
now look at this technet.microsoft.com link
For example, to enable Remote Desktop, use the following:
<Group>#FirewallAPI.dll,-28752</Group>
how is Enabling a Group exist example on MSDN. my code snipet bassed on this

Related

Create new session using _IECreate()

I have two AutoIt scripts. Both contain Global $oIE = _IECreate($myUrl, 1). They create two IE windows for the same URL.
In IE, when selecting "new session" from "file" menu, each window gets its own session. But using two different script files at the same time, both windows login to the same account. How can I open every IE window with a new session?
Sessions relate to each unique iexplore.exe process. Start new instance of iexplore.exe per required session (untested, no error checking) :
#include <IE.au3>
Global Const $g_sUrl = 'https://stackoverflow.com/'
Global $g_aIE[2]
For $i1 = 0 To UBound($g_aIE, 1) -1
_IECreateSession($g_aIE[$i1], $g_sUrl)
Next
Func _IECreateSession(ByRef $oIE, Const $sUrl)
Local Const $iPID = ShellExecute('iexplore.exe', '-nosessionmerging about:blank')
Local $aWnd
WinWait('Blank Page')
$aWnd = _WinAPI_EnumProcessWindows($iPID, True)
$oIE = _IEAttach($aWnd[1][1], 'hwnd')
_IELoadWait($oIE)
_IENavigate($oIE, $sUrl)
Return $iPID
EndFunc

How to use backup semantics (seBackup privilege) over the network?

I am trying to enumerate a directory on a remote file server.
I want to use backup-semantics in order to not require administrator credentials.
On the test server, I have created a share:
Share permissions: everyone full control
NTFS permissions: only SYSTEM (I removed all others)
I am currently using this code:
static void accessWithBackupSemantics() {
NetResource netResource = new NetResource() {
Scope = ResourceScope.GlobalNetwork,
ResourceType = ResourceType.Disk,
DisplayType = ResourceDisplayType.Share,
Usage = ResourceUsage.Connectable,
RemoteName = #"\\target-srv\TargetShare"
};
// open "net use" connection
int netResult = Native.WNetAddConnection2(netResource,
#"***password***",
#"DOMAIN\backup_op_user",
0);
if (netResult == 0 || netResult == 1219) {
// enable privileges
// (this is taken from AplhaFS)
using (new PrivilegeEnabler(Privilege.Backup)) {
try {
// try open remote directory
SafeFileHandle fsHandle = Native.CreateFile(
#"\\target-srv\TargetShare",
EFileAccess.GenericRead,
EFileShare.Read | EFileShare.Write,
IntPtr.Zero,
ECreationDisposition.OpenExisting,
EFileAttributes.BackupSemantics,
IntPtr.Zero);
Console.WriteLine("Handle is valid: " + !fsHandle.IsInvalid);
}
catch (Exception ex) {}
finally {
Native.WNetCancelConnection2(netResource.RemoteName, 0, true);
}
}
}
}
PrivilegeEnabler class is taken from AlphaFS
Native win32 structures and flags are taken from pinvoke.net/kernel32.createfile
This works if I specify "DOMAIN\Administrator" in the username, but does not work (the error is 5 - access denied) if I try to use a domain account that is a member of the local "Backup Operators" on target-srv server.
I have also examined the security event log on target-srv, for every connection created with WNetAddConnection2 a "Special Logon" event is written. The details of this event include the list of privileges that the logon account was given.
In both cases (when I connect with administrator or with backup_op_user) - seBackupPrivilege is indeed listed.
I tried to give extra privileges to the "Backup Operators" so the list has all the privileges that the Administrator has - but it made no change.
Questions:
What is the right way to use Backup-Semantics over the network?
How come it works with Administrator and not with a member of "Backup Operators" - are there additional implicit permissions for the Admin?
I have seen many examples of local use of Backup-Semantics, but not one that can be used over the network - please don't reply with links to examples of local usage.

InitiateShutdown fails with RPC_S_SERVER_UNAVAILABLE error for a remote computer

I'm trying to implement rebooting of a remote computer with InitiateShutdown API using the following code, but it fails with RPC_S_SERVER_UNAVAILABLE or 1722 error code:
//Process is running as administrator
//Select a remote machine to reboot:
//INFO: Tried it with and w/o two opening slashes.
LPCTSTR pServerName = L"192.168.42.105";
//Or use 127.0.0.1 if you don't have access to another machine on your network.
//This will attempt to reboot your local machine.
//In that case make sure to call shutdown /a /m \\127.0.0.1 to cancel it.
if(AdjustPrivilege(NULL, L"SeShutdownPrivilege", TRUE) &&
AdjustPrivilege(pServerName, L"SeRemoteShutdownPrivilege", TRUE))
{
int nErrorCode = ::InitiateShutdown(pServerName, NULL, 30,
SHUTDOWN_INSTALL_UPDATES | SHUTDOWN_RESTART, 0);
//Receive nErrorCode == 1722, or RPC_S_SERVER_UNAVAILABLE
}
BOOL AdjustPrivilege(LPCTSTR pStrMachine, LPCTSTR pPrivilegeName, BOOL bEnable)
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
BOOL bRes = FALSE;
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
if(LookupPrivilegeValue(pStrMachine, pPrivilegeName, &tkp.Privileges[0].Luid))
{
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;
bRes = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
int nOSError = GetLastError();
if(bRes)
{
if(nOSError != ERROR_SUCCESS)
bRes = FALSE;
}
}
CloseHandle(hToken);
return bRes;
}
So to prepare for this code to run I do the following on this computer, which is Windows 7 Pro (as I would do for the Microsoft's shutdown tool):
Run the following "as administrator" to allow SMB access to the logged in user D1 on the 192.168.42.105 computer (per this answer):
NET USE \\192.168.42.105\IPC$ 1234 /USER:D1
Run the process with my code above "as administrator".
And then do the following on remote computer, or 192.168.42.105, that has Windows 7 Pro (per answer here with most upvotes):
Control Panel, Network and Sharing Center, Change Advanced Sharing settings
"Private" enable "Turn on File and Printer sharing"
Set the following key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
LocalAccountTokenFilterPolicy=dword:1
RUN secpol.msc, then go to Local Security Policy, Security Settings, Local Policies, User Rights Assignment. Add "Everyone" to "Force shutdown from a remote system". (Just remember to remove it after you're done testing!)
Note that the following shutdown command seems to work just fine to reboot the remote computer:
shutdown /r /m \\192.168.42.105 /t 30
What am I missing with my code?
EDIT:
OK. I will admit that I was merely interested in why InitiateShutdown doesn't seem to "want" to work with a remote server connection, while InitiateSystemShutdownEx or InitiateSystemShutdown had no issues at all. (Unfortunately the latter two did not have the dwShutdownFlags parameter, which I needed to pass the SHUTDOWN_INSTALL_UPDATES flag to, which caused my persistence...)
At this point I had no other way of finding out than dusting out a copy of WinDbg... I'm still trying to dig into it, but so far this is what I found...
(A) It turns out that InitiateSystemShutdownEx internally uses a totally different RPC call. W/o too many details, it initiates RPC binding with RpcStringBindingComposeW using the following parameters:
ObjUuid = NULL
ProtSeq = ncacn_np
NetworkAddr = \\192.168.42.105
EndPoint = \\PIPE\\InitShutdown
Options = NULL
or the following binding string:
ncacn_np:\\\\192.168.42.105[\\PIPE\\InitShutdown]
(B) While InitiateShutdown on the other hand uses the following binding parameters:
ObjUuid = 765294ba-60bc-48b8-92e9-89fd77769d91
ProtSeq = ncacn_ip_tcp
NetworkAddr = 192.168.42.105
EndPoint = NULL
Options = NULL
which it later translates into the following binding string:
ncacn_np:\\\\192.168.42.105[\\PIPE\\lsarpc]
that it uses to obtain the RPC handle that it passes to WsdrInitiateShutdown (that seems to have its own specification):
So as you see, the InitiateShutdown call is technically treated as Unknown RPC service (for the UUID {765294ba-60bc-48b8-92e9-89fd77769d91}), which later causes a whole bunch of credential checks between the server and the client:
which, honestly, I'm not sure I want to step into with a low-level debugger :)
At this stage I will say that I am not very well versed on "Local Security Authority" interface (or the \PIPE\lsarpc named pipe configuration.) So if anyone knows what configuration is missing on the server side to allow this RPC call to go through, I would appreciate if you could post your take on it?

Programmatically set Outlook 2013 Signature Defaults?

Is it possible to programmatically set the Outlook 2013 Default Signature settings? We can generate the user's signature OK but would like to also set the signature to appear by default in user's emails:
The setting itself seems to be tucked-away in the Registry under an Outlook profile:
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Profiles\Outlook\9375CFF0413111d3B88A00104B2A6677\00000002
Reg Values:
New Signature
Reply-Forward Signature
... (which have binary data, presumably encoding the HTML file name/reference).
Not sure if I can use the Outlook Object Model to access and set settings? And whether this would be possible with a ClickOnce application?
I haven't cleaned up the code yet, but this works for me to set the signature in Outlook 2013. In python (yes I know its ugly and not PEP8).
import _winreg
def set_default():
try:
#this makes it so users can't change it.
outlook_2013_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Office\15.0\Common\MailSettings", 0, _winreg.KEY_ALL_ACCESS)
_winreg.SetValueEx(outlook_2013_key, "NewSignature", 0, _winreg.REG_SZ, "default" )
_winreg.SetValueEx(outlook_2013_key, "ReplySignature", 0, _winreg.REG_SZ, "default" )
# sets the sigs in outlook profile
outlook_2013_base_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Office\15.0\Outlook\Profiles", 0, _winreg.KEY_ALL_ACCESS)
default_profile_2013_tup = _winreg.QueryValueEx(outlook_2013_base_key,'DefaultProfile')
default_profile_2013 = default_profile_2013_tup[0]
print default_profile_2013
outlook_2013_profile_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER,
"Software\\Microsoft\\Office\\15.0\\Outlook\\Profiles\\" + default_profile_2013 + "\\9375CFF0413111d3B88A00104B2A6676", 0, _winreg.KEY_ALL_ACCESS)
for i in range(0, 10):
try:
outlook_2013_sub_key_name = _winreg.EnumKey(outlook_2013_profile_key,i)
print outlook_2013_sub_key_name, "sub_key_name"
outlook_2013_sub_key = _winreg.OpenKey(outlook_2013_profile_key, outlook_2013_sub_key_name, 0, _winreg.KEY_ALL_ACCESS)
_winreg.SetValueEx(outlook_2013_sub_key, "New Signature", 0, _winreg.REG_SZ, "default" )
_winreg.SetValueEx(outlook_2013_sub_key, "Reply-Forward Signature", 0, _winreg.REG_SZ, "default" )
except:
pass
except:
print('no 2013 found')
Outlook signatures are set on the per account basis in profile data (stored in the registry). You can see the data in OutlookSpy - click IOlkAccountManager button and double click on the account.
IOlkAccountManager can be accessed only in C++ or Delphi. If using Redemption is an option (it can be used from any language, including VBA or .Net, I am its author), it exposes the RDOAccount.ReplySignature and NewMessageSignature properties.

Is it possible to duplicate the following credential process in VB.NET?

Solution (kinda):
Turns out this impersonation with .NET's security only allows application-level access. Since the COM object is at the system level, the impersonated user still cannot instantiate it. I figured this out by right-clicking the executable and selecting "Run As...", the program functioned fine. I found out that launches the program with system access (assuming the user you are running it with has those credentials). Now I am in the process of creating an external program that will launch this application using this method.
Thanks for the tips :D
I have a windows XP installation on a virtual machine. It is part of my domain, but the logged in user is a local user only. Obviously, if I try to access a network share it will prompt for a user/password:
The program I am testing out on the virtual machine uses a COM object to interface with data from another program. If I do not impersonate, I get errors because I do not have the proper credentials.
I did some research into the matter and found a number of websites that had a decent amount of VB.NET information. The problem I am having with the code I wrote is I can access the network resources, but I cannot instantiate the COM object.
If I fill and submit the credential prompt (above) before attempting to instantiate it, it works fine. That leads me to believe there must be something that the WinXP credential prompt is doing that I am not. Below is the code I am using for Impersonation:
Public Sub BeginImpersonation()
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Const SecurityImpersonation As Integer = 2
Dim win32ErrorNumber As Integer
_tokenHandle = IntPtr.Zero
_dupeTokenHandle = IntPtr.Zero
If Not LogonUser(_username, _domainname, _password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, _tokenHandle) Then
win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
Throw New ImpersonationException(win32ErrorNumber, GetErrorMessage(win32ErrorNumber), _username, _domainname)
End If
If Not DuplicateToken(_tokenHandle, SecurityImpersonation, _dupeTokenHandle) Then
win32ErrorNumber = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
CloseHandle(_tokenHandle)
Throw New ImpersonationException(win32ErrorNumber, "Unable to duplicate token!", _username, _domainname)
End If
Dim newId As New System.Security.Principal.WindowsIdentity(_dupeTokenHandle)
_impersonatedUser = newId.Impersonate()
_impersonating = True
End Sub
I have also tried sending different flags to the impersonator method, but nothing seems to be working. Here are the different flags I found:
Enum LOGON32_LOGON
INTERACTIVE = 2
NETWORK = 3
BATCH = 4
SERVICE = 5
UNLOCK = 7
NETWORK_CLEARTEXT = 8
NEW_CREDENTIALS = 9
End Enum
Enum LOGON32_PROVIDER
[DEFAULT] = 0
WINNT35 = 1
WINNT40 = 2
WINNT50 = 3
End Enum
Enum SECURITY_LEVEL
Anonymous = 0
Identification = 1
Impersonation = 2
Delegation = 3
End Enum
I have run into this before, and used two different soloution - the easiest was using a third party app: TqcRunas: http://www.quimeras.com/Products/products.asp which allows you to package the required creentials in an encrypted file. However is a pain if the password is forced to expire.
The other solution that I have used is to call a new process with alternative credentials:
Dim myProcessStartInfo As ProcessStartInfo = New ProcessStartInfo
With myProcessStartInfo
.FileName = "file path and name"
.Domain = "domainname"
.UserName = "username"
'password needs to be a SerureString
Using NewPassword As New Security.SecureString
With NewPassword
For Each c As Char In "password".ToCharArray
.AppendChar(c)
Next c
.MakeReadOnly()
End With
.Password = NewPassword.Copy
End Using
'UseShellExecute must be false for impersonated process
.UseShellExecute = False
End With
Using Process As New System.Diagnostics.Process
With Process
.StartInfo = myProcessStartInfo
.Start()
End With
End Using
With your definitions, I use
LogonUser(_username, _domainname, _password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, _tokenHandle)
in my code that is authenticating across the network. I am impersonating a local user on the remote box, as you are. It was so long ago that I don't remember the rationale for using these values, however.
I do a similar thing to map network drives for copying files between machines. I didn't write the code but it's pretty much the same as yours, except for two things:
After the Impersonate method returns I close both tokens using the CloseHandle routine, before I exit my impersonator method.
At the top of the impersonator the first thing that happens is a call to RevertToSelf, presumably to cancel any previous impersonation.
I don't know if they would make a difference but it's worth a try. Here are the relevant declarations:
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long
Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long

Resources