java获取的NTLM电脑用户名并解码(python解码)

java的NTLM电脑用户名解码(python解码)

getMi(传入密文)

得到一个前部分乱码,后部分电脑用户名的字符串

getcode(传入字节码)

得到一个前部分乱码,后部分电脑用户名的字符串

NTLMSSP中文解决思路

因后面需要自己补码和加码的一些的问题,思路仅限参考,最终的成品文件是encode.py文件,调用此文件就可以了

英文是正常显示的,中文则显示的乱码,得到base64编码后的数据是这样的

英文

NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00\x98\x00\x00\x008\x008\x00\xb0\x00\x00\x00\x1e\x00\x1e\x00X\x00\x00\x00\x04\x00\x04\x00v\x00\x00\x00\x1e\x00\x1e\x00z\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x05\x82\x00\x02\n\x00cE\x00\x00\x00\x0fOA\x02\x05\xec\xbd\xddB&V\x99;\xdc\x0f\x11qD\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00D\x002\x00G\x00O\x003\x00J\x00N\x00'Y\xed\x94D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00D\x002\x00G\x00O\x003\x00J\x00N\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x8d\x1f\xf4<\xb4\xa2\x1fv\x1a\xfe\xf1%3\x94=\xab\x01\x01\x00\x00\x00\x00\x00\x00K\xa4\xcd?\xb2=\xd7\x01TU\x9a[\xac\xf0\xbdO\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

通过二进制软件显示的内容如下:

发现是中间的用户名正常显示的,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C9iPzwSi-1620471671015)(C:/Users/admin/Desktop/个人解决问题集/编码问题/编码问题/1.png)]

中文

NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00\x84\x00\x00\x008\x008\x00\x9c\x00\x00\x00\x14\x00\x14\x00X\x00\x00\x00\x04\x00\x04\x00l\x00\x00\x00\x14\x00\x14\x00p\x00\x00\x00\x00\x00\x00\x00\xd4\x00\x00\x00\x05\x82\x00\x02\n\x00cE\x00\x00\x00\x0f\x9e\xed$-Y\xe29\x90\x98\xc1(\xf3\xa7iR1D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00Km\xd5\x8b'Y\xed\x94D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00Km\xd5\x8b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0C\xbdj\xa8\xae\xc5\x13\xf5\x86\x89\xea\x04\xa9Oh\x01\x01\x00\x00\x00\x00\x00\x00\x99X-\\\xb3=\xd7\x01\x92\xacw\x9a6RZ\x94\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00

通过二进制软件显示的内容如下:

中文的内容发现全是变成乱码了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UpDEA6II-1620471671022)(C:/Users/admin/Desktop/个人解决问题集/编码问题/编码问题/2.png)]

分析

在得知我们的汉字内容为‘测试’的时候,对其文字进行ascii的编码获取

得到

测 ascii码:27979,十六进制:6D4B

试 ascii码:35797,十六进制:8BD5

因为我们获取的时候是将进制转换为ascii码来打印输出的,所以我不能直接在ascii吗上找问题,得分析乱码这部分的进制,

已知用户名DESKTOP-测试

根据上图右侧的数据显示,在-后面的两个汉字都变成乱码了,-的ASCII码是2D

所以根据2D的的位置。我们找到有四个,前面一个和最后一个一看就不是,因为显示的内容没有DESKTOP相关的内容,所以我们就只获取后面两个的值

2D 00 4B 6D D5 8B两个2D后面的值都是一样的,看到这个,就觉得与上面有一丝相似的感觉,拉下来对比一下

测 ascii码:27979,十六进制:6D4B

试 ascii码:35797,十六进制:8BD5

突然发现,原来乱码的原因是因为那个解析的时候,把汉字的进制反向写入的

所以,我们要将这一部分的内容恢复到他原来的顺序

python实现

#获取的内容是字节类型的,需要手动转字符串类型,我这里是直接存放的字符串
q2 = "NTLMSSP\x00\x03\x00\x00\x00\x18\x00\x18\x00\x84\x00\x00\x008\x008\x00\x9c\x00\x00\x00\x14\x00\x14\x00X\x00\x00\x00\x04\x00\x04\x00l\x00\x00\x00\x14\x00\x14\x00p\x00\x00\x00\x00\x00\x00\x00\xd4\x00\x00\x00\x05\x82\x00\x02\n\x00cE\x00\x00\x00\x0f\x9e\xed$-Y\xe29\x90\x98\xc1(\xf3\xa7iR1D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00Km\xd5\x8b'Y\xed\x94D\x00E\x00S\x00K\x00T\x00O\x00P\x00-\x00Km\xd5\x8b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0C\xbdj\xa8\xae\xc5\x13\xf5\x86\x89\xea\x04\xa9Oh\x01\x01\x00\x00\x00\x00\x00\x00\x99X-\\\xb3=\xd7\x01\x92\xacw\x9a6RZ\x94\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
#定义一个函数
def getname(w):
	#初始化一个空字符串,为后面拼接做准备
    name = ''
    #计算传入进来的乱码长度
    mx = len(w)
    #根据传入进来的乱码进行一个0-乱码长度的反向遍历
    for i in range(0,len(w)):
        #因为汉字的编码是占4个字节,转成16进制的话,就占2位了,所以我们需要每隔两个进行处理
        if i %2 ==0:
            #函数内容分解在下面
            name += chr(int(hex(ord(w[mx-i-1])).replace('0x','')+hex(ord(w[mx-i-2])).replace('0x',''),16))
	#对汉字进行反转
    name = name[::-1]
    return  name
