美文网首页
简书文章攻防记

简书文章攻防记

作者: xiangyue | 来源:发表于2021-01-06 16:31 被阅读0次

今天,由于找东西,突然链接跳到了简书,心想这么久都没登录过简书了,就来登录一下,看看有什么消息没,这一登不知道,一登吓一跳,我的简书竟然被人攻击了,产生了很多莫名的服务信息(由于简书审核,所以只能马赛克了)

攻击的服务信息.png

看了下这个文集,应该有一百来条的文章基本都是垃圾文章,本来想删文集来着,就在我下定决定按下的时候,突然萌生了一个想法,让程序来删除

看着这么多条服务信息,心里还是有一丝安慰的,竟然这么瞧得起我,于是心生一计,干脆写个程序来删除吧,一想到还能服务大众,越想就越觉得有意思,说干就干

  1. 由于是已经删除完了垃圾文章后,突然想写篇文章,所以上面的图都是程序删除完后,浏览器上仅有的原始信息了,所以下面的文章列表都是自己虚构的
  2. 由于我的整个文集都是垃圾文章,所以如果有人要尝试的话,一定要记得备份,备份,备份
  3. 可能会有人问,直接删除文集不就行了吗,哈哈,作为程序员,喜欢倒腾,就这么点爱好了
  4. 可以研究下调用删除文集的接口,应该和删除文章的差不多

获取被攻击的文集

当然咯,第一步要做的肯定就是需要将这些垃圾文章的列表拿到对吧,这样后面的操作才有意义,根据我这么多年敏锐的观察力,一眼就瞅到了对应的连接(说明简书的开发者还是比较有规范的,所以才这么好找,简书看到了记得给广告费)


垃圾文章列表获取.png

获取删除文章的连接

这个就更简单啦,随便在这个文集下面选择一个文章,然后进行删除,就能看出大概的规则了,结合上面获取的列表可以看出,简书删除文章的时候,其实就是将文章的id传输,拼装成一个url来进行删除的


删除文章.png

好了,以上获取和删除的逻辑我们现在都已经了解了,接下来就是用程序来实现了,想了想,很久都没有用go语言了,所以就决定临幸一下go语言(其实是因为简单)

程序获取攻击的文章

首先,我们需要对这个获取文章的url进行分析,看传递了什么参数,当然,经验老到的人肯定一眼都瞟出其中的端倪


Cookie的获取.png

en,用的是cookie,这就没啥了,接下来程序实现

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    http "net/http"
)
type Course []struct {
    ID int `json:"id"`
}

func main()  {

    client:=&http.Client{}
    cookie:="read_mode=day; default_font=font2; locale=zh-CN; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22176d642da4470a-086ef9f560f1e38-44586b-2073600-176d642da4513f%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%7D%2C%22%24device_id%22%3A%22…user=1; __yadk_uid=Y5sqV7tE8oQ3X7h8V2hNiJs9Q27Nvkk; Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1609912474; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1609914436; _m7e_session_core=96e43f62507e2f5f9ac1fb43ddbcb574; remember_user_token=W1s2Nzk5NjQ1XSwiJDJhJDExJGtSdnUzeldlbnhHeDYvb0RYb2xtSWUiLCIxNjA5OTEyNTEyLjkxMzA1ODgiXQ%3D%3D--a6f6577b77a8a6b9305392e4b5fa8e67716c2886; web_login_version=MTYwOTkxMjUxMg%3D%3D--30269124b31f829f8dc78c3e88183b3e9bc94172; _ga=GA1.2.306275077.1609912570; _gid=GA1.2.806692222.1609912570"


    url:="https://www.jianshu.com/author/notebooks/14164901/notes"
    req,err:=http.NewRequest("GET",url,nil)
    req.Header.Add("Cookie",cookie)
    //ua:="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:84.0) Gecko/20100101 Firefox/84.0"
    //req.Header.Add("User-Agent",ua)
    //req.Header.Add("If-None-Match","W/\"64d5260ebd8004b8d4007e68c8c9d0cc")
    //req.Header.Add("Referer","https://www.jianshu.com/writer")
    req.Header.Add("Accept","application/json")

    res,err:=client.Do(req)
    if err!=nil{
        fmt.Println("get url %s fail",url)
        return
    }

    var course Course
    c,err:=ioutil.ReadAll(res.Body)
    if err := json.Unmarshal(c, &course); err != nil {
        panic(err)
    }
    fmt.Println(course)
}

