Python 3 reads passwords in sqlyog configuration files

What is the purpose of this person?

I have more or less heard some safety circle bulls say similar ideas, to the effect that they can scan configuration files of various programs and services (such as SVN files, RSYNC configuration files, etc.).
Find sensitive information from it, and then find the breakthrough of intrusion. Along the same lines, administrators use a variety of management tools (SSH,FTP,mysql and so on).
Such tools usually have passwords locally, and if the configuration information in these tools is read by malicious scans, it may cause extremely significant losses.
So I want to try to verify that the sensitive information of various management tools is easy to read and decode. Second, in the process of thinking, there will be a variety of data and hands-on practice, which can well practice and review programming skills.

Based on the idea that there are always people who want to be ashamed, I would rather that the operating system or security software can provide more sophisticated rights control. After all, whether Baidu or 360 or Xunlei's whole bucket, the bottom line of software of these companies is relatively low.
If these or other software do not have access to our sensitive data, we will be more assured.

sqlyog is a very good commercial open source mysql management tool.

After installing sqlyog, the configuration file will be stored in the user directory:

C:\Users\%user%\AppData\Roaming\SQLyog\sqlyog.ini
Take the environment variable% AppData%+on SQLyogsqlyog.ini.

The following is the sqlyog.ini file fragment:

[UserInterface]
Language=zh-cn
Version=2
ThemeFile=963
ThemeType=1
[Themedetails]
ThemeFile=964
ThemeType=1
[SQLYOG]
Encoding=utf8
Left=0
Top=0
Right=600
Bottom=600
Maximize=0
Host=new connection
ChildMaximized=1
[Connection 1]
Name=new connection
Host=localhost
User=root
StorePassword=1
Password=sLBzS1h0309zR9IxMQ==
Port=3306
Database=
......

The "==" sign is the most obvious feature of base64 encoding. Generally speaking, when you see characters like sLBzS1h0309zR9IxMQ===, you know base64.
The encoding process of sqlyog is to carry out bitwise operations on the bytes of the password, and then base 64 encoding exists in the configuration file.
Another thing to note is that python bit s move left and carry, so it needs to be 255.

Give an example:

>>> 2<<10
2048
>>> 2<<10&255
0
Python 3 reads the password in sqlyog.ini:
# -*- coding: utf-8 -*-
"""
Created on 2017-03-15 07:42:58

@author: codegay
"""

import os
import configparser
import base64


def decode(base64str):
    tmp = base64.b64decode(base64str)
    return bytearray([(b<<1&255)|(b>>7) for b in tmp]).decode("utf8")

sqlyogini = os.environ.get('APPDATA')+"\\SQLyog\\sqlyog.ini"
print("sqlyogini File path:",sqlyogini)
ini = configparser.ConfigParser()
ini.read(sqlyogini,encoding='utf8')

connections = [r for r in ini.sections() if 'name' in ini.options(r) and ini.get(r,'password')]

for c in connections:
    name = ini.get(c,'name')
    host = ini.get(c,'host')
    user = ini.get(c,'user')
    b64pass = ini.get(c,'password')
    password = decode(b64pass)
    print(name,host,user,sep='\n')
    print('Password',password)
    print('----------------------------------------------------------------------------------')
After running the program, output:
Sqlyog INI file path: C: Users root AppData Roaming SQLyog sqlyog.ini
 new connection
localhost
root
 Password aa new connection bb

2017-4-8 21:55:53 codegay

Reference material:

Retrieve passwords stored in SQLyog https://dd9e.blogspot.jp/2014/05/retrieve-passwords-stored-in-sqlyog.html
sqlyog-decode-pwd https://github.com/gkralik/sqlyog-decode-pwd/blob/master/decode.py

The following is the function of encryption and decryption in sqlyog source code: https://github.com/webyog/sqlyog-community/blob/dc5840df35705e8b38058de862b6409135293c53/src/CommonHelper.cpp
Additionally, sqlyog's code feels pretty good.

DecodePassword(wyString &text)
{
    wyChar      pwd[512]={0}, pwdutf8[512] = {0};

    strcpy(pwdutf8, text.GetString());
    
    DecodeBase64(pwdutf8, pwd);
    RotateBitLeft((wyUChar*)pwd);
    strncpy(pwdutf8, pwd, 511);
    text.SetAs(pwdutf8);
    
    return wyTrue;
}


/*rotates bit right */
void
RotateBitRight(wyUChar *str)
{
    wyInt32     count;

    for(count = 0; str[count]; count++)
        str[count] = (((str[count])>>(1)) | ((str[count])<<(8 - (1))));

    return;
}

// We keep the name in encrypted form.
// so we do a bit rotation of 1 on the left before writing it into the registry.
void 
RotateBitLeft(wyUChar *str)
{
    wyInt32     count;

    for(count = 0; str[count]; count++)
        str[count] = (((str[count])<<(1)) | ((str[count])>>(8 - (1))));

    return;
}

wyBool
EncodePassword(wyString &text)
{
    wyChar *encode = NULL, pwdutf8[512] = {0};

    strcpy(pwdutf8, text.GetString());
    RotateBitRight((wyUChar*)pwdutf8); 
    EncodeBase64(pwdutf8, strlen(pwdutf8), &encode);
    strncpy(pwdutf8, encode, 511);

    text.SetAs(pwdutf8);
    
    if(encode)
        free(encode);

    return wyTrue;
}

Keywords: Python encoding MySQL github

Added by nightowl on Thu, 11 Jul 2019 23:05:03 +0300