TL;DR: Instagram contained two distinct vulnerabilities that allowed an attacker to brute-force passwords of user accounts. Combined with user enumeration, a weak password policy, no 2FA nor other mitigating security controls, this could have allowed an attacker to compromise many accounts without any user interaction, including high-profile ones. Facebook fixed both issues and awarded a combined bounty of $5.000.
- May 29, 2018 - Here we will introduce top 6 Instagram password cracker to deal with this. Simply download the hackinstagram.net software and you could.
- Download now Instagram Hack Tool v3.7.2 that can hack any account and find every password you want. Get Instagram Hack Tool v3.7.2 for free right now.
- Grids for Instagram Windows Grids brings the best Instagram experience to your Windows, with Stories (Grids for Instagram is the first and only app that supports stories!), Direct Message and Large/Fullscreen photo and video viewing.now with the ability to upload and repost photos.
Hack Instagram Password by using our service and get access to any Instagram account. Confidentiality, Anonymity and 100% guarantee to hack your chosen target. Instagram for windows pc free download - Windows Virtual PC (64-bit), Free PC Bible, PC Optimizer, and many more programs.
Authentication brute-force vulnerabilities are very serious issues for any web application. Users are known to pick weak passwords and reuse them and manydictionaries with millions of human-chosen passwords are publicly available to attackers to easily mount successful attacks. However, there are some additional arguments that make brute-force particularly effective against Instagram:
- User Enumeration: Instagram usernames are public & enumerable via incrementaluserIDs.
- Weak Password Policy: At the time of submission, the Instagram password policy only enforced a minimum length of 6 characters, allowing choices such as “123456” and “password”.
- Two-Factor Authentication: 2FA has only been introduced in February 2016, and is still not rolled out globally.
- Account Lockout Policy: No account lockout policy is currently in place, nor any other mitigating security controls.
Therefore, exploitation of these issues could have resulted in the compromise of millions of the 400+ million active Instagram accounts – especially those with predictable passwords. Of course, targeted attacks against high-profile (Celebrity) accounts could have been very effective as well (cf. Apple’s Celebgate).
Out of Scope: In order to identify the Mobile Authentication endpoint communication in an intercepting proxy, SSL Pinning had to be bypassed in the Instagram for Android application. Additionally, in order to modify & attack this endpoint communication, a key had to be phished from the Android application, which is used to generate a HMACSHA256 signature over the POST parameters of every outgoing request. A Burp Plugin was written that transparently hotpatches the signature for outgoing requests generated, such as those generated by the Burp Intruder module – see below. More details can be found in this previous blogpost.
The Instagram for Android application used the endpoint at https://i.instagram.com/api/v1/accounts/login/ to perform authentication. A simple brute-force attack against this mobile authentication endpoint with Burp Intruder revealed that approximately 1000 reliable guesses could be made from one unique IP address, after which the response changed to “username not found”, although the user obviously still existed (Rate limiting):
However, only the next consecutive 1000 guesses resulted in the “username not found” response error message. From the 2000th consecutive guess onward, a reliable response (password correct/incorrect) was followed by an unreliable one (user not found):
This allowed a reliable brute-force attack, since an attacker could reason on the reliable response messages and simply replay the unreliable ones until a reliable answer was received. The only limitation of this attack was that on average, 2 authentication requests had to be made for one reliable password guess attempt. A quick & dirty python script with basic threading support “InstaBrutal.py” was made to prove this. The output of a brute-force attack of 10000 popular passwords against my Instagram test account “bruteforceme” with password “perfectcrime” can be seen here:
InstaBrutal.py 10k brute-force against Instagram user
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 | hoes hevnm4 epson eeeee1 perfectcrime # python instabrutal.py [INFO]Usage:python instabrutal.py<INSTAGRAM_USERNAME><DICTIONARY_FILENAME><THREADS>[DEBUG] # python instabrutal.py bruteforceme 10k_most_common.txt 50 [INFO]Total# passwords: 10001 147.20pw/s[=]7%(736/10001)(Good:686Bad:0Error:0) 105.00pw/s[]10%(1050/10001)(Good:1000Bad:272Error:0) 70.00pw/s[]10%(1050/10001)(Good:1000Bad:706Error:0) 55.00pw/s[]10%(1100/10001)(Good:1050Bad:1028Error:0) 50.84pw/s[]12%(1271/10001)(Good:1221Bad:1218Error:0) 50.60pw/s[]15%(1518/10001)(Good:1468Bad:1453Error:0) 49.94pw/s[]17%(1748/10001)(Good:1698Bad:1696Error:0) 49.50pw/s[]19%(1980/10001)(Good:1930Bad:1913Error:0) 48.56pw/s[]21%(2185/10001)(Good:2135Bad:2132Error:0) 48.18pw/s[]24%(2409/10001)(Good:2359Bad:2353Error:0) 48.20pw/s[]26%(2651/10001)(Good:2601Bad:2593Error:0) 48.02pw/s[]28%(2881/10001)(Good:2831Bad:2825Error:0) 46.57pw/s[]30%(3027/10001)(Good:2977Bad:2973Error:0) 46.96pw/s[]32%(3287/10001)(Good:3237Bad:3234Error:0) 46.72pw/s[]35%(3504/10001)(Good:3466Bad:3427Error:0) 46.38pw/s[]37%(3710/10001)(Good:3660Bad:3658Error:0) 46.61pw/s[]39%(3962/10001)(Good:3912Bad:3910Error:0) 46.58pw/s[]41%(4192/10001)(Good:4142Bad:4130Error:0) 45.88pw/s[]43%(4359/10001)(Good:4309Bad:4303Error:0) 46.25pw/s[]46%(4625/10001)(Good:4575Bad:4573Error:0) 46.47pw/s[]48%(4879/10001)(Good:4829Bad:4823Error:0) 45.84pw/s[]50%(5042/10001)(Good:4992Bad:4990Error:0) 45.95pw/s[]52%(5284/10001)(Good:5234Bad:5229Error:0) 45.93pw/s[]55%(5512/10001)(Good:5462Bad:5455Error:0) 45.97pw/s[]57%(5746/10001)(Good:5696Bad:5693Error:0) 45.55pw/s[]59%(5921/10001)(Good:5871Bad:5870Error:0) 45.70pw/s[]61%(6169/10001)(Good:6119Bad:6115Error:0) 45.84pw/s[]64%(6418/10001)(Good:6368Bad:6355Error:0) 45.86pw/s[]66%(6649/10001)(Good:6599Bad:6594Error:0) 45.81pw/s[]68%(6872/10001)(Good:6822Bad:6812Error:0) 45.32pw/s[]70%(7025/10001)(Good:6975Bad:6973Error:0) 45.63pw/s[]73%(7301/10001)(Good:7251Bad:7247Error:0) 45.63pw/s[]75%(7529/10001)(Good:7479Bad:7463Error:0) 45.56pw/s[]77%(7746/10001)(Good:7696Bad:7680Error:0) 45.17pw/s[]79%(7905/10001)(Good:7855Bad:7839Error:0) 45.54pw/s[]81%(8197/10001)(Good:8147Bad:8134Error:0) 45.36pw/s[]83%(8392/10001)(Good:8342Bad:8342Error:0) 45.26pw/s[]85%(8599/10001)(Good:8549Bad:8547Error:0) 45.43pw/s[]88%(8858/10001)(Good:8807Bad:8801Error:0) 45.49pw/s[]90%(9098/10001)(Good:9047Bad:9037Error:0) 45.31pw/s[]92%(9289/10001)(Good:9238Bad:9224Error:0) 45.24pw/s[]95%(9501/10001)(Good:9450Bad:9441Error:0) 45.41pw/s[]97%(9763/10001)(Good:9712Bad:9711Error:0) 45.37pw/s[]99%(9982/10001)(Good:9931Bad:9924Error:0) 44.45pw/s[]100%(10001/10001)(Good:9999Bad:9992Error:0) |
Notice that the first 1000 guesses were reliable (“good”) guesses, followed by 1000 unreliable ones (“bad”), which were ignored by the python script. Hereafter, the ratio remained closely around 50%. The numbers are slightly off due to lack of thread locks around the global variables storing them, as the purpose of the quick & dirty script was to simply prove the underlying vulnerability.
Although the script made 10001 password guesses for account “bruteforceme”, an attacker could simply login from any IP address, including the one that was used to mount the brute-force attack. This indicated a lack of additional security controls against account compromise, such as account lockout, IP address location-based fraud detection, …
Since a couple of months, Instagram allows registration via its website as opposed to only via its mobile applications. Registering a test account “arneswinnen8168” with password “passwd” issued the following underlying request & response:
However, by simply replaying this exact request, a different response message was now encountered:
After removing all parameters in the request except “username” and “password”, the replay of a request with a correct password value and one of an incorrect password value highlights the credentials oracle:
Finally, a burp intruder brute-force attack of 10001 passwords, with the 10001th entry being the correct password “passwd”, confirmed the trivial brute-force attack:
Logging in with the harvested credentials again worked, no account lockout or other security controls were triggered during the successful brute-force attack:
- Issue #1 was resolved by fixing the rate-limiting bug in the mobile authentication endpoint.
- Issue #2 was resolved by introducing rate-limiting on the web registration endpoint.
- The password policy was slightly hardened, and extremely easy passwords such as “123456” and “password” are now not allowed anymore.
- 28/12/2015: Submitted bug report for issue #1 to Facebook Bug Bounty, including PoC python script.
- 08/02/2016: Submitted bug report for issue #2 to Facebook Bug Bounty.
- 11/02/2016: Facebook confirmed that issue #2 is patched.
- 13/02/2016: Facebook confirmed that issue #1 was patched earlier as well and granted a combined bounty of $5.000.
- 04/04/2016: Informed Facebook that fix for issue #2 is not effective.
- 10/05/2016: Facebook reconfirmed new fix for issue #2.
- 19/05/2016: New fix deemed working, public disclosure.
Arne Swinnen
Belgian. IT Security. Bug Bounty Hunter.
TL;DR: Instagram contained two distinct vulnerabilities that allowed an attacker to brute-force passwords of user accounts. Combined with user enumeration, a weak password policy, no 2FA nor other mitigating security controls, this could have allowed an attacker to compromise many accounts without any user interaction, including high-profile ones. Facebook fixed both issues and awarded a combined bounty of $5.000.
Authentication brute-force vulnerabilities are very serious issues for any web application. Users are known to pick weak passwords and reuse them and manydictionaries with millions of human-chosen passwords are publicly available to attackers to easily mount successful attacks. However, there are some additional arguments that make brute-force particularly effective against Instagram:
- User Enumeration: Instagram usernames are public & enumerable via incrementaluserIDs.
- Weak Password Policy: At the time of submission, the Instagram password policy only enforced a minimum length of 6 characters, allowing choices such as “123456” and “password”.
- Two-Factor Authentication: 2FA has only been introduced in February 2016, and is still not rolled out globally.
- Account Lockout Policy: No account lockout policy is currently in place, nor any other mitigating security controls.
Therefore, exploitation of these issues could have resulted in the compromise of millions of the 400+ million active Instagram accounts – especially those with predictable passwords. Of course, targeted attacks against high-profile (Celebrity) accounts could have been very effective as well (cf. Apple’s Celebgate).
Instagram For Windows 10
Out of Scope: In order to identify the Mobile Authentication endpoint communication in an intercepting proxy, SSL Pinning had to be bypassed in the Instagram for Android application. Additionally, in order to modify & attack this endpoint communication, a key had to be phished from the Android application, which is used to generate a HMACSHA256 signature over the POST parameters of every outgoing request. A Burp Plugin was written that transparently hotpatches the signature for outgoing requests generated, such as those generated by the Burp Intruder module – see below. More details can be found in this previous blogpost.
The Instagram for Android application used the endpoint at https://i.instagram.com/api/v1/accounts/login/ to perform authentication. A simple brute-force attack against this mobile authentication endpoint with Burp Intruder revealed that approximately 1000 reliable guesses could be made from one unique IP address, after which the response changed to “username not found”, although the user obviously still existed (Rate limiting):
However, only the next consecutive 1000 guesses resulted in the “username not found” response error message. From the 2000th consecutive guess onward, a reliable response (password correct/incorrect) was followed by an unreliable one (user not found):
This allowed a reliable brute-force attack, since an attacker could reason on the reliable response messages and simply replay the unreliable ones until a reliable answer was received. The only limitation of this attack was that on average, 2 authentication requests had to be made for one reliable password guess attempt. A quick & dirty python script with basic threading support “InstaBrutal.py” was made to prove this. The output of a brute-force attack of 10000 popular passwords against my Instagram test account “bruteforceme” with password “perfectcrime” can be seen here:
InstaBrutal.py 10k brute-force against Instagram user
2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 | hoes hevnm4 epson eeeee1 perfectcrime # python instabrutal.py [INFO]Usage:python instabrutal.py<INSTAGRAM_USERNAME><DICTIONARY_FILENAME><THREADS>[DEBUG] # python instabrutal.py bruteforceme 10k_most_common.txt 50 [INFO]Total# passwords: 10001 147.20pw/s[=]7%(736/10001)(Good:686Bad:0Error:0) 105.00pw/s[]10%(1050/10001)(Good:1000Bad:272Error:0) 70.00pw/s[]10%(1050/10001)(Good:1000Bad:706Error:0) 55.00pw/s[]10%(1100/10001)(Good:1050Bad:1028Error:0) 50.84pw/s[]12%(1271/10001)(Good:1221Bad:1218Error:0) 50.60pw/s[]15%(1518/10001)(Good:1468Bad:1453Error:0) 49.94pw/s[]17%(1748/10001)(Good:1698Bad:1696Error:0) 49.50pw/s[]19%(1980/10001)(Good:1930Bad:1913Error:0) 48.56pw/s[]21%(2185/10001)(Good:2135Bad:2132Error:0) 48.18pw/s[]24%(2409/10001)(Good:2359Bad:2353Error:0) 48.20pw/s[]26%(2651/10001)(Good:2601Bad:2593Error:0) 48.02pw/s[]28%(2881/10001)(Good:2831Bad:2825Error:0) 46.57pw/s[]30%(3027/10001)(Good:2977Bad:2973Error:0) 46.96pw/s[]32%(3287/10001)(Good:3237Bad:3234Error:0) 46.72pw/s[]35%(3504/10001)(Good:3466Bad:3427Error:0) 46.38pw/s[]37%(3710/10001)(Good:3660Bad:3658Error:0) 46.61pw/s[]39%(3962/10001)(Good:3912Bad:3910Error:0) 46.58pw/s[]41%(4192/10001)(Good:4142Bad:4130Error:0) 45.88pw/s[]43%(4359/10001)(Good:4309Bad:4303Error:0) 46.25pw/s[]46%(4625/10001)(Good:4575Bad:4573Error:0) 46.47pw/s[]48%(4879/10001)(Good:4829Bad:4823Error:0) 45.84pw/s[]50%(5042/10001)(Good:4992Bad:4990Error:0) 45.95pw/s[]52%(5284/10001)(Good:5234Bad:5229Error:0) 45.93pw/s[]55%(5512/10001)(Good:5462Bad:5455Error:0) 45.97pw/s[]57%(5746/10001)(Good:5696Bad:5693Error:0) 45.55pw/s[]59%(5921/10001)(Good:5871Bad:5870Error:0) 45.70pw/s[]61%(6169/10001)(Good:6119Bad:6115Error:0) 45.84pw/s[]64%(6418/10001)(Good:6368Bad:6355Error:0) 45.86pw/s[]66%(6649/10001)(Good:6599Bad:6594Error:0) 45.81pw/s[]68%(6872/10001)(Good:6822Bad:6812Error:0) 45.32pw/s[]70%(7025/10001)(Good:6975Bad:6973Error:0) 45.63pw/s[]73%(7301/10001)(Good:7251Bad:7247Error:0) 45.63pw/s[]75%(7529/10001)(Good:7479Bad:7463Error:0) 45.56pw/s[]77%(7746/10001)(Good:7696Bad:7680Error:0) 45.17pw/s[]79%(7905/10001)(Good:7855Bad:7839Error:0) 45.54pw/s[]81%(8197/10001)(Good:8147Bad:8134Error:0) 45.36pw/s[]83%(8392/10001)(Good:8342Bad:8342Error:0) 45.26pw/s[]85%(8599/10001)(Good:8549Bad:8547Error:0) 45.43pw/s[]88%(8858/10001)(Good:8807Bad:8801Error:0) 45.49pw/s[]90%(9098/10001)(Good:9047Bad:9037Error:0) 45.31pw/s[]92%(9289/10001)(Good:9238Bad:9224Error:0) 45.24pw/s[]95%(9501/10001)(Good:9450Bad:9441Error:0) 45.41pw/s[]97%(9763/10001)(Good:9712Bad:9711Error:0) 45.37pw/s[]99%(9982/10001)(Good:9931Bad:9924Error:0) 44.45pw/s[]100%(10001/10001)(Good:9999Bad:9992Error:0) |
Instagram Password Cracker No Download
Notice that the first 1000 guesses were reliable (“good”) guesses, followed by 1000 unreliable ones (“bad”), which were ignored by the python script. Hereafter, the ratio remained closely around 50%. The numbers are slightly off due to lack of thread locks around the global variables storing them, as the purpose of the quick & dirty script was to simply prove the underlying vulnerability.
Although the script made 10001 password guesses for account “bruteforceme”, an attacker could simply login from any IP address, including the one that was used to mount the brute-force attack. This indicated a lack of additional security controls against account compromise, such as account lockout, IP address location-based fraud detection, …
Since a couple of months, Instagram allows registration via its website as opposed to only via its mobile applications. Registering a test account “arneswinnen8168” with password “passwd” issued the following underlying request & response:
However, by simply replaying this exact request, a different response message was now encountered:
After removing all parameters in the request except “username” and “password”, the replay of a request with a correct password value and one of an incorrect password value highlights the credentials oracle:
Finally, a burp intruder brute-force attack of 10001 passwords, with the 10001th entry being the correct password “passwd”, confirmed the trivial brute-force attack: Corellaser software download.
Logging in with the harvested credentials again worked, no account lockout or other security controls were triggered during the successful brute-force attack:
Instagram For Windows Pc
- Issue #1 was resolved by fixing the rate-limiting bug in the mobile authentication endpoint.
- Issue #2 was resolved by introducing rate-limiting on the web registration endpoint.
- The password policy was slightly hardened, and extremely easy passwords such as “123456” and “password” are now not allowed anymore.
- 28/12/2015: Submitted bug report for issue #1 to Facebook Bug Bounty, including PoC python script.
- 08/02/2016: Submitted bug report for issue #2 to Facebook Bug Bounty.
- 11/02/2016: Facebook confirmed that issue #2 is patched.
- 13/02/2016: Facebook confirmed that issue #1 was patched earlier as well and granted a combined bounty of $5.000.
- 04/04/2016: Informed Facebook that fix for issue #2 is not effective.
- 10/05/2016: Facebook reconfirmed new fix for issue #2.
- 19/05/2016: New fix deemed working, public disclosure.
Arne Swinnen
Belgian. IT Security. Bug Bounty Hunter.