#因为用户名有两个,我们只需要取一个就可以了,因为汉字编码不确定,所以我们只能暂时通过`Y这个减号来定位汉字的初始头部,尾部的话,因为是16进制和这个特殊的编码格式,导致后面有很长的一段000,所以下面我只需要定位这两个中间的值就可以了,findall返回的是一个数组[0]是取第一个返回成功的值及我们匹配到的内容
w2 = re.findall('\'Y(.*)\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',q2,re.S)[0]
#得到 í”D E S K T O P - KmÕ‹            
#split 进行切片,[0]得到是D E S K T O P,[1]得到乱码 KmÕ‹
des = w2.split('-')
#[0]的内容是正常的,所以我们不需要管它,将我们的[1]这个乱码的传入这个getname函数内
print(des[0]+'-'+getname(des[1]))

chr(int(hex(ord(w[mx-i-1])).replace('0x','')+hex(ord(w[mx-i-2])).replace('0x',''),16))

分解:

des[1]):首页我们得到是一串\x00Km\xd5\x8b字符串,这里有四个ascii编码转换失败的乱码

然后for循环对每个乱码进行循环

ord是python内置的函数,将汉字/字母,转成ascii编码

ord(w[mx-i-1]),ord(w[mx-i-2])#第一组 ascii 139 213
ord(w[mx-i-1]),ord(w[mx-i-2])#第二组 ascii 109 75

接下来,我们将这两组ascii码,转16进制

ord(hex(ord(w[mx-i-1])),hex(ord(w[mx-i-2])))#第一组 ascii 0x8b 0xd5
ord(hex(ord(w[mx-i-1])),hex(ord(w[mx-i-2])))#第二组 ascii 0x6d 0x4b

转换成16进制后,发现带有0x的标识符,所以我们进行

.replace('0x','')进行替换

得到 8b d56d 4b

我们得到是16进制了,但是内容是由两个16进制组合起来的10进制,我们要进行拼接

所以接下来,我们对其拼接,并转成10进制,

代码如下

#两个内容相加,得到8BD5  和6D4B
hex(ord(w[mx-i-1])).replace('0x','')+hex(ord(w[mx-i-2])).replace('0x','')
#然后对8BD5  和6D4B在进行转成10进制,得到35797和27979
int(hex(ord(w[mx-i-1])).replace('0x','')+hex(ord(w[mx-i-2])).replace('0x',''),16)

对得到的两个ascii编码进行转换

chr是将数字转换成字符串

chr(int(hex(ord(w[mx-i-1])).replace('0x','')+hex(ord(w[mx-i-2])).replace('0x',''),16))

我们遍历后得到的是试测

所以后面进行字符串反转name = name[::-1]

最后进行拼接

print(des[0]+'-'+getname(des[1]))
#得到í”D E S K T O P - 测试

完整代码

import sys
#传入排序错误的乱码

def getname(w):
    #定义的一个空字符串对象,将传入进去后的编码进行组合,为了后面查看编码的顺序
    text = ''
    # w = w.replace()
    #定义一个空字符串,将编码后的汉字进行拼接
    name = ''
    # 计算传进来的长度
    mx = len(w)
    #从0遍历到字符串长度
    for i in range(0,len(w)):
        #每隔两位数进行操作
        if i %2 ==0:
            #[mx-i-1] mx是字符串最大长度,最大长度减去当前当前i遍历的值然后-1,因为len会获取整个字符串的个数,但是for遍历是从0开始,所以-1就是当前元素
            #ord-函数=》传入当前字符串,得到当前字符串的acsii码-10进制
            #hex-内置函数=》将10进制转16进制(默认)
            #int-内置函数=》传入对象,返回一个int 10进制数字对象 ,16是指定传入的对象是16进制的

            #判断是等于20,20是一个空值,要去掉,因为汉字4个字节,字母是2个字节,解码的时候,默认都是按4个字节来解码的,字母缺失的字节,按20补位补上来了
            #判断第一位数
            if hex(ord(w[mx-i-1])).replace('0x','') == '20':
                name += chr(
                    int(hex(ord(w[mx - i - 2])).replace('0x', ''), 16))
                text += str(hex(ord(w[mx - i - 1])) + hex(ord(w[mx - i - 2])))
            # 判断第二位数
            elif hex(ord(w[mx-i-2])).replace('0x','') == '20':
                name += chr(
                    int(hex(ord(w[mx - i - 1])).replace('0x', ''), 16))
                text += str(hex(ord(w[mx - i - 1])) + hex(ord(w[mx - i - 2])))
            # 判断第二位数,是否小于10,小于10的话,默认会把0给省略调,所以就得把0补上去
            elif ord(w[mx - i - 2]) < 10:
                name += chr(int(hex(ord(w[mx - i - 1])).replace('0x', '') + '0'+hex(ord(w[mx - i - 2])).replace('0x', ''),16))
                text += str(hex(ord(w[mx - i - 1])) + '0'+hex(ord(w[mx - i - 2])))
            elif (int(hex(ord(w[mx-i-2])).replace('0x',''),16)<15)&(int(hex(ord(w[mx-i-2])).replace('0x',''),16)>0):
                name += chr(
                    int(hex(ord(w[mx - i - 1])).replace('0x', '') + '0'+hex(ord(w[mx - i - 2])).replace('0x', ''), 16))
                text += str(hex(ord(w[mx - i - 1])) + hex(ord(w[mx - i - 2])))
            #没有条件的话就默认把2个都转了
            else:
                name += chr(int(hex(ord(w[mx-i-1])).replace('0x','')+hex(ord(w[mx-i-2])).replace('0x',''),16))
                
                text += str(hex(ord(w[mx - i - 1])) + hex(ord(w[mx - i - 2])))
    #字符串反转
    name = name[::-1]
    #text 是16字节码,需要的话可以查看
    return  name
