Blind SQLi Timing Checks and DoS
I have been testing Arachni's experimental branch against a few
vulnerable applications (Hackazon in this case) and have run into
an issue where Arachni causes a DoS against a local target web
server using the following options:
./arachni http://172.x.y.z:8000/ --plugin=autologin:url=http://172.x.y.z:8000/user/login,parameters='username=user&password=test123',check='Logout' --scope-exclude-pattern logout --timeout 02:00:00 --http-request-concurrency=1 --http-request-timeout=10000 --browser-cluster-ignore-images --browser-cluster-pool-size=1 --audit-with-raw-payloads --checks=sql_injection_timing
I was able to trace this back to the Blind SQLi timing checks by
monitoring the scan and saw the number of Apache pids and an
excessive number of CLOSE_WAIT's for connections on the target host
when Arachni started the Blind SQLi timing checks. I also monitored
the mysql database on the target for long running queries and the
Apache logs so I could see what Arachni was sending to hang the
server:
while a==a; do echo "Apache PIDs: ps -ef | grep apache | grep -v grep | wc -l
"; echo "CLOSE_WAIT Connections: netstat -an | grep CLOSE_WAIT | grep ":8000" | wc -l
"; mysql -uhackazon -p****** -e"SELECT TIME,INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER='hackazon'";echo "Apache Log: grep "sleep(4)" /var/log/apache2/access.log | tail -1 | cut -d"]" -f2
"; echo "##########################"; sleep 5; done
After a few minutes into the Blind SQLi timing checks, the target
host becomes unresponsive. I've tried the previously mentioned
suggestion for
rate-limiting concurrent connections, however it doesn't seem
have an affect in this scenario. This issue seems to happen when a
successful Blind SQLi attack occurs against the target within a
query's WHERE clause and large tables:
Apache PIDs: 152
CLOSE_WAIT Connections: 152
+------+--------------------------------------------------------------------------------------------+
| TIME | INFO |
+------+--------------------------------------------------------------------------------------------+
| 0 | SELECT TIME,INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE USER='hackazon' |
| 182 | SELECT * FROM 'tbl_categories' WHERE 'tbl_categories'.'categoryID' = '49'=sleep(4)='' LIMIT 1 |
+------+--------------------------------------------------------------------------------------------+
Apache Log: "GET /category/view?id=49'=sleep(4)=' HTTP/1.1" 200 5681 "-" "Arachni/v2.0dev"
The attack results in a sleep(4) occurring for every row when the
condition is false, so it creates a very long running query (i.e.
~4 mins for the query above with some other queries taking over 14
mins). Since this happens for a number on inputs on this target, I
believe this is why I'm seeing so many Apache PIDs and CLOSE_WAITs
occurring that eventually kills the server. Is it possible to look
for dangerous conditions such as this with the timing checks and
selectively throttle only the timing checks when a connection has
been open longer than some safe upper limit (i.e. sleep(4) +
some_safe_upper_limit) to ensure a target doesn't get DoS'd?
I tried testing this in the latest nightly build instead of running directly from the experimental branch, but scans seem to be hanging at "Processing plugins" with the Nov. 23rd nightly build.
Comments are currently closed for this discussion. You can start a new one.
Keyboard shortcuts
Generic
? | Show this help |
---|---|
ESC | Blurs the current field |
Comment Form
r | Focus the comment reply box |
---|---|
^ + ↩ | Submit the comment |
You can use Command ⌘
instead of Control ^
on Mac
Support Staff 1 Posted by Tasos Laskos on 02 Dec, 2015 11:05 PM
I don't think this has to do with HTTP request throttling, it looks to be solely the result of the SQL injection payload and I'll fix it ASAP.
Thanks a lot for the information, I'll let you know once a nightly is available that fixes this issue.
Cheers
Support Staff 2 Posted by Tasos Laskos on 02 Dec, 2015 11:23 PM
Come to think about it again, the high DB query runtimes may not be related to the payload, but by resource exhaustion due to the many Apache workers.
Especially since the SQL query has a
LIMIT
clause.Does the issue occur after uncommenting this line?:
https://github.com/Arachni/arachni/blob/experimental/lib/arachni/ht...
Support Staff 3 Posted by Tasos Laskos on 03 Dec, 2015 12:17 AM
I did a little more research, a solution to this seems to only exist for MySQL >= 5.6.
I figured with the
LIMIT
clause it wouldn't be the payload, but from what I could find it turns out that things work exactly the way you described.The
sleep()
function call is executed for each row, and even when injected as a subquery ((select sleep(4)
) it'll still behave the same way for any version < 5.6.If you are worried about stressing remote MySQL servers you better not load the
sql_injection_timing
check or specify themssql,pgsql
platforms which will skip MySQL payloads.4 Posted by wspires on 03 Dec, 2015 03:55 PM
I tried uncommenting that line you suggested and the results are similar as before:
I believe the resource exhaustion is an indirect result of the long running query that's created with the attack payload. All of those Apache procs are hanging around inCLOSE_WAIT
until those long running queries return to allow the connections to fully close. I don't think there is anything that Arachni can do to force that connection to fully close when the DB is tying up the Apache connections inCLOSE_WAIT
.The reason why I was looking at request throttling is because throttling the rate of the timing test requests once something like this occurs during a scan may allow the rest of a scan to finish while waiting for those long running queries to return for the timing tests. Another way to handle it once something like this is detected is to just bail out of the remaining mysql timing checks altogether and report the vuln and potential DoS condition to the user. I'm not sure how possible something like that would be though.
So far I haven't noticed where Blind SQLi has been reported in any of the scans where I ran into this, even though the payload seems to be executing. This may be due to the excessive time it takes for the query to return, but I'm not sure if that would cause a reporting issue.
Support Staff 5 Posted by Tasos Laskos on 03 Dec, 2015 04:08 PM
The issues aren't being reported because the server has become unusable so there's no way to verify them.
This is just the first stage of the timing attacks.
As for throttling the timing attacks, that happens during the verification phases, it's assumed that the server will make it past the initial candidate gathering phase though.
There usually are server side timeouts for sql queries to prevent these types of problems and the scanner can only do so much.
If you're worried about that happening in real world circumstances the only solution is to not perform sql injections using timing attacks against MySQL.
Tasos Laskos closed this discussion on 07 Dec, 2015 09:48 PM.