Jsonp has been very popular lately, but it’s really been rotten, but it has never been taken seriously. Just last month, I dug a CSRF from a community in Sina caused by jsonp, to prepare an article, and then the article would be shared.
Because Sina has fixed the problem, I will share it first. The following is a part of the article that was written at that time.
I heard that sina sent clothes in May, and I didn’t have much time to dig holes. Originally, I wanted to hand in a CSRF brush that I dug two years ago. It turned out that the hole had already disappeared and the target station was changed.
In detail, it was my 302 jump to Sina stock (http://guba.sina.com.cn/).
Recently, the stock market is very hot. How many people have become rich in the stock market? So I simply opened the burpsuite in the stock bar and found an interesting CSRF.
Sina micro-blog played a lot of students to know that Sina’s defense strategy for CSRF vulnerabilities is to check Referer, but the stock bar post here is not, a rare check is token.
If you want to grab a POST packet with normal posting, we can see that it contains _csrf_token field. After a simple FUZZ discovery, this request does not check Referer, so long as _csrf_token is correct, you can post.
So, how to get _csrf_token, I have the following train of thought:
- See if there is a jsonp that leaks token at this site
- Stealing source code through flash
Why do I have these ideas? First, getting the token must be a cross domain process, and the cross domain is usually CORS, postMessage, and jsonp, where CORS and postMessage do not exist, then I go to the jsonp.
flashThe idea should have been around for a long time. At this time last year, /fd had already mentioned this in drops: http://drops.wooyun.org/tips/2031
But there is a very important condition in law 2 that we need to find a point that can control the content of the output, such as uploading, jsonp, etc., but in fact, this position is not easy to find. It is not as simple as the first one.
0x02 jsonpSell your _csrf_token
Then, follow your own ideas to test it.
I first modified _csrf_token into a random string and sent it back to retrieve such a result.
The returned packet is a JSON format string containing a _csrf_token. Sending this packet many times, I find that this token changes every time.
Then I can guess that the token of stock bar is a dynamic generation. It should be stored in session. Every check will generate a new one.
But here is the return value in JSON format, not jsonp.
So I added “& callback=hehehe” in the GET parameter to try:
It is obvious that the format of the return has changed. Though not jsonp, it is a < script>.
Why is the callback=hehehe changed? This should be a development habit, and usually there are two formats of JSON and jsonp when the design of the API is developed, and the variable name for the function name of the jsonp is usually callback.
Here is < script> or there is no cross domain, parent.hehehe executes the hehehe function in the parent framework, but the parent framework (10.211.55.3) and guba.sina.com.cn are still different domains, chromeThe mistake will burst out.
Try to change the HTTP method to GET:
Surprise, the way a change gets jsonp.
Then, if I use this _csrf_token in jsonp to test whether I can post successfully,
The tragedy is, no…
So I have two conjectures
- _csrf_tokenRelated to the HTTP method, the GET method only hurts the token obtained by the GET method, and POST uses token of POST.
- _csrf_tokenUnlike “Ba ID”, different ID corresponds to different token. The reason is that many reasons for returning error have been referred to as “lack of parameters: bar ID or bar name”.
The first guess is negated by my programmer’s intuition. I have never seen such a program written.
I tried second conjectures, adding & to the URL of the GET packet; bid=9947, sending the packet again:
It’s still in jsonp format. I sent the token to the post packet to send:
A jsonp sold the _csrf_token completely.
0x03 Constructing POC to publish any post
So I started writing POC to finish the steps I just finished manually. The following ideas are as follows:
- jsonpGet token
- Construction of POST form submission
First build a simple code to get token:
The results are as follows:
Token has been obtained.
At this time, the token is embedded in the form to submit:
<form action=“http://guba.sina.com.cn/api/?s=Thread&a=safe_post” method=“POST” id=“csrfsend”>
<input type=“hidden” name=“bid” value=“9947”>
<input type=“hidden” name=“tid” value=“”>
<input type=“hidden” name=“content” value=“This is the result of the test. “>
<input type=“hidden” name=“title” value=“This is the test title “>
<input type=“hidden” id=“token” name=“_csrf_token” value=“”>
<input type=“hidden” name=“anonymous” value=“1”>
var csrf_token = obj[“result”][“data”][“_csrf_token”];
document.getElementById(“token”).value = csrf_token;
The above code is saved as sinacsrf.html and can be triggered by any user visit. A new post is published in block 9947:
As shown in the picture, it has been published:
This is a typical CSRF vulnerability, which is to steal the token through jsonp to bypass the check of the back end.
The post can also be added to the link, seducing other users to click, click on the access to post again, resulting in a CSRF worm.