大概解读下:

  1. 因为请求需要携带cookie,所以直接使用http.Get就不行啦,需要自己来进行构建了,这里的cookie,需要获取浏览器中自己的cookie哦
  2. 这里需要注意的点,就是Header里面需要加Accept这个头,否则返回的状态码是406
  3. 为了方便展示呢,就把io流进行了转换,然后进行了输出,看看结果是不是对的
  4. 由于整个流程我们只需要id,所以就没有对其他字段进行转化,有兴趣的可以在Course里面自己添加即可

因为我总共就创建了两篇测试文章,刚刚为了给你们看删除的逻辑进行截图,所以,现在程序获取就只能获取到一个了,别问我为什么不多创建个,因为懒,哈哈,还有就是不想前面重新截图,看下程序的输出结果


只有一篇垃圾文章的id.png

和浏览器的结果比对一下


浏览器只剩一篇文章.png

嗯,和程序的结果一致,吾心甚慰,接下来就是终极大招,删除步骤的书写了

其实感觉简书做的还是勉强吧,比如我以为它会做csrf攻击之类的,结果没有,以为他要做ua之类的拦截的,还是没有,嗯,先这样吧,希望简书的开发者看到了不要喷我

程序删除攻击文章

既然文章的id都获取到了,那么删除文章,就只需要对连接进行拼装,然后发起一个post请求就可以了,所以基本上和get获取文章列表差不多,唯一需要注意的点呢,就是因为文章id是个数组,我们只需要写个循环进行调用接口,对吧,就这么简单

for _,val :=range course{
        fmt.Println("begin delete Title:", val.ID)
        titleUrl :="https://www.jianshu.com/author/notes/"+strconv.Itoa(val.ID)+"/soft_destroy"
        req,_:=http.NewRequest("POST",titleUrl,nil)
        req.Header.Add("Cookie",cookie)
        //ua:="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:84.0) Gecko/20100101 Firefox/84.0"
        //req.Header.Add("User-Agent",ua)
        //req.Header.Add("If-None-Match","W/\"64d5260ebd8004b8d4007e68c8c9d0cc")
        //req.Header.Add("Referer","https://www.jianshu.com/writer")
        req.Header.Add("Accept","application/json")
        res,_:=client.Do(req)
        defer res.Body.Close()
        buf := new(bytes.Buffer)
        buf.ReadFrom(res.Body)
        newStr := buf.String()
        fmt.Println("delete res:",newStr)
}

这里只是列举了删除片段,整个逻辑最后贴出

注意的点:

  1. 因为我们的标题id是个int类型,所以拼装的时候需要将其转换成string,然后进行拼接,
  2. 这里将删除请求的响应内容打印,看和浏览器的响应结果是否一致
  3. 较真的话,在删除的时候,可以考虑使用并发来进行删除文章,因为互不影响,可以提高效率
浏览器删除响应结果.png 程序删除响应结果.png

这么一看,跟我们在浏览器上面的响应结果一致,所以再去我们的文集看看还有没有垃圾文章

再次查看垃圾文集.png

可以看到,整个世界都清净了

完整代码

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    http "net/http"
    "strconv"
)
type Course []struct {
    ID int `json:"id"`
}

