How to make Global Payments even worse



  • In short: McAfee.

    In medium: McAfee Secure Web Mail

    In long:

    Our one client who uses the horrific payment provider Global Payments took so long to do anything on their end, that their account lapsed. So they had to go through the whole approval and setup process again. Which meant they had to get us new developer credentials and store ID.

    I finally got the email today saying that my user ID and password were ready. All I had to do was follow the link in the email provided, and enter my userid and password to retrieve my SUPA SEKUR EMAILZ!

    Need userid and password to get... uhg, fine, okay, I'll just go and hit the password reset link on whatever stupid email page they have.  Follow the link and BAM first thing Monday morning and I just got McAfee'd. The email page takes 30 seconds to load, and it's just a shitty-looking page mostly consisting of stock photos and a single "floating" div. We couldn't actually program the page in 1995 Flash, so let's just make it look like we did:

    Fine, fine fine-- I'll just fucking hit the nice big RESET button there. It does a postback and-- I need to put in my correct password into order to reset my password... 😞

    At least that's what I assume the red squiggle "missing field" line means. It's not like there any error messages anywhere.

    My fucking Monday morning.

    Oh, even more fun. Despite all this SUPER SECURE EMAILS!!!!! being so super secure and not transmitting any sensitive information in plaintext-- I noticed right at the bottom of the original email there's a "Forgot your password?" link.

    If I click it, it takes me to a Forgot your Password page, with my email address pre-filled. Because my email address is in an ID field in the querystring. And it's just Base64 encoded. No salting. No GUID that'll map to my email address server side. Just a might-as-well-be-plaintext Base64 encoded string.

    And this is the company our client wants to entrust their financials to. 😞



  • I wonder if that forgot your password thing is vulnerable to XSS.



  • @slipstream said:

    I wonder if that forgot your password thing is vulnerable to XSS.
     

    Have fun.

    https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=INSERT BASE64 STRING HERE&vip=0



  • @Lorne Kates said:

    @slipstream said:

    I wonder if that forgot your password thing is vulnerable to XSS.
     

    Have fun.

    https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=INSERT BASE64 STRING HERE&vip=0

     

    Even better!  If you change the string to by a Base64 encoded email address, it looks like you'll either get one of two results.

    1) A temporary password has been sent...

    2) Invalid user.

    Which means you can test for valid usernames AND arbitrarily lock people out of their accounts. It doesn't say "a link to reset your password has been sent". It says, in translation "We've reset your password and emailed it to you in plaintext. Your old password is no longer valid. Let's hope you didn't have any mission critical functions set up to use it, since anyone can just throw a monkey wrench into those gears. lol fuck you."

     



  • Well, let's hope this doesn't get on the internet.

    O wait...



  • @Lorne Kates said:

    @Lorne Kates said:

    @slipstream said:

    I wonder if that forgot your password thing is vulnerable to XSS.
     

    Have fun.

    https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=INSERT BASE64 STRING HERE&vip=0

     

    Even better!  If you change the string to by a Base64 encoded email address, it looks like you'll either get one of two results.

    1) A temporary password has been sent...

    2) Invalid user.

    Which means you can test for valid usernames AND arbitrarily lock people out of their accounts. It doesn't say "a link to reset your password has been sent". It says, in translation "We've reset your password and emailed it to you in plaintext. Your old password is no longer valid. Let's hope you didn't have any mission critical functions set up to use it, since anyone can just throw a monkey wrench into those gears. lol fuck you."

     

    What's the base 64 for 'OR1=1;-- eh? 😉

     


  • Winner of the 2016 Presidential Election

    @Lorne Kates said:

    Which means you can test for valid usernames AND arbitrarily lock people out of their accounts. It doesn't say "a link to reset your password has been sent". It says, in translation "We've reset your password and emailed it to you in plaintext. Your old password is no longer valid. Let's hope you didn't have any mission critical functions set up to use it, since anyone can just throw a monkey wrench into those gears. lol fuck you."

    I considered this scenario, and I use something similar to this schema [from memory]:
    UserID int not null identity( 1, 1 ) primary key,
    Username varchar(30) not null unique,
    PasswordHash varbinary(60) not null,
    PasswordSalt varbinary(60) not null,
    TemporaryPasswordHash varbinary(60) null,
    TemporaryPasswordSalt varbinary(60) null,
    TemporaryPasswordExpires datetime null,
    check ( ( TemporaryPasswordHash is null and TemporaryPasswordSalt is null and TemporaryPasswordExpires is null ) or ( TemporaryPasswordHash is not null and TemporaryPasswordSalt is not null and TemporaryPasswordExpires is not null ) )

    So, if you forget your password, a temporary password is emailed to you, but your old one remains valid if you never finish the process. If you log in with the temporary password before it expires, you are forced to set a new password (which clears the temporary one). If someone else tries to reset your password, just disregard the password reset email.

    The check constraint just makes sure you set all three temporary fields or none of them.



  • @TGV said:

    Well, let's hope this doesn't get on the internet.

    O wait...

     

     I'll give you one more (Python). Choose an appropriate length and characters and you're done: 

    import urllib
    gen = itertools.combinations_with_replacement(characters,password_length) 
    for password in gen:
    urllib.urlopen('https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=' + password + '&vip=0 ')
     

     

     



  • @fire2k said:

    @TGV said:

    Well, let's hope this doesn't get on the internet.

    O wait...

     

     I'll give you one more (Python). Choose an appropriate length and characters and you're done: 

    import urllib
    gen = itertools.combinations_with_replacement(characters,password_length) 
    for password in gen:
    urllib.urlopen('https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=' + password + '&vip=0 ')
     

    I am intrigued by your notion of a password reset link that requires knowledge of the password.

    You do know the difference between a password and an email address, right? 




  • @DaveK said:

    @fire2k said:

    @TGV said:

    Well, let's hope this doesn't get on the internet.

    O wait...

     

     I'll give you one more (Python). Choose an appropriate length and characters and you're done: 

    import urllib
    gen = itertools.combinations_with_replacement(characters,password_length) 
    for password in gen:
    urllib.urlopen('https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=' + password + '&vip=0 ')
     

    I am intrigued by your notion of a password reset link that requires knowledge of the password.

    You do know the difference between a password and an email address, right? 



    "my email address is qjejfhri2$5jso5&2kJFJ@4kfiI%JskRK"


  • Discourse touched me in a no-no place

    @Ben L. said:

    "my email address is qjejfhri2$5jso5&2kJFJ@4kfiI%JskRK"
    "That's amazing! That's the same email address as my luggage!"



  • @DaveK said:

    @fire2k said:

    @TGV said:

    Well, let's hope this doesn't get on the internet.

    O wait...

     

     I'll give you one more (Python). Choose an appropriate length and characters and you're done: 

    import urllib
    gen = itertools.combinations_with_replacement(characters,password_length) 
    for password in gen:
    urllib.urlopen('https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=' + password + '&vip=0 ')
     

    I am intrigued by your notion of a password reset link that requires knowledge of the password.

    You do know the difference between a password and an email address, right? 


     

    import urllib
    gen = itertools.combinations_with_replacement(characters,length) 
    for id in gen:
    urllib.urlopen('https://swd.globalpay.com/swm/login.do?method=forgotPasswd&push=true&id=' + id + '&vip=0 ')
    FTFY 

     


Log in to reply
 

Looks like your connection to What the Daily WTF? was lost, please wait while we try to reconnect.