看雪论坛
发新帖
1

[原创]Sina登录破解[Go语言]

灵雀 2017-3-15 00:29 2065

      最近做了一个小破解,仅是练习Go语言之用,不作为其他商业用途,若有不妥欢迎大家指正...


     Sina登录的大致流程如下:

     1、Client发送一个登录请求:http://my.sina.com.cn/profile/unlogin

     2、Server响应请求,返回Set_Cookies字段要求Client设置下次请求的cookies(ps:这步我忽略了,实则不该省去)

     3、Client请求:

          http://login.sina.com.cn/sso/prelogin.php?

          entry=account&callback=pluginSSOController.preloginCallBack&su=base64用户名 

          &rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_= 请求时间戳(我有偷懒省去了) 

     4、Server响应请求,返回一些关键参数servertime、nonce、pubkey、rsakv、account,这些参数是下面发送POST

          请求需要用到的重要参数

     5、根据 pubkey 给 passwd 加密,之后作为一个 sp 字段放在POST包中发送给Server

     6、Client发送POST数据包

     7、Server影响Client,返回一个数据包,retcode标志是否成功,若成功,retcode = 0,若失败,retcode = 非零值


   

   一、登录sina账号链接:http://my.sina.com.cn/profile/unlogin

         由于我省去了cookies设置,所以此处就不放WireShark抓包的图了...


   二、开始登录-->登录界面

         


   三、登录过程,使用截获数据包软件WireShark/BurpSuite,认证成功POST包内容如下:

         

      可以很容易的得出,发送POST包的地址: http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)&_=

      这里是个时间戳,也可以省略,它的效果图是:

              

          解析关键参数:

          1)su : base64加密的用户名

          2)sp : 经过服务器返回的公钥(后面提到)加密的密码

          3)servertime :请求时间戳

          4)nonce : 计算加密密码时候使用

          5)rsakv :其实我也不知道是嘛

          6)sr :当前使用机器分辨率,这里根据自己的机器分辨率修改就可以了

      

        其中,servertime、nonce、rsakv可以从服务器返回,从分析截获数据包可知请求的地址,先上个数据包截图:

       =========>>>请求包 WireShark抓包内容如下:

         

       =========>>>对应的Wireshark抓到的响应包如下:

         

      

        

          得出请求地址:

          http://login.sina.com.cn/sso/prelogin.php?

          entry=account&callback=pluginSSOController.preloginCallBack&su=base64用户名  

          &rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=      

          上图中Pubkey是比较重要的,是用于加密密码的公钥


    四、下面就是 填充POST包里的参数,发送POST包验证了,没有圈出的POST包参数是固定的,那么最重要的是获取

            servertime、nonce、pubkey、rsakv、account,填充到POST包中的su、sp、servertime、nonce、rsakv 

           111.获取参数 servertime、nonce、pubkey、rsakv 源代码

           1)首先是计算su(PS:请求链接需要这个参数)     

           看一下,网页自带js[ssologin.js]用户名 su 加密的代码截图:

              

   

       Golang中这样实现:===============================================

               func encryptUname(uname string) string {  // 获取username base64加密后的结果
	             urlEncode := url.QueryEscape(uname)  // html转义uname
	             return base64.StdEncoding.EncodeToString([]byte(urlEncode))
               }

     2)抓取网页内容 

         //url的取值为
         // url = http://login.sina.com.cn/sso/prelogin.php? 
         //entry=account&callback=pluginSSOController.preloginCallBack&su=base64用户名 
         //&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=
         
         // proxy_addr = "" 这里赋值为空即可
         func fetch(url, proxy_addr *string) (html string, oHeader http.Header) {
	       client := &http.Client{}
	       req, err := http.NewRequest("GET", *url, nil)
	       if err != nil {
	         	log.Fatal(err.Error())
	       }
	       resp, err := client.Do(req)
	       if err != nil {
		        log.Fatal(err.Error())
	      }
	      oHeader = resp.Header
	      if resp.StatusCode == 200 {
		     robots, err := ioutil.ReadAll(resp.Body)
		     resp.Body.Close()
		     if err != nil {
			 log.Fatal(err.Error())
	             }
	            
	             html = string(robots)
	      }else {
		
		     html = ""
	      }
	      return
          }


     222.填充POST包,发送给服务器

       1)上述过程中已经成功获取servertime、nonce、pubkey、rsakv 重要参数了

       2)计算加密密码

   

       看一下,网页自带js密码 sp 加密的代码:

          

       

     下面是Golang中实现计算密码RSA加密的代码:

 

          //把字符串转换bigint
           func string2big(s string) *big.Int {
	        ret := new(big.Int)
	        ret.SetString(s, 16)  // 将字符串转换成16进制
	        return ret
           }
           
           
           //加密密码
           func encryptPassword(context urljson, password string) string {
	        pub := rsa.PublicKey{
	         	N: string2big(context.Key),
	        	E: 65537,                       // 65537 是上述图片的 10001 的16进制形式
	        }
	   
                // servertime、nonce之间加\t,然后在\n ,和password拼接 
	        encryString := strconv.Itoa(context.Stime) + "\t" + context.Noce + "\n" + password
	   
                // 拼接字符串加密
	         encryResult, _ := rsa.EncryptPKCS1v15(rand.Reader, &pub, []byte(encryString))
	         return hex.EncodeToString(encryResult)
           }


  333.发送POST包 Golang代码

    

      resp, _ := client.PostForm("http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)&_=",
      url.Values{
		      "entry":       {"account"},      //固定值
		      "gateway":     {"1"},            //固定值
		      "from":        {},  
		      "savestate":   {"30"},           //固定值     
		      "qrcode_flag": {"true"},         //固定值
		      "useticket":   {"0"},            //固定值
		      "pagerefer":   {},
		      "vsnf":        {"1"},            //固定值
		      "su":          {ssu},            // rsa公钥加密后的密码 =======
		      "service":     {"sso"},          //固定值
		      "servertime":  {sertime},        //============= 服务器返回值
		      "nonce":       {content.Noce},   //============= 服务器返回值
		      "pwencode":    {"rsa2"},         //固定值
		      "rsakv":       {content.Kv},     //============= 服务器返回值  
		      "sp":          {ssp},            // base64加密后的username =====
		      "sr":          {"1395*822"},     //屏幕分辨率
		      "encoding":    {"UTF-8"},        //固定值
		      "cdult":       {"3"},            //固定值
		      "domain":      {"sina.com.cn"},  //固定值 
		      "prelt":       {"48"},           //下面有解释
		      "returntype":  {"TEXT"},         //固定值 
	     })
	     
	      b, _ := ioutil.ReadAll(resp.Body)
	      fmt.Println(string(b))	
	    
	    }

  

      解析:"prelt":这个值可以随机构造,js计算代码 

      preloginTime = (new Date()).getTime() - preloginTimeStart - (parseInt(result.exectime, 10) || 0)

      然后将preloginTime 赋值给prelt  


     最后对比一下抓包返回验证通过的 和 程序实现返回结果 验证效果图:

     1)服务器返回表示

         

 

      2)Golang程序实现的返回结果

         


      可以看到 retcode 也是 0,代表成功,若失败 retcode为非零值,还会有一串字符提示 reason



      小结:主要sina登录流程并不复杂,主要是对于passwd的计算要花点时间,passwd的加密过程就是:

          11)处理pubkey,处理方式在ssologin.js中可以分析得出

          22)servertime、nonce之间加\t,然后在\n ,和password拼接

          33)使用处理过的秘钥 对 拼接后的字符串加密

          加密流程可以通过调用它自带的ssologin.js文件实现,感觉有点麻烦,不如自己写出来呢,还有一点值得

          注意的是,POST包填充的顺序不能有错,数据包按照WireShark中抓到的包格式构造就OK了


      自我的学习心得,写出来给大家共享一下,若有疏漏之处,请大家不吝赐教,多谢...





   


