Hello all,
Welcome to the Securitytube Python Scripting Expert Course and Certification... If you have enrolled into the course, these words should sound like music in your head :).
I took yesterday the exam and I want to write down here my feelings and impressions on the experience.
A 6 hours exam is definitely not the most relaxing moment of your live. I slept for 12 hours the night before, woke up, strong breakfast, a 30 minutes walk to got up my mind and... there we go!.
4 full virtual desks opened. One with sublime and terminator to develop the scripts in linux, another one with windows XP, Immunity debugger and some pyhooks already opened, the third one with a kali linux and a bash shell directly pointing to the ruby scripts folder for generating and check string patterns (pattern_create.rb and pattern_offset.rb), and finally the last one with a metasploitable machine such a case something involving opened ports, other services or testing over DVWA, Mutillidae and so on... Everything ready... mmmm, no!, A coke beside me... ok, now.
I started 1 hour before the exam reviewing my code because I wanted to start the exam in the highest concentration peak and it worked fine for me. Just received the exam by e-mail, half an hour before the scheduled, and 4 questions on it... Hands on!
Even though I don't know the results, I think if you have gone through all the course, code all the practices with Vivek and performed the suggested exercises, you shouldn't be worried about the exam. I had ready 3 on 4 exercises after 1 hour.
After 3 and a half hours trying the last one I decided to give up. I am not going to unveil any exercise in the exam but I will tell you to dig in how to recover and to manage "Handle" windows object from the stack.
If you have any question, just post a comment and I will be back to you.
++Security
++Security
Sunday 28 August 2016
SPSE Securitytube Python Scripting Expert Exam
Sunday 21 August 2016
SPSE IMAP and DB connection
As another of the exercises of the mocked exam, it is necessary to retrieve information from an e-mail account via IMAP.
Before going into the exercise itself several things are needed. First of all we need to install the database, I chose Mysql just because is the most known for me but you can use any other, it is up to you.
After installing the database you will need the connector for python and if you are using linux (which is quite probable) you will need the -dev packages as well. Don't panic, step by step you will find how to install all the staff just googling.
After installing the DBMS is recommended as well to create a new database user and grant it the convenient permissions. I leave all this set up to you and I will concentrate this post in solving strictly the exercise itself.
First of all start Mysqld and connect as root in order to create the database, and grant permissions to our user previously created:
$ sudo /etc/init.d/mysql start
$ mysql -u root -p
Insert the password when prompted for it. We shouldn't start the database as root in a real environment but create another user with the minimum privileges and run the DBMS using that user. As it is just an example, please, skip that detail.
Now we need to create a new DB, lets call it "mail" (original, isn't? :)).
mysql> CREATE DATABASE mail;
Query OK, 1 row affected (0.00 sec)
mysql> CREATE DATABASE mail;
Query OK, 1 row affected (0.00 sec)
And grant permission on the database to our user previously created user.
mysql> GRANT ALL PRIVILEGES ON mail.* TO [user];
Query OK, 0 rows affected (0.00 sec)
Now we exit from the database and enter again using our [user]
$ mike@mike-SATELLITE-S50-B:~$ mysql -u [user] -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
We select the database and create the table:
mysql> use mail
Database changed
mysql> CREATE TABLE emails (num_mail VARCHAR(10), mail_content MEDIUMTEXT);
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+----------------+
| Tables_in_mail |
+----------------+
| emails |
+----------------+
1 row in set (0.00 sec)
Note the table is created with two columns, the num_mail is intended to store an index of the e-mail and the mail_content which will keep the content of the e-mail.
With all the tasks before, we have our database ready. Now go ahead with the code. Don't forget our objective is retrieving the e-mail and store it into the database table we have just created. Therefore you need an e-mail account and enable the IMAP connection for that account. I chose Gmail but again this is up to you. I spent sometime looking for free disposable email with IMAP support without success... If you are more lucky, please, leave a comment!. I leave to you how to enable IMAP for the platform of your election.
Now check the code at the bottom of the next link:
https://docs.python.org/2/library/imaplib.html
With some little changes we come to the next piece of code:
I have tried to develop this piece of code self-explaining through 'print' statements so, there shouldn't be too many questions.
The previous script opens both connections, the one to the database and the one to the IMAP Server. After that, it performs the login and fetches the inbox. The next step is seek for all the e-mails in the inbox. For each e-mail, it retrieves its content and execute the query that adds the e-mail index and the content to the database.
to inspect the content in the database just perform a select in the table emails.
mysql> SELECT * FROM emails;
mysql> GRANT ALL PRIVILEGES ON mail.* TO [user];
Query OK, 0 rows affected (0.00 sec)
Now we exit from the database and enter again using our [user]
$ mike@mike-SATELLITE-S50-B:~$ mysql -u [user] -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
We select the database and create the table:
mysql> use mail
Database changed
mysql> CREATE TABLE emails (num_mail VARCHAR(10), mail_content MEDIUMTEXT);
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+----------------+
| Tables_in_mail |
+----------------+
| emails |
+----------------+
1 row in set (0.00 sec)
Note the table is created with two columns, the num_mail is intended to store an index of the e-mail and the mail_content which will keep the content of the e-mail.
With all the tasks before, we have our database ready. Now go ahead with the code. Don't forget our objective is retrieving the e-mail and store it into the database table we have just created. Therefore you need an e-mail account and enable the IMAP connection for that account. I chose Gmail but again this is up to you. I spent sometime looking for free disposable email with IMAP support without success... If you are more lucky, please, leave a comment!. I leave to you how to enable IMAP for the platform of your election.
Now check the code at the bottom of the next link:
https://docs.python.org/2/library/imaplib.html
With some little changes we come to the next piece of code:
#!/usr/bin/env python
import getpass, imaplib
import mysql.connector
DATABASE = 'mail'
USER = 'usernamehere'
PASS = 'passwordhere'
MAIL_SERVER = "imap.gmail.com"
MAIL_ACCOUNT = "mailhere@gmail.com"
# Connecting to the database and preparing the query
print "[i] connecting to the database:" + DATABASE + "...",
cnx = mysql.connector.connect(user=USER, password=PASS, host='127.0.0.1', database=DATABASE)
cursor = cnx.cursor()
print "[ OK ]"
print "[i] defining the query...",
new_entry = ("INSERT INTO emails (num_mail, mail_content) VALUES (%s, %s)")
print "[ OK ]"
print "[i] connecting to the mail server " + MAIL_SERVER + "...",
M = imaplib.IMAP4_SSL(MAIL_SERVER)
print "[ OK ]"
print "[i] logging in and selecting inbox...",
M.login(MAIL_ACCOUNT, getpass.getpass())
M.select()
print "[ OK ]"
print "[i] Searching e-mails...",
typ, data = M.search(None, 'ALL')
print "[ OK ]"
for num in data[0].split():
print "[i] fetching e-mail " + str(num) + "...",
typ, data = M.fetch(num, '(RFC822)')
print "[ OK ]"
print "[i] constructing data tuple and executing query...",
info = (num,data[0][1])
cursor.execute(new_entry,info)
print "[ OK ]"
print "[i] committing the changes made and closing database connection!...",
cnx.commit()
cursor.close()
cnx.close()
print "[ OK ]"
print "[i] closing IMAP connection!...",
M.close()
M.logout()
print "[ OK ]"
import getpass, imaplib
import mysql.connector
DATABASE = 'mail'
USER = 'usernamehere'
PASS = 'passwordhere'
MAIL_SERVER = "imap.gmail.com"
MAIL_ACCOUNT = "mailhere@gmail.com"
# Connecting to the database and preparing the query
print "[i] connecting to the database:" + DATABASE + "...",
cnx = mysql.connector.connect(user=USER, password=PASS, host='127.0.0.1', database=DATABASE)
cursor = cnx.cursor()
print "[ OK ]"
print "[i] defining the query...",
new_entry = ("INSERT INTO emails (num_mail, mail_content) VALUES (%s, %s)")
print "[ OK ]"
print "[i] connecting to the mail server " + MAIL_SERVER + "...",
M = imaplib.IMAP4_SSL(MAIL_SERVER)
print "[ OK ]"
print "[i] logging in and selecting inbox...",
M.login(MAIL_ACCOUNT, getpass.getpass())
M.select()
print "[ OK ]"
print "[i] Searching e-mails...",
typ, data = M.search(None, 'ALL')
print "[ OK ]"
for num in data[0].split():
print "[i] fetching e-mail " + str(num) + "...",
typ, data = M.fetch(num, '(RFC822)')
print "[ OK ]"
print "[i] constructing data tuple and executing query...",
info = (num,data[0][1])
cursor.execute(new_entry,info)
print "[ OK ]"
print "[i] committing the changes made and closing database connection!...",
cnx.commit()
cursor.close()
cnx.close()
print "[ OK ]"
print "[i] closing IMAP connection!...",
M.close()
M.logout()
print "[ OK ]"
I have tried to develop this piece of code self-explaining through 'print' statements so, there shouldn't be too many questions.
The previous script opens both connections, the one to the database and the one to the IMAP Server. After that, it performs the login and fetches the inbox. The next step is seek for all the e-mails in the inbox. For each e-mail, it retrieves its content and execute the query that adds the e-mail index and the content to the database.
to inspect the content in the database just perform a select in the table emails.
mysql> SELECT * FROM emails;
Thursday 18 August 2016
SPSE Pyhooks
Some time ago I was looking for the way of developing my own tools. Of course thinking on creating tools to attack web applications. After a quick search in google I found out the SecurityTube Python Scripting Expert Course which content was mainly in form of videos. Finally I decided to bet on the certification and here we are trying to go through the exam in just a couple of weeks.
I save my opinion about the course until I have actually finished. It is still some study and the exam pending for me.
Going to the point, one of the parts of the reversing course was attaching to an existent process by means of pyhooks. There are several different types of pyhooks being the most used during the course the ones of BPHook type. You can extend the information on pyhooks here.
As one of the exercises in the mocked exam, we need to develop a script hooking to the bind function in certain .exe file. The objective of the pyhook is printing the IP and the port the .exe file is binding to.
This piece of code solves the problem:
#!/usr/bin/env python
import immlib
from immlib import LogBpHook
import struct
import socket
DESC = "Bind hook demo"
class DemoHook(LogBpHook):
def __init__(self):
LogBpHook.__init__(self)
def run(self, regs):
imm = immlib.Debugger()
sockAddrIn = imm.readLong(regs['ESP'] + 8)
port = struct.unpack("!H",imm.readMemory(sockAddrIn + 2,2))
bindedIp = imm.readMemory(sockAddrIn + 4,4)
imm.log("[+] Bind Function called.")
imm.log("Port binded: %d" % port)
imm.log("IP Address: %s" % str(socket.inet_ntoa(bindedIp)))
#receivedStr = imm.readString(secondArg)
#imm.log("Received String %s" % receivedStr)
def main(args):
imm = immlib.Debugger()
hookFunction = "ws2_32.bind"
functAddress = imm.getAddress(hookFunction)
newHook = DemoHook()
newHook.add("Bind Hook", functAddress)
return "Bind BPHooking"
Simple, isn't it?. Let see what is behind each LoC in this "small" pyhook
import immlib
from immlib import LogBpHook
import struct
import socket
DESC = "Bind hook demo"
class DemoHook(LogBpHook):
def __init__(self):
LogBpHook.__init__(self)
def run(self, regs):
imm = immlib.Debugger()
sockAddrIn = imm.readLong(regs['ESP'] + 8)
port = struct.unpack("!H",imm.readMemory(sockAddrIn + 2,2))
bindedIp = imm.readMemory(sockAddrIn + 4,4)
imm.log("[+] Bind Function called.")
imm.log("Port binded: %d" % port)
imm.log("IP Address: %s" % str(socket.inet_ntoa(bindedIp)))
#receivedStr = imm.readString(secondArg)
#imm.log("Received String %s" % receivedStr)
def main(args):
imm = immlib.Debugger()
hookFunction = "ws2_32.bind"
functAddress = imm.getAddress(hookFunction)
newHook = DemoHook()
newHook.add("Bind Hook", functAddress)
return "Bind BPHooking"
Simple, isn't it?. Let see what is behind each LoC in this "small" pyhook
By default the bind function in Windows takes 3 arguments according to the documentation in here:
That three arguments are:
- s [in]: A descriptor identifying an unbound
- socket.name [in]: A pointer to a sockaddr structure of the local address to assign to the bound socket .
- namelen [in]: The length, in bytes, of the value pointed to by the name parameter.
So, we are interested in the second parameter as is the one including the local address.
It worths to mention that the stack grows from higher to lower positions in X86 systems and the parameters are introduced in the stack starting from the last one of them.
keeping it in mind we will find in memory just after the call the first parameter
in ESP+4, the second one in ESP+8 and the third one in ESP+12 (the first one included in the stack which is a LIFO structure).
And how it will look like? The structure is as follows:
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
As you know, the infomation in the stack is not the parameter itself but the memory address where to find the parameter value. Therefore we need to read ESP + 8 where we will locate the memory address of the scokaddr_in structure.
As we want to print the port number, we need to read a short starting from that point + 2 memory positions (busy with the sin_family).
Another important consideration is that the information in memory for this parameter is stored in network byte order. We can use the "!" character in the format string to indicate we want to read form memory in this way or alternatively use ">" character since network order is equivalent to Big Endian.
According to the documentation in here you can find how the format string should be forged in order to read an unsigned short from a memory position and the number of bytes it will take up.
https://docs.python.org/2/library/struct.html
As a result we have already our variable containing the port number
Exactly following the same thinking we can come up with how to retrieve the
IP address from the stack... or maybe not. Again something missing. Even though we know an IPv4 address is 4 bytes we don't know if the struct in_addr has any other fields inside.
Another important consideration is that the information in memory for this parameter is stored in network byte order. We can use the "!" character in the format string to indicate we want to read form memory in this way or alternatively use ">" character since network order is equivalent to Big Endian.
According to the documentation in here you can find how the format string should be forged in order to read an unsigned short from a memory position and the number of bytes it will take up.
https://docs.python.org/2/library/struct.html
As a result we have already our variable containing the port number
Exactly following the same thinking we can come up with how to retrieve the
IP address from the stack... or maybe not. Again something missing. Even though we know an IPv4 address is 4 bytes we don't know if the struct in_addr has any other fields inside.
Another quick googling and we found out it looks like this:
https://msdn.microsoft.com/es-es/library/windows/desktop/ms738571(v=vs.85).aspx
typedef struct in_addr {
union {
struct {
u_char s_b1,s_b2,s_b3,s_b4;
} S_un_b;
struct {
u_short s_w1,s_w2;
} S_un_w;
u_long S_addr;
} S_un;
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
So what would we find in the memory address of sockAddrIn + 4? If we assume the server is using a code like the one in here:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs.85).aspx
we will find an unsigned long corresponding to the S_addr parameter. But the story doesn't end so fast. We need a function to translate the data recovered from memory to a string which can be understood and properly displayed. Our function is in the "socket" module and it is called inet_ntoa. Again we need to know this method is taking a PACKED IP address as parameter so we shouldn't to unpack the information in memory or it won't work. Reference in here:
https://docs.python.org/2/library/socket.html
That's it, we can just print confortably both parameters to the log. For running
the pyhook, as it has been developed as a pycommand it must be placed in the pycommands folder of immunity debugger.
Another important aspect to take into account is that the bind call is called only once, after that one there is a loop calling accept in order to serve all the clients. That means the pyhook must be run before the .exe file executing the function call. The correct order is open the .exe file, execute the pyhook and then run the program.
++Security
Wednesday 17 August 2016
A new hope
When I started working on security, there in 2006, I would never imagine to be where I am today. I have been involved in projects with some of the greatest companies in the world and I still feel like a newbie. I would never imagine to find so huge knowledge field than the more you know the more you feel insignificant.
The idea of starting this blog came from a course I am going through currently. Some of the exercises are not exactly easy and I have decided to put some of them black on white.
My idea is just use this blog as a support for my continuous learning on IT Security so I expect to treat different topics ranging from secure engineering to penetration testing. If you don't mind having another page in your bookmarks or another RSS in your feed, I hope you to find interesting articles from time to time ;).
++Security
The idea of starting this blog came from a course I am going through currently. Some of the exercises are not exactly easy and I have decided to put some of them black on white.
My idea is just use this blog as a support for my continuous learning on IT Security so I expect to treat different topics ranging from secure engineering to penetration testing. If you don't mind having another page in your bookmarks or another RSS in your feed, I hope you to find interesting articles from time to time ;).
++Security
Subscribe to:
Posts (Atom)