`
|
|
Archive for the ‘Hacking’ Category
Monday, November 25th, 2013
Recently we started getting the following error on the Agile India Registration site:
error number: 35
error message: Unknown SSL protocol error in connection to our_payment_gateway:443 |
error number: 35
error message: Unknown SSL protocol error in connection to our_payment_gateway:443
This error occurs when we try to connect to our Payment Gateway using Curl on the server side (PHP.)
By looking at the error message, it occurred to me, that may be, we are not setting the correct SSL protocol, which is supported by our PG server.
Using SSL Lab’s Analyser, I figured out that our PG server only supports SSL Version 3 and TLS Version 1.
Typically, if we don’t specify the SSL version, Curl figures out the supported SSL version and uses that. However to force Curl to use SSL Version 3, I added the following:
curl_setopt($ch, CURLOPT_SSLVERSION, 3); |
curl_setopt($ch, CURLOPT_SSLVERSION, 3);
As expected, it did not make any difference.
The next thing that occurred to me, was may be, the server was picking up a wrong SSL certificate and that might be causing the problem. So I got the SSL certificates from my payment gateway and then starting passing the path to the certificates:
curl_setopt($ch, CURLOPT_CAPATH, PATH_TO_CERT_DIR); |
curl_setopt($ch, CURLOPT_CAPATH, PATH_TO_CERT_DIR);
Suddenly, it started working; however not always. Only about 50% of the time.
May be there was some timeout issue, so I added another curl option:
curl_setopt($ch, CURLOPT_TIMEOUT, 0); //Wait forever |
curl_setopt($ch, CURLOPT_TIMEOUT, 0); //Wait forever
And now it started working always. However, I noticed that it was very slow. Something was not right.
Then I started using the curl command line to test things. When I issued the following command:
curl -v https://my.pg.server
* About to connect() to my.pg.server port 443 (#0)
* Trying 2001:e48:44:4::d0... connected
* Connected to my.pg.server (2001:e48:44:4::d0) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSLv3, TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to my.pg.server:443
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to my.pg.server:443 |
curl -v https://my.pg.server
* About to connect() to my.pg.server port 443 (#0)
* Trying 2001:e48:44:4::d0... connected
* Connected to my.pg.server (2001:e48:44:4::d0) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSLv3, TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to my.pg.server:443
* Closing connection #0
curl: (35) Unknown SSL protocol error in connection to my.pg.server:443
I noticed that it was connecting on iPV6 address. I was not sure if our PG server supported iPV6.
Looking at Curl’s man pages, I saw an option to resolve the domain name to IPv4 address. When I tried:
curl -v -4 https://my.pg.server |
curl -v -4 https://my.pg.server
it worked!
* About to connect() to my.pg.server port 443 (#0)
* Trying 221.134.101.175... connected
* Connected to my.pg.server (221.134.101.175) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
* subject: C=IN; ST=Tamilnadu; L=Chennai; O=Name Private Limited;
OU=Name Private Limited; OU=Terms of use at www.verisign.com/rpa (c)05; CN=my.pg.server
* start date: 2013-08-14 00:00:00 GMT
* expire date: 2015-10-13 23:59:59 GMT
* subjectAltName: my.pg.server matched
* issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network;
OU=Terms of use at https://www.verisign.com/rpa (c)10;
CN=VeriSign Class 3 International Server CA - G3
* SSL certificate verify ok.
> GET / HTTP/1.1
... |
* About to connect() to my.pg.server port 443 (#0)
* Trying 221.134.101.175... connected
* Connected to my.pg.server (221.134.101.175) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
* subject: C=IN; ST=Tamilnadu; L=Chennai; O=Name Private Limited;
OU=Name Private Limited; OU=Terms of use at www.verisign.com/rpa (c)05; CN=my.pg.server
* start date: 2013-08-14 00:00:00 GMT
* expire date: 2015-10-13 23:59:59 GMT
* subjectAltName: my.pg.server matched
* issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network;
OU=Terms of use at https://www.verisign.com/rpa (c)10;
CN=VeriSign Class 3 International Server CA - G3
* SSL certificate verify ok.
> GET / HTTP/1.1
...
Long story short, it turns out that passing -4 or –ipv4 curl option, forces iPV4 usage and this solved the problem.
So I removed everything else and just added the following option and things are back to normal:
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); |
curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
Posted in Deployment, Hacking, Hosting, HTTP, Networking | 7 Comments »
Monday, September 30th, 2013
Today, my six year old and I did a little experiment to figure-out what is actually inside a laptop’s battery.
We took a dead battery from one of my Mac Book Pro and cracked it open.
Posted in Experiment, Hacking | No Comments »
Wednesday, July 17th, 2013
On my latest pet project, SlideShare Presentation Stack, I wanted to make an AJAX call to SlideShare.net to fetch all the details of the given slideshare user. One easy way to get this information is to request for the user’s RSS feed. However the RSS feed is only served as xml. And due to same-origin policy, I can’t make an AJAX call from my javascript to retrive the XML. I wish SlideShare support JSONP for fetching the user’s RSS feed. However they don’t. They do expose an API with rate limiting, but I wanted something simple. I found the following hack to work-around this issue:
<script type="text/javascript">
simpleAJAXLib = {
init: function () {
this.fetchJSON('http://www.slideshare.net/rss/user/nashjain');
},
fetchJSON: function (url) {
var root = 'https://query.yahooapis.com/v1/public/yql?q=';
var yql = 'select * from xml where url="' + url + '"';
var proxy_url = root + encodeURIComponent(yql) + '&format=json&diagnostics=false&callback=simpleAJAXLib.display';
document.getElementsByTagName('body')[0].appendChild(this.jsTag(proxy_url));
},
jsTag: function (url) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
return script;
},
display: function (results) {
// do the necessary stuff
document.getElementById('demo').innerHTML = "Result = " + (results.error ? "Internal Server Error!" : JSON.stringify(results.query.results));
}
}
</script> |
<script type="text/javascript">
simpleAJAXLib = {
init: function () {
this.fetchJSON('http://www.slideshare.net/rss/user/nashjain');
},
fetchJSON: function (url) {
var root = 'https://query.yahooapis.com/v1/public/yql?q=';
var yql = 'select * from xml where url="' + url + '"';
var proxy_url = root + encodeURIComponent(yql) + '&format=json&diagnostics=false&callback=simpleAJAXLib.display';
document.getElementsByTagName('body')[0].appendChild(this.jsTag(proxy_url));
},
jsTag: function (url) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
return script;
},
display: function (results) {
// do the necessary stuff
document.getElementById('demo').innerHTML = "Result = " + (results.error ? "Internal Server Error!" : JSON.stringify(results.query.results));
}
}
</script>
Trigger the AJAX call asynchronously by adding the following snippet where ever required:
<script type="text/javascript">
simpleAJAXLib.init();
</script> |
<script type="text/javascript">
simpleAJAXLib.init();
</script>
How does this actually work?
- First, I would recommend you read my previous blog which explains how to make JSONP AJAX calls without using any javascript framework or library.
- Once you understand that, the most important piece you need to understand is how we’ve used Yahoo! Query Language (YQL) as a proxy to retrieve your XML request to be served via JSONP.
- Use the following steps:
- Write a SQL statement like select * from xml where url=’your_xml_returning_url’ and URI encode it.
- Append your yql statement to YQL url – https://query.yahooapis.com/v1/public/yql?q=
- Finally specify the format as json (ex: format=json) and a callback function name, which will be invoked by the browser once the results are retrieved (ex: callback=simpleAJAXLib.display)
- In the callback function, you can access the xml data from this JSON object: query.results
Posted in Hacking, HTTP, JavaScript | 9 Comments »
Wednesday, July 17th, 2013
On my latest pet project, SlideShare Presentation Stack, I wanted to make an AJAX call to fetch data from another domain. However due to same-origin policy, I can’t make a simple AJAX call, I need to use JSONP. JQuery and bunch of other libraries provide a very convenient way of making JSONP calls. However to minimize the dependency of my javascript library, I did not want to use any javascript framework or library. Also I wanted the code to be supported by all browsers that supported javascript.
One option was to use XMLHttpRequest. But I wanted to explore if there was any other option, just then I discovered this totally interesting way of making JSONP AJAX call. Code below:
<script type="text/javascript">
simpleAJAXLib = {
init: function () {
this.fetchViaJSONP('your_url_goes_here');
},
fetchViaJSONP: function (url) {
url += '?format=jsonp&jsonp_callback=simpleAJAXLib.handleResponse';
document.getElementsByTagName('body')[0].appendChild(this.jsTag(url));
},
jsTag: function (url) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
return script;
},
handleResponse: function (results) {
// do the necessary stuff; for example
document.getElementById('demo').innerHTML = "Result = " + (results.error ? "Internal Server Error!" : results.response);
}
};
</script> |
<script type="text/javascript">
simpleAJAXLib = {
init: function () {
this.fetchViaJSONP('your_url_goes_here');
},
fetchViaJSONP: function (url) {
url += '?format=jsonp&jsonp_callback=simpleAJAXLib.handleResponse';
document.getElementsByTagName('body')[0].appendChild(this.jsTag(url));
},
jsTag: function (url) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', url);
return script;
},
handleResponse: function (results) {
// do the necessary stuff; for example
document.getElementById('demo').innerHTML = "Result = " + (results.error ? "Internal Server Error!" : results.response);
}
};
</script>
Trigger the AJAX call asynchronously by adding the following snippet where ever required:
<script type="text/javascript">
simpleAJAXLib.init();
</script> |
<script type="text/javascript">
simpleAJAXLib.init();
</script>
How does this actually work?
Its simple:
- Construct the AJAX URL (any URL that support JSONP) and then append the callback function name to it. (For ex: http://myajaxcall.com?callback=simpleAJAXLib.handleResponse.) Also don’t forget to mention JSONP as your format.
- Create a new javascript html tag and add this URL as the src of the javascript tag
- Append this new javascript tag to the body. This will cause the browser to invoke the URL
- On the server side: In addition to returning the data in the expected formart, wrap the data as a paramater to the actual backback function and return it with a javascript header. The browser would eval this returned javascript and hence your callback function would be invoked. See server side code example below:
$data = array("response"=>"your_data");
header('Content-Type: text/javascript');
echo $_GET['jsonp_callback'] ."(".json_encode($data).")"; |
$data = array("response"=>"your_data");
header('Content-Type: text/javascript');
echo $_GET['jsonp_callback'] ."(".json_encode($data).")";
P.S: Via this exercise, I actually understood how JSONP works.
If you want to call an API, which does not support JSONP, you might be interested in reading my other blog post on Fetching Cross Domain XML in JavaScript, which uses Yahoo Query Language (YQL) as a proxy to work around the same-origin-policy for xml documents.
Posted in Hacking, HTTP, JavaScript | 2 Comments »
Sunday, December 30th, 2012
Create the following AppleScript using the AppleScript Editor
on run argv
set the this_file to item 1 of argv
set the vertical_crop to 20
set the horizontal_crop to 30
tell application "Image Events"
launch
set this_image to open this_file
copy dimensions of this_image to {W, H}
crop this_image to dimensions {W - horizontal_crop, H - vertical_crop}
save this_image with icon
close this_image
end tell
end run |
on run argv
set the this_file to item 1 of argv
set the vertical_crop to 20
set the horizontal_crop to 30
tell application "Image Events"
launch
set this_image to open this_file
copy dimensions of this_image to {W, H}
crop this_image to dimensions {W - horizontal_crop, H - vertical_crop}
save this_image with icon
close this_image
end tell
end run
Compile and save the file as a script.
Now you are ready to run the script on your images:
naresh$ osascript crop_image.scpt /complete/path/to/image.ext |
naresh$ osascript crop_image.scpt /complete/path/to/image.ext
Results:
Before |
After |
|
|
Posted in Hacking, Tools | No Comments »
Wednesday, November 21st, 2012
Over the years, I bought many iPhones for family and friends from US. Only for the last 2 Years, Apple has been selling unlocked phones. Before that, for most phones, I had to figure out a way to jailbreak and carrier unlock the phone via Ultrasn0w.
For iPhone 3Gs, to carrier unlock your phone, I had to upgrade my phone’s baseband to 6.15.00 (iPad’s baseband) and then using Ultrasn0w I could use the phone with any service provider in India.
However for iPhone 4 with baseband 4.11.08, Ultrasn0w could not do the carrier unlock. Basically there was no way to upgrade/downgrade the baseband. I had given up hope and my daughter was happily using those iPhones as toys. Just then I came across BejingPhoneRepair’s IMEI Unlocking Steps. I was very skeptical that this would work. Paid $15 USD for 1 phone and it worked like a charm. I was able to unlock all my iPhone4’s.
Then I had this iPhone 3Gs, which I had jail broken and upgraded the baseband to 6.15.00. I wanted to upgrade that to iOS 6.0.1. So I thought I might as well use the same IMEI unlock. After I paid and followed the exact same steps I did for iPhone4, I realized there was an issue:
It refused to recognize the SIM card. Then I came across this article from Richard Ker of BeijingiPhoneRepair. This explains that iTunes does not let you activate your iPhone 3Gs with baseband 6.15.00 on iOS 6.
The solution they propose is to downgrade your baseband to 5.13.04 first. To downgrade your baseband you can get the original iPhone 3GS iOS 5.1.1 firmware and then using Redsn0w to flash the baseband. Since I already had iOS 6.0.1 installed on my phone, I kept getting the following error:
AppleBaseband: Could not find mux function error.
Tried downgrading my phone to iOS 5.1.1 using Redsn0w and iTunes, but no luck. Apple does not allow you to downgrade from iOS 6 to iOS 5. You need the SHSH blobs saved for iOS 5.1.1 to downgrade as Apple has stopped signing this firmware. Using Redsn0w I tried searching Cydia’s server to see if SHSH blobs were available. No luck. So I followed the following steps to fix the issue:
- Using Redsn0w (0.9.14b2 or above), I put my phone in DFU mode.
- During the restore process, iTunes verifies with Apple’s server if the device is allowed to install the specific version of firmware. To work around this issue, I appended the following line 74.208.105.171 gs.apple.com to my host file (/etc/hosts) to fool iTunes.
- Then using iTunes, restored iOS 4.1 (8B117) firmware on my phone. I usually download my firmwares from iClarified’s site.
- After Launching redsn0w. Under Extras > Select IPSW and select the original iOS 4.1 (8B117) firmware
- Did a controlled shutdown of my iPhone (“slide to power off”).
- Returned to the first screen and clicked ‘Jailbreak’.
- Checked the ‘Downgrade from iPad baseband’ checkbox and unchecked Cydia. Next.
- Redsn0w started the downgrade process and you finally I saw the ‘Flashing Baseband’ screen on my iPhone with the Pawnapple icon. DO NOT INTERRUPT your iPhone while baseband flashing is in progress. This steps takes a good 5-10 mins.
- When this was done, after rebooting my iPhone, the baseband was downgraded to 5.13.04.
- Then I connected my phone to iTunes once more and upgraded my firmware to iOS 6.0.1.
- Once the upgrade was done, I saw this screen on iTunes.
- Now my phone can connect to the local service provider.
Posted in Hacking, iPhone, Tips | 77 Comments »
Tuesday, February 28th, 2012
Last evening I checked into a very popular hotel in Bangalore. I was fascinated by the lavish suites and all the jazz.
Soon my fascination for the real world stopped and I wanted to get on to the internet. As soon as I tried to connect to the internet, I got the following error in my browser:
WTF? I don’t have that crap (IE) with me and would never want to install it either.
However I realized that I could trick the server, by setting my browser’s user agent to IE 7.
Just as I was celebrating my smartness, I hit the next roadblock:
Turns out that the 24Online service uses SSL v2 (Secure Sockets Layer 2.0), which of course was deprecated since the collapse of the roman empire.
I could not figure out how to enable this on safari or chrome. Suddenly I remembered, I could go to the about:config tab in Firefox and poke around there.
Tried filtering on security.*ssl2 and to my surprise found a config property called security.enable_ssl2. Tried turning it on. No luck!
Tried enabling the various encryption algorithms for the protocol/certificate:
Yahoo! I was able to move to the next hurdle.
Finally I saw Firefox warning me about accessing the site with a fake certificate. I added the certificate to the exception list and there it was, The WWW. Finally I was connect!
Posted in Hacking, Networking | No Comments »
|