def getcode(q1):
    code = ''
    code2 = ''
    len_q = len(q1)
    for q in range(1,len_q):
        if q %2 ==0:
            if int(q1[len_q-q]) < 0:
                n1 = abs(int(q1[len_q-q]))
                n2 = abs(int(q1[len_q-q-1]))
                n3 = 256-n1-n2
                q1[len_q - q] = n1+int(n3/2)
                q1[len_q - q-1] = int(q1[len_q - q]+(n3/2))
                code += chr(abs(int(q1[len_q - q ])))
                code += chr(abs(int(q1[len_q - q - 1])))
                code2 += hex(abs(int(q1[len_q - q])))
                code2 += hex(abs(int(q1[len_q - q - 1])))
                # print(q1[len_q - q], q, q1[len_q - q - 1])
            elif int(q1[len_q-q-1]) < 0:
                n1 = abs(int(q1[len_q - q]))
                n2 = abs(int(q1[len_q - q - 1]))
                n3 = 256 - n1 - n2
                q1[len_q - q - 1] = n1 + n3
                code += chr(abs(int(q1[len_q - q])))
                code += chr(abs(int(q1[len_q - q - 1])))
                code2 += hex(abs(int(q1[len_q - q ])))
                code2 += hex(abs(int(q1[len_q - q - 1])))
            elif (int(q1[len_q - q - 1])<=15)&(int(q1[len_q - q - 1])>9)&(len(hex(int(q1[len_q - q - 1])).replace('0x',''))<2):
                code += chr(abs(int(q1[len_q - q])))
                code += chr(int('0x0'+hex(abs(int(q1[len_q - q - 1]))).replace('0x',''),16))
                code2 += hex(abs(int(q1[len_q - q])))
                code2 += hex(abs(int(q1[len_q - q - 1])))
                print('1'*50,'0x0'+hex(abs(int(q1[len_q - q - 1]))).replace('0x',''))
                pass
            else:
                code += chr(abs(int(q1[len_q - q])))
                code += chr(abs(int(q1[len_q - q - 1])))
                code2 += hex(abs(int(q1[len_q - q])))
                code2 += hex(abs(int(q1[len_q - q - 1])))
        code2 += hex(abs(int(q1[len_q - q - 1])))
    print(code2)
    code = code[::-1]

    return getname(code)
#命令行启动-传入字节码
#取第一个参数
# arg = sys.argv[1]
# print(getcode(arg))

#字节码
getcode('78,84,76,77,83,83,80,0,3,0,0,0,1,0,1,0,104,0,0,0,0,0,0,0,105,0,0,0,0,0,0,0,88,0,0,0,0,0,0,0,88,0,0,0,16,0,16,0,88,0,0,0,0,0,0,0,105,0,0,0,5,-118,0,2,10,0,97,74,0,0,0,15,-94,-87,-79,113,-78,-21,-75,125,-40,25,119,-11,80,42,34,92,-95,-117,-105,123,58,103,45,0,13,84,87,91,48,0,49,0,0')
#密文
import base64
def getMi(w22):
    w22 = base64.decodebytes(w22)
    ntext = ''
    for i in w22:
        ntext += chr(i)
    if len(ntext.split('\n')[-1][0:-1]) % 2 != 0:
        return getname('\n' + ntext.split('\n')[-1][0:-1])
    else:
        return getname(ntext.split('\n')[-1][0:-1])
#调用
# print(getMi(b'TlRMTVNTUAADAAAAAQABAGAAAAAAAAAAYQAAAAAAAABYAAAAAAAAAFgAAAAIAAgAWAAAAAAAAABhAAAABYoAAgoAukcAAAAPsCGyvOTFLBSCTN+ut0SfXABO9V8pWQJYAA=='))

最后尾部的就是字符串,前面一段带有乱码是因为这个密文里面带有电脑用户名、登录用户名、密码等,电脑虽然是明文的,

---------------结尾---------------
第一次写文章,有些地方写的不好的,希望大佬们轻点喷,谢谢

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值