How to let my program access a file in System32? - c#

I want to make a C# program that deletes a file in system32. The program can delete a file in an normally accessed area such as the desktop but won't find a file in system32, how would I give the program access to system32?
Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string filepath = #"C:\Windows\System32\New.txt";
if (File.Exists(filepath))
{
File.Delete(filepath);
}
else
{
Console.WriteLine("File not found");
Console.ReadLine();
}
}
}
}

To begin with you SHOULD NOT delete files from system 32 folder, these files usually belong to OS and should not be tempered with.
Anyways ! i would not ask why you have this requirement but windows User Account Control (UAC) will not allow you perform this operation just like that, You will need to elevate the permissions and take ownership of the file as shown below :
//take ownership of the file, code assumes file you want to delete is toBeDeleted.txt
ProcessStartInfo processInfo = new ProcessStartInfo("cmd.exe", #"/k takeown /f C:\Windows\System32\toBeDeleted.txt && icacls C:\Windows\System32\toBeDeleted.txt /grant %username%:F");
processInfo.UseShellExecute = true;
processInfo.Verb = "runas";
processInfo.FileName = fileName;//path of your executable
try
{
Process.Start(processInfo);
// a prompt will be presented to user continue with deletion action
// you may want to have some other checks before deletion
File.Delete(#"C:\Windows\System32\toBeDeleted.txt");
return true;
}
catch (Win32Exception)
{
//Do nothing as user cancelled UAC window.
}
When you run this a prompt will be presented to user to confirm this action, if you want to avoid this you'll need to run your entire host process with elevated permissions by Creating and Embedding an Application Manifest (UAC) to require the 'highestAvailable' execution level: this will cause the UAC prompt to appear as soon as your app is started, and cause all child processes to run with elevated permissions without additional prompting.
Hope this helps !

Related

System.UnauthorizedAccessException occurs under Admin privileges with full access to folder

I'm all out of ideas on fixing an "Access Denied" issue on Windows 8.1...
I'm building a console app in Visual Studio under Administrative mode and my app is simply trying to do the following:
using System.IO;
namespace CommandCenterScriptLauncher
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("The argument passed was " + args[0] + ".");
Console.ReadLine();
File.WriteAllText(#"C:\Users\Matt\Music\target", "TEXT FILE BODY WITH ARG: " + args[0]);
}
catch
{
Console.WriteLine("No arguments were passed.");
Console.ReadLine();
File.WriteAllText("C:\\Users\\Matt\\Music\\target", "TEXT FILE BODY WITH NO ARGS");
}
}
}
}
Not only am I running in Admin mode which isn't helping, but the folder itself is NOT read only, and ALL USERS on the Security tab for the target folder have been granted FULL CONTROL.
What else am I missing here?!
You need to pass in a filename to File.WriteAllText. Right now, it looks like you are trying to write to a directory. That won't work.
Can you write in another location?. Windows for some reason prevent for writing on system folders. Try something like 'c:/Test/yourFile.txt'.
Check also UAC is disabled.

See command line arguments being passed to a program

You may skip this part
I am using a batch file that I have in my thumb drive in order to
mount a true crypt volume. I created that batch file with the help of
this link. on that batch file I have the username and password
that I pass as arguments to trueCrypt.exe in order for it to be
mounted.
Anyways so my question is: will it be possible to see the arguments being passed to a program from a third party process? In other words, will it be possible to see the arguments being passed to this program:
using System;
using System.Reflection;
using System.Diagnostics;
class Program
{
static string password = "";
static void Main(string[] args)
{
if (args.Length > 0)
password = args[0];
// get location where this program resides
var locationOfThisExe = Assembly.GetExecutingAssembly().Location;
Console.Write("Press enter to start a new instance of this program.");
Console.Read();
var randomArgument = new Random().NextDouble().ToString();
Process.Start(locationOfThisExe, randomArgument);
// I am passing a random argument to a new process!
// is it possible to see these arguments from another process?
}
}
Edit
I am creating an edit cause I think I explained my self incorrectly but this edit should be a solution instead of a question
I think this question has not received enough attention. Executing the command showed by https://stackoverflow.com/users/235660/alois-kraus shows:
(I pasted the output on notepad++)
on the image it does not show very clearly but I was able to see the argument being pass to that process. That matters a lot to me because I mount my true crypt volumes with the command:
"C:\Program Files\TrueCrypt\TrueCrypt.exe" /v "a:\volume.tc" /lz /a /p a
that tells to truecrypt that I want to mount the volume located at a:\volume.tc on drive letter z and the password is a
If I execute that command true crypt will mount that volume on drive z:
the problem is that If I then execute the command wmic process note what shoes up:
Note the password is in there!
So in summary it is not safe to pass secure information as an argument. It may be secure if you close the process that received the arguments but I think it is important to be aware of this...
If other users with administrative rights or with the same user account can execute programs you can see all command lines with
wmic process
from all processes with this single command line.

Need to delete files in Program files using c#, files wont delete