func main()  {

    client:=&http.Client{}
    cookie:="read_mode=day; default_font=font2; locale=zh-CN; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22176d642da4470a-086ef9f560f1e38-44586b-2073600-176d642da4513f%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%7D%2C%22%24device_id%22%3A%22…user=1; __yadk_uid=Y5sqV7tE8oQ3X7h8V2hNiJs9Q27Nvkk; Hm_lvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1609912474; Hm_lpvt_0c0e9d9b1e7d617b3e6842e85b9fb068=1609914436; _m7e_session_core=96e43f62507e2f5f9ac1fb43ddbcb574; remember_user_token=W1s2Nzk5NjQ1XSwiJDJhJDExJGtSdnUzeldlbnhHeDYvb0RYb2xtSWUiLCIxNjA5OTEyNTEyLjkxMzA1ODgiXQ%3D%3D--a6f6577b77a8a6b9305392e4b5fa8e67716c2886; web_login_version=MTYwOTkxMjUxMg%3D%3D--30269124b31f829f8dc78c3e88183b3e9bc94172; _ga=GA1.2.306275077.1609912570; _gid=GA1.2.806692222.1609912570"


    url:="https://www.jianshu.com/author/notebooks/14164901/notes"
    req,err:=http.NewRequest("GET",url,nil)
    req.Header.Add("Cookie",cookie)
    req.Header.Add("Accept","application/json")

    res,err:=client.Do(req)
    if err!=nil{
        fmt.Println("get url %s fail",url)
        return
    }

    var course Course
    c,err:=ioutil.ReadAll(res.Body)
    if err := json.Unmarshal(c, &course); err != nil {
        panic(err)
    }
    //fmt.Println(course)

    for _,val :=range course{
        fmt.Println("begin delete Title:", val.ID)
        titleUrl :="https://www.jianshu.com/author/notes/"+strconv.Itoa(val.ID)+"/soft_destroy"
        req,_:=http.NewRequest("POST",titleUrl,nil)
        req.Header.Add("Cookie",cookie)
        req.Header.Add("Accept","application/json")
        res,_:=client.Do(req)
        defer res.Body.Close()
        buf := new(bytes.Buffer)
        buf.ReadFrom(res.Body)
        newStr := buf.String()
        fmt.Println("delete res:",newStr)
    }
}

相关文章

  • 简书文章攻防记

    今天,由于找东西,突然链接跳到了简书,心想这么久都没登录过简书了,就来登录一下,看看有什么消息没,这一登不知道,一...

  • 为什么呲溜一下就是4年

    我记得才是不久前下载的简书,写写,记记。 后来,卸了,忘了什么原因 今天看到一篇好文章,源自简书 又重新下载下来 ...

  • 2022年 我选择从头开始

    今天打开简书,准备重新写文章,看到了简书消息:“今天是你加入简书的 5 周年,亲爱的简友竹子成长记:你于2016 ...

  • 自己的想法,玩简书的原因,和简书对我的帮助

    我第一次知道简书是从一篇公众号文章看到的,简书有很多优势,随时随地写写记记是最大的特点了,简书是我目前打开最多的a...

  • 简书=鸡汤?爬取今日看点数据:1916篇简书热门文章可视化

    一、前言 最近写得两篇关于简书的数据可视化文章:《简书推荐作者风云榜(爬取简书app数据)》、《我的简书一月记:数...

  • 简书文章被锁记

    这几天网络学习已经接近尾声,交了八月份作业就能毕业了。 为了很好的完成八月份大作业,我从上周四课程...

  • 持续中

    7月24 支付宝记步器失效,简书看不了发不的文章,

  • 我用PPT将「简书」推荐给你

    已经记不起什么时候在简书打开第一篇文章,也已经记不起什么时候在简书书写第一篇文章。 依稀记得这款APP,一直存在我...

  • 「碎语杂记」乘数被乘数同样重要

    昨天,从简书上看到一篇讨论简书币价格走势的文章,才记起简书币还有个币值的问题。 原先的简书挺简单,就是个可以随便记...

  • 2018W34,关键词:开拓、自律

    本周加入简书,得益于在诺禾培训时见到周先生的简书文章,决定在此为个小基地写些周记和随笔。周记是自律性的每周...

网友评论

      本文标题:简书文章攻防记

      本文链接:https://www.haomeiwen.com/subject/ddonoktx.html