Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement anti-CSRF protection bypass #2

Closed
bdamele opened this issue Jun 26, 2012 · 18 comments
Closed

Implement anti-CSRF protection bypass #2

bdamele opened this issue Jun 26, 2012 · 18 comments

Comments

@bdamele
Copy link
Member

bdamele commented Jun 26, 2012

I think that this can be done taking advantage of the object that handles --forms (forms parsing) switch.

@ghost ghost assigned stamparm Jun 26, 2012
stamparm added a commit that referenced this issue Sep 6, 2012
stamparm added a commit that referenced this issue Oct 19, 2012
stamparm added a commit that referenced this issue Oct 19, 2012
@chym chym mentioned this issue Nov 10, 2012
@bdamele
Copy link
Member Author

bdamele commented Dec 20, 2012

Sometimes applications implement CSRF protection in a stronger way: the token is renewed upon a refresh and invalidated server-side once used.

sqlmap could handle this case as follows:

  1. user provides --form (or a --data with inside some param named like nonce or token).
  2. sqlmap recognizes possible CSRF token(s).
  3. sqlmap asks user "are these X parameters, tokens?"
  4. user says Yes.
  5. sqlmap automatically performs a request to the original page.
  6. sqlmap extracts from the response body the token value.
  7. sqlmap performs the request to the target page (form in case of --forms, same page in case of --data) with the extracted value of token.

@bdamele bdamele reopened this Dec 20, 2012
@tennessee
Copy link

Good day!

sqlmap does not recognize the CSRF token. The parameter name token is not quite standard, I tried to change it to mean 'token' or 'nonce' but that, unfortunately, had no effect! Can I somehow explicitly in sqlmap option to define a token. Thank you!

@stamparm
Copy link
Member