Why wont the files in the test folder delete?? How can i get admin access??
namespace Delete
{
using System;
using System.Windows.Forms;
using System.IO;
public class Delete
{
public Delete()
{
if (Directory.Exists(#"C:\Program Files (x86)\test\"))
{
string[] filePaths = Directory.GetFiles(#"C:\Program Files (x86)\test\");
foreach (string file in filePaths) { File.Delete(file); }
}
}
}
}
You need to rethink your strategy.
If you are adding/removing files programatically from within your application, they should be stored in a separate location (that won't need admin privs to elevate for writing/deleting, etc.):
like the user's data directory/your company/your application, or
the user's documents/your company/your application
The Program Files directory is for application specific files (DLL's, etc) that are installed with the program but don't change once installed/updated.
Here's an example of the User's Data directory by application:
public static DirectoryInfo ApplicationVersionDirectory()
{
return new DirectoryInfo(System.Windows.Forms.Application.UserAppDataPath);
}
This is due to the UAC. So either run your executable as admin by right clicking -> "Run as Administrator" or if you want to do it programatically refer to other posts like Windows 7 and Vista UAC - Programmatically requesting elevation in C#
In order to delete files from "Program Files" folder you need to start application as an administrator. Otherwise you will not be able to get an access to %PROGRAMFILES%.
Here is the sample code to restart current app and run it as admin:
ProcessStartInfo proc = new ProcessStartInfo();
proc.UseShellExecute = true;
proc.FileName = Application.ExecutablePath;
proc.Verb = "runas";
try
{
Process.Start(proc);
}
catch
{
// The user refused the elevation.
// Do nothing and return directly ...
return;
}
Application.Exit(); // Quit itself

C# running batch file on remote machine after PsExec has been started

Basically, I'm trying to run the batch file that was copied on the remote machine, by the way, this is my first attempt at coding, so please be nice but critique it if you want, I'm still learning the language and had to spend 3 hours to get this far, thank god for Google, LOL.
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void cleanerBtn_Click(object sender, EventArgs e)
{
//Copying Batch File to Remote Host
string fileToCopy = "C:\\Clean.bat";
string newLocation = hostName.Text;
string newFile = (newLocation + "\\clean.bat");
System.IO.File.Copy(fileToCopy, newLocation);
//Run PsExec
string psExec = "psexec -s "+newLocation+" cmd";
System.Diagnostics.Process.Start("CMD.exe", psExec);
//Run Batch File using PsExec
//Removing Batch File from Remote Host
System.IO.File.Delete(newFile);
}
}
}
Thanks in advance.
From PSExec help:
-c Copy the specified program to the remote system for
execution. If you omit this option the application
must be in the system path on the remote system.
Use that flag to make PSExec copy the batch file that you want executed to the remote system and run it. You don't have to write extra code to do that.
Basically you want to do:
psexec \\server cmd.exe /c file_you_want_to_run.bat
Try running CMD.exe with /C. From cmd.exe help:
/C Carries out the command specified by string and then terminates
The /C needs to be appended to the content of the psExec:
System.Diagnostics.Process.Start("CMD.exe", "/C " + psExec);
I believe you'll get the expected results then. If not, you might want to make sure psexec.exe is in a directory that is in the PATH environment variable.
Also, you might be interested to look into ProcessStartInfo to specify different other parameters that can be set for the execution of a process.

C# redirect standardinput with PGP -ka command

I am having a problem which seems really daft. I must be missing something silly. We have a PGP keyring that is on one of our production servers. The user account it belongs to is not allowed to be logged on as interactively for security. Our problem is we sometimes need to add new keys and can not do this easily. So we thought we could create a quick console app that would be run as its ID and would call the PGP commands via the command line.
The command gets called but it asks for input to confirm what we are doing. Our problem is the "y" we send to standardinput is never displayed and the key is not verified.
here is the code:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.DirectoryServices;
using System.Threading;
namespace TestConsoleApp
{
class RegExValidator
{
private System.Diagnostics.Process myProcess;
public RegExValidator()
{
}
public static void Main(string[] args)
{
RegExValidator myValidator = new RegExValidator();
myValidator.InstallKeys("C:\\Test\\batch.asc", "batch.asc");
}
private void InstallKeys(string keyPath, string keyName)
{
myProcess = new System.Diagnostics.Process();
myProcess.StartInfo.RedirectStandardInput = true;
myProcess.StartInfo.CreateNoWindow = false;
myProcess.StartInfo.UseShellExecute = false;
myProcess.StartInfo.FileName = "pgp";
myProcess.StartInfo.Arguments = "-ka " + keyPath + "";
myProcess.Start();
StreamWriter myInput = myProcess.StandardInput;
myInput.AutoFlush = true;
Thread.Sleep(3000);
myInput.WriteLine("y");
myInput.WriteLine(Environment.NewLine);
}
}
}
This is the output we get on the command line.
C:\Test>TestConsoleApp.exe
Pretty Good Privacy(tm) Version 6.5.2
(c) 1999 Network Associates Inc.
Uses the BSafe(tm) Toolkit, which is copyright RSA Data Security, Inc.
Export of this software may be restricted by the U.S. government.
WARNING: Environmental variable TZ is not defined, so GMT timestamps
may be wrong. See the PGP User's Guide to properly define TZ
Looking for new keys...
DSS 2048/1024 0xDE053A3D 2007/05/29 Batch Interface <batch#netgiro.com>
sig? 0xDE053A3D (Unknown signator, can't be checked)
keyfile contains 1 new keys. Add these keys to keyring ? (Y/n)
C:\Test>
Can anyone help?
Thanks
EDIT
We tried this process but instead of PGP we just moved a file and we got the Y/N box and that worked. It would seem that you may not be able to do it with PGP. No idea why though.
The message
keyfile contains 1 new keys. Add these keys to keyring ? (Y/n)
suggests replying with an Uppercase Y. try changing your call to:
myInput.WriteLine("Y");
(I have no PGP installed for checking, but have encountered other command line interfaces that insisted on case.)
Another thing to try is flushing stream buffers, which clears all buffers for the stream and causes any buffered data to be written to the underlying device:
myInput.WriteLine("Y");
myInput.Flush();

Categories

Resources