上一篇博文实际演示了通过程序伪造请求实现的“机器点赞”,这片博文是另外一个演示,把欺骗对象换成了新浪新闻,伪造的请求也是一条新闻评论的点赞。相对来说,新浪新闻的系统就比较有意思一点。

先分析一下“点赞”的逻辑,新浪新闻评论点赞只有一次 HTTP Post,没发现 Token 的逻辑。下面两张图是一条新闻评论真人点赞的数据包,第一张图是请求,蓝框内标明了发送的数据,第二张图是服务器回应。

It's about the network
“点赞”请求
It's about the network
“点赞”回应

当按下“赞”时,客户端向一个地址 http://....news.sina.com.cn/cmnt/vote 发送 HTTP Post 请求,这个地址看上去比较通用,估计点赞都是这个地址。传输的数据如下,原始数据没有换行,下面的分行显示是方便分析。

"channel=kj
&newsid=comos-hmhafir4650580
&parent=5BC28E6B-6F93DE60-55B9D29A-86F-867
&format=js
&vote=1
&callback=function(a){}
&domain=sina.com.cn"

请求的地址比较通用,那么数据就会有比较详细的信息,以下是一些猜测 channel=kj:表示新闻板块,“kj”指科技新闻。 newsid=comos-hmhafir4650580:表示具体新闻。 parent=5BC28E6B-6F93DE60-55B9D29A-86F-867:和评论数据有关。

服务器回应的数据如下,原始数据也没有换行,这里排成代码的方式是方便分析。服务器回应之后点赞即结束,相对网易新闻来说,新浪新闻点赞的逻辑就简单很多,发个 HTTP Post 就完事。

var data={
    "result": {
        "status": {
            "msg": "", 
            "code": 0
        }, 
        "language": "ch", 
        "encoding": "gbk", 
        "content": "", 
        "user": {
            "nick": "", 
            "id": "0"
        }, 
        "time": "2018-10-14 13:07:29", "id": ""
    }
}

接下来编写脚本发送这个请求,实现机器“点赞”。这里我用了 Windows 的 PowerShell 脚本和 cURL,PowerShell 可以直接调用 .NET,是 Windows 系统天然的脚本。下面代码我删除了部分内容(用“…”代替)。

$comment_url = "http://....news.sina.com.cn/cmnt/vote"
$post_data = '"channel=kj&newsid=...&parent=...&format=js&vote=1..."'

$header_agent = '"User-Agent: Windows 12; x64; Chrome/72"'
$header_refer = '"Referer: http://....news.sina.com.cn/comment/skin/default.html?channel=kj&newsid=..."'

$curl_exe = "...\curl-7.61.1-win64\bin\curl.exe"

$vote_times = 0
$vote_max = 200

$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = "cmd"
$psi.CreateNoWindow = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardInput = $true
$psi.RedirectStandardOutput = $true

$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$process.Start()
$process.BeginOutputReadLine()

function requestVote() {
    $process.Refresh()
    $process.StandardInput.WriteLine($curl_exe + " --silent --header " + $header_agent + 
        " --header " + $header_refer + " --data " + $post_data + " " + $comment_url)
}

Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -Action {
    if($Event.SourceEventArgs.Data.StartsWith("var data") -and $Event.SourceEventArgs.Data.EndsWith("}")) {
        $vote_times++
        $line_progress = $vote_times.ToString() + ", " + $Event.SourceEventArgs.Data
        Write-Host $line_progress
        
        if ($vote_times -le $vote_max) {
            Start-Sleep -Seconds 1
            requestVote
        } else {
            $process.Close()
        }
    }
}

Write-Host `n
requestVote

上面的代码是调用 cURL 发送 HTTP Post,收到服务器回应后等 1 秒钟再发送下一次。这样就实现了循环“点赞”,当“点赞”次数超过设定次数时则停止。$header_agent 相关代码仅仅是为了制造一个假象,没有别的作用。

除了逻辑简单之外,新浪新闻点赞的反作弊策略也比较简单。服务器会判断 HTTP 头的 Referer 信息,数据包需要加入该信息($header_refer = '"Referer: http://....news.sina.com.cn/comment/skin/default.html?channel=kj&newsid=..."'),否则“点赞”失败,除此外没碰到别的错误。之前提到网易新闻要 60 秒才能点一次,而新浪新闻 1 秒点一次也可以,均为一个 IP。

It's about the network
机器“点赞”中
It's about the network
点赞前
It's about the network
点赞后

参考数据:新浪新闻(网站、新闻、评论均为“素材”,不代表本人观点)
本文代码仅供参考。