最新回复 (24)
1
灵雀 2017-3-15 00:32
2

 我这排版有点丑...

xietao 2017-3-15 09:23
3
返回的是混淆过的JS怎么办?
1
灵雀 2017-3-15 13:15
4
xietao 返回的是混淆过的JS怎么办?
你说的是哪个地方的返回?
xietao 2017-3-15 13:40
5
灵雀 你说的是哪个地方的返回?
之前用node.js抓一个页面, 返回的是混效过的js跳转代码
1
灵雀 2017-3-15 18:15
6
那你可以百度"js反混淆",解析一下再看
19
仙果 2017-3-15 20:23
7
楼主可以改下排版就会清爽很多的
1
灵雀 2017-3-15 22:36
8

仙果 楼主可以改下排版就会清爽很多的

嗯嗯,我再改改,谢谢

chinacoold 2017-3-16 23:08
9
写的真好
1
灵雀 2017-3-17 18:53
10
chinacoold 写的真好
谢谢夸奖
Crakme 2017-3-17 19:10
11
这个得精华我表示不服怎么办
1
灵雀 2017-3-18 14:49
12
Crakme 这个得精华我表示不服怎么办[em_13]
4
我是土匪 2017-3-19 16:10
13
要换工作的话可以联系我哦
anhuiyuhu 2017-3-19 19:01
14
顶顶更健康
1
灵雀 2017-3-19 21:31
15
anhuiyuhu 顶顶更健康
嘿嘿,谢谢你帮我顶贴,向大神看齐
halou 2017-3-20 12:13
16
棋牌辅助透视联系我603580196 重谢
zhuangbx 2017-3-20 20:38
17
谢谢分享,很好,很详细
1
灵雀 2017-3-20 23:18
18
zhuangbx 谢谢分享,很好,很详细[em_1]
大神太客气了,大家一起学习
marsboys 2017-3-21 08:34
19
长知识了
1
灵雀 2017-3-21 09:02
20
marsboys 长知识了
1
杨剑超 2017-3-21 14:07
21
我是来看Go的
kxkris 2017-3-21 15:30
22
LZ,你的微博ID不打码是想求关注么
1
灵雀 2017-3-21 22:52
23
kxkris LZ,你的微博ID不打码是想求关注么[em_19]
那个是测试用的
1
灵雀 2017-3-21 22:52
24
杨剑超 我是来看Go的
共同学习一下撒
pealcock 2017-3-25 21:48
25
这说明新浪还是明文存储用户口令
返回



©2000-2017 看雪学院 | Based on Xiuno BBS | 知道创宇带宽支持 | 微信公众号:ikanxue
Time: 0.011, SQL: 8 / 京ICP备10040895号-17