Either user explicitly states the anti-CSRF token name (e.g. --csrf-token) or sqlmap automatically recognizes it (and asks user if it's correct in recognition) (e.g. csrf_token or csrf_nonce). If everything goes well, anti-CSRF token would be extracted after the dummy request/response and stored for usage in the following SQLI request.

p.s. case where this all would be problematic is the multi-threaded data retrieval

@stamparm stamparm changed the title Implement anti-CSRF protection bypass (e.g. .NET VIEWSTATE) Implement anti-CSRF protection bypass Oct 23, 2014
stamparm added a commit that referenced this issue Oct 23, 2014
@stamparm
Copy link
Member

New options:

$ python sqlmap.py -hh | grep CSRF
    --csrf-token=CSR..  Parameter used to hold CSRF protection token
    --csrf-url=CSRFURL  URL address to visit to extract CSRF protection token

Option --csrf-url doesn't have to be explicitly used if the original --url carries the CSRF protection token

stamparm added a commit that referenced this issue Oct 23, 2014
@stamparm
Copy link
Member

Example run:

python sqlmap.py -u "http://debiandev/sqlmap/mysql/csrf/post.php" --csrf-token="secret_token" --csrf-url="http://debiandev/sqlmap/mysql/csrf/" --data="id=1&secret_token="  --flush-session --batch -v 6

...

[11:45:20] [TRAFFIC OUT] HTTP request [#42]:
GET /sqlmap/mysql/csrf/ HTTP/1.1
Accept-language: en-us,en;q=0.5
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: sqlmap/1.0-dev-7fc9e82 (http://sqlmap.org)
Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Host: debiandev
Pragma: no-cache
Cache-control: no-cache,no-store
Cookie: PHPSESSID=4bca6044f9b0c382fb6771a745498dfe
Connection: close

[11:45:20] [TRAFFIC IN] HTTP response [#42] (200 OK):
Content-length: 173
X-powered-by: PHP/5.2.6-1+lenny4
Content-encoding: gzip
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Vary: Accept-Encoding
Uri: http://debiandev/sqlmap/mysql/csrf/
Server: Apache/2.2.9
Connection: close
Pragma: no-cache
Cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Date: Thu, 23 Oct 2014 09:45:29 GMT
Content-type: text/html



<html>
<form method="POST" name="csrfguard_sample" action="post.php">
  <input type="text" name="id">
  <input type="hidden" name="secret_token" value="14140575295448ce39011c2">
  <input type="submit" value="Submit">
</form>

[11:45:20] [TRAFFIC OUT] HTTP request [#43]:
POST /sqlmap/mysql/csrf/post.php HTTP/1.1
Accept-language: en-us,en;q=0.5
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: sqlmap/1.0-dev-7fc9e82 (http://sqlmap.org)
Accept-charset: ISO-8859-15,utf-8;q=0.7,*;q=0.7
Host: debiandev
Pragma: no-cache
Cache-control: no-cache,no-store
Content-type: application/x-www-form-urlencoded; charset=utf-8
Cookie: PHPSESSID=4bca6044f9b0c382fb6771a745498dfe
Content-length: 41
Connection: close

id=1&secret_token=14140575295448ce39011c2

...

stamparm added a commit that referenced this issue Oct 23, 2014
@stormwin
Copy link

I have seen some web sites that store csrf token in cookie. When we make a request to the server, some of them expect token to be at the end of URL or post data, and some of them expect a token in headers like X-CSRF-TOKEN: 14140575295448ce39011c2... what about the last case with token in headers, does sqlmap support that?

@stamparm
Copy link
Member

Not (yet). Problem is that in those cases (as I know), necessary changes are being done with the usage of Javascript, which is a huge obstacle.

p.s. @stormwin do you have one of those examples around?

@stamparm
Copy link
Member

inurl:"services/session/token"

p.s. the whole process is described here: http://tylerfrankenstein.com/code/drupal-services-csrf-token-firefox-poster
p.p.s. going to implement this too

stamparm added a commit that referenced this issue Oct 23, 2014
stamparm added a commit that referenced this issue Oct 23, 2014
@stamparm
Copy link
Member

@stormwin Implemented support for X-CSRF-TOKEN (too)

Example run:

python sqlmap.py -u "http://debiandev/sqlmap/mysql/get_int.php?id=1" --headers="X-CSRF-Token: oTpCTAKvWui1gsp3itVdZOu9F2BQxU55N323S51BWJ0" --csrf-url="http://debiandev/services/session/token" --csrf-token=x-csrf-token -v 6

...

[14:35:18] [TRAFFIC OUT] HTTP request [#1]:
GET /services/session/token HTTP/1.1
Host: debiandev
X-CSRF-Token: oTpCTAKvWui1gsp3itVdZOu9F2BQxU55N323S51BWJ0
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: sqlmap/1.0-dev-abbd352 (http://sqlmap.org)
Connection: close

[14:35:19] [INFO] heuristics detected web page charset 'ascii'
[14:35:19] [TRAFFIC IN] HTTP response [#1] (200 OK):
Content-length: 170
Set-cookie: PHPSESSID=1f45b44924edc6ec8375a58a57e03c9d; path=/
<snip>
Content-type: text/plain

Hv6eT8LnbJtGV_cJ8RKHy3Y98qBX-0GBSjkhQNrVuko
[14:35:19] [TRAFFIC OUT] HTTP request [#2]:
GET /sqlmap/mysql/get_int.php?id=1 HTTP/1.1
Host: debiandev
X-CSRF-Token: Hv6eT8LnbJtGV_cJ8RKHy3Y98qBX-0GBSjkhQNrVuko
Accept-encoding: gzip,deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-agent: sqlmap/1.0-dev-abbd352 (http://sqlmap.org)
Cookie: PHPSESSID=1f45b44924edc6ec8375a58a57e03c9d
Connection: close

...

p.s. basically, in those kind of cases (with X-CSRF-Token header value) CSRF protection token is given in raw text/plain form by visiting a special page (e.g. ...services/session/token)

@stormwin
Copy link

@stamparm nice... i will test this at the weekend.

just to sum up:

server can set up csrf token in:

  1. HTML Forms
  2. Cookie
  3. Headers (haven't seen this yet, but it is possible i think)
    *some applications randomizing value of csrf token on every request, and some, occasionally (for example on every 5 minutes)

server can expect request from user with csrf token in:

  1. URL
  2. In POST Data
  3. In Header

@stamparm
Copy link
Member

@stormwin I am still in need for a page utilizing CSRF tokens through Cookie. sqlmap still doesn't support this.

@codewatchorg
Copy link

The latest CSRF updates break sqlmapapi as sqlmap appears to expect the csrfUrl option to be set. When it isn't set then sqlmapapi errors out with a log that the csrfUrl option is missing (this is one that isn't auto set by the API).

It's not a big deal as the work around is to manually set the config option with /option//set.

stamparm added a commit that referenced this issue Nov 17, 2014
@stamparm
Copy link
Member

@codewatchorg thank you for your report. It should be fixed with the latest revision

bf30075 pushed a commit to bf30075/sqlmap that referenced this issue Nov 17, 2014
@bdamele bdamele added normal and removed low labels Feb 13, 2015
@pich4ya
Copy link

pich4ya commented Mar 14, 2015

How about CSRF token in either javascript code

<script>
window.csrf = 'aaaabbbbcccc';
</script>

or in JSON format

{"csrf":"bf4676dc51856f01"}

and how about CSRF token which required POST data?
I request the option to extract token using supplied user regex

@stamparm
Copy link
Member

@pich4ya those would be non-standard (custom) CSRF protection methods. In those kind of cases you would need to run either Burp or similar tool.

I can make that "regex", but how to know (as it's non-standard), where the end point expects the token to appear? If the answer is "make the option for that too", I'll need to deny as it would become one of those options/switches that nobody uses

@bdamele bdamele modified the milestones: 1.0, 1.1 May 16, 2016
@nu11secur1ty
Copy link

--csrf-url="https://www.blabal.com/tarator/kokazako/?page=8" --csrf-token="token"

;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants