├── .github ├── ISSUE_TEMPLATE │ └── apply-archive-link.yml └── workflows │ └── update-output.yaml ├── .gitignore ├── README.md ├── config.go ├── fetch.go ├── go.mod ├── go.sum ├── images ├── README │ └── image-20230804150510583.png ├── demo.v1.png └── logic.v1.png ├── input └── friends.json ├── main.go ├── output ├── friends.json └── friends.md ├── post.go ├── read.go ├── render.go ├── template └── template.md └── write.go /.github/ISSUE_TEMPLATE/apply-archive-link.yml: -------------------------------------------------------------------------------- 1 | name: 档案录入申请 2 | description: 将个人博客接入到HelloCTF的Archive中,请先将本站点(https://ctf.tj.cn)添加到你的友链中。 3 | title: "档案申请: " 4 | labels: [] 5 | assignees: 6 | - ProbiusOfficial 7 | body: 8 | - type: input 9 | id: name 10 | attributes: 11 | label: 站点名字 12 | placeholder: 你的站点名字 13 | validations: 14 | required: true 15 | - type: input 16 | id: url 17 | attributes: 18 | label: 站点地址 19 | placeholder: 站点地址 20 | validations: 21 | required: true 22 | - type: input 23 | id: description 24 | attributes: 25 | label: 站点描述 26 | placeholder: 这是站点描述 27 | validations: 28 | required: true 29 | - type: input 30 | id: avatar 31 | attributes: 32 | label: 站点图标或个人头像 33 | description: 站点图标或个人头像 34 | placeholder: https://example.com/avatar.png 35 | validations: 36 | required: true 37 | - type: dropdown 38 | id: direction 39 | attributes: 40 | label: 主要方向 41 | description: 在CTF中主要擅长的方向,如果擅长实战请填写Web,其他请选择Other。 42 | options: 43 | - Web 44 | - Misc 45 | - Crypto 46 | - Reverse 47 | - Pwn 48 | - Other 49 | -------------------------------------------------------------------------------- /.github/workflows/update-output.yaml: -------------------------------------------------------------------------------- 1 | # Auto Run and Commit Re 2 | name: Update Output 3 | 4 | on: 5 | push: 6 | branches: 7 | - main 8 | pull_request: 9 | schedule: 10 | - cron: "0 0 * * *" 11 | 12 | jobs: 13 | run_and_commit: 14 | runs-on: ubuntu-latest 15 | 16 | permissions: 17 | # Give the default GITHUB_TOKEN write permission to commit and push the 18 | # added or changed files to the repository. 19 | contents: write 20 | 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v3 24 | 25 | - name: Set up Go 26 | uses: actions/setup-go@v4 27 | with: 28 | go-version: '1.20' # 替换为你希望使用的Go版本 29 | 30 | - name: Install dependencies 31 | run: go mod tidy 32 | 33 | - name: Run go run . 34 | run: go run . 35 | 36 | - name: Check for changes 37 | id: check_changes 38 | run: | 39 | if [ -n "$(git status --porcelain)" ]; then 40 | echo "CHANGES=true" >> $GITHUB_ENV 41 | fi 42 | 43 | - name: Commit changes 44 | if: env.CHANGES == 'true' 45 | uses: stefanzweifel/git-auto-commit-action@v4 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vscode/ 3 | .DS_Store 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HelloCTF-CTFerlink 2 | 3 | 本项目基于 https://github.com/NX-Official/friends-link-plus 4 | 5 | 原理为利用GithubAction定时抓取对应博客的RSS进行MarkDown的生成。 6 | 7 | 该项目会收集师傅们的博客,将内容分方向(Web MISC Crypto Re Pwn 等等)展示到[http://ctf.tj.cn](https://t.co/cHuCzDSgxk)的一个独立页面 8 | 9 | 效果可以参考杭电他们的wiki [https://cs.hdu.wiki/blog/](https://t.co/BOADbyc2Hm) 10 | 11 | 感谢白夜师傅 [@h4kuy4](https://github.com/h4kuy4) 提供的建议 12 | 13 |  14 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "reflect" 7 | "strconv" 8 | "strings" 9 | "unicode" 10 | ) 11 | 12 | var Config config 13 | 14 | type config struct { 15 | InputPath string `default:"input/friends.json"` 16 | OutputJsonPath string `default:"output/friends.json"` 17 | OutputMarkdownPath string `default:"output/friends.md"` 18 | TemplatePath string `default:"template/template.md"` 19 | NumOutputPost int `default:"20"` 20 | ContentLength int `default:"200"` 21 | } 22 | 23 | // Get configs from ENV, you set them in GitHub Actions Workflow 24 | func init() { 25 | Config = loadConfigFromEnv() 26 | } 27 | 28 | func loadConfigFromEnv() config { 29 | cfg := config{} 30 | t := reflect.TypeOf(cfg) 31 | v := reflect.ValueOf(&cfg) 32 | 33 | for i := 0; i < t.NumField(); i++ { 34 | field := t.Field(i) 35 | defaultValue := field.Tag.Get("default") 36 | envValue := getEnv(ConvertToSnakeCase(field.Name), defaultValue) 37 | setFieldValue(v.Elem().Field(i), envValue) 38 | } 39 | 40 | return cfg 41 | } 42 | 43 | func getEnv(key, defaultValue string) string { 44 | value := os.Getenv(key) 45 | if value == "" { 46 | log.Printf("Warning: Environment variable %s not set. Using default value: %s", key, defaultValue) 47 | return defaultValue 48 | } 49 | return value 50 | } 51 | 52 | func setFieldValue(field reflect.Value, value string) { 53 | switch field.Kind() { 54 | case reflect.String: 55 | field.SetString(value) 56 | // Add support for other data types here if needed 57 | // For example: 58 | case reflect.Int: 59 | intValue, err := strconv.Atoi(value) 60 | if err == nil { 61 | field.SetInt(int64(intValue)) 62 | } else { 63 | log.Printf("Warning: Environment variable %s is not a int. Using default value: %s", field, value) 64 | } 65 | // case reflect.Bool: 66 | // boolValue, err := strconv.ParseBool(value) 67 | // if err == nil { 68 | // field.SetBool(boolValue) 69 | // } 70 | } 71 | } 72 | 73 | // ConvertToSnakeCase converts a string to snake case 74 | // InputPath -> INPUT_PATH 75 | func ConvertToSnakeCase(input string) string { 76 | var result strings.Builder 77 | for i, c := range input { 78 | if unicode.IsUpper(c) { 79 | if i > 0 { 80 | result.WriteByte('_') 81 | } 82 | result.WriteRune(unicode.ToUpper(c)) 83 | } else { 84 | result.WriteRune(unicode.ToUpper(c)) 85 | } 86 | } 87 | return result.String() 88 | } 89 | -------------------------------------------------------------------------------- /fetch.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/mmcdole/gofeed" 5 | "net/http" 6 | ) 7 | 8 | func (friend *Friend) FetchFeed() error { 9 | resp, err := http.Get(friend.RSS) 10 | if err != nil { 11 | return err 12 | } 13 | defer resp.Body.Close() 14 | 15 | friend.Feed, err = gofeed.NewParser().Parse(resp.Body) 16 | if err != nil { 17 | return err 18 | } 19 | // 20 | //fmt.Println(friend.Feed) 21 | //fmt.Println(friend.Feed.Title) 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module friends-link-plus 2 | 3 | go 1.20 4 | 5 | require ( 6 | github.com/mmcdole/gofeed v1.2.1 7 | golang.org/x/net v0.4.0 8 | ) 9 | 10 | require ( 11 | github.com/PuerkitoBio/goquery v1.8.0 // indirect 12 | github.com/andybalholm/cascadia v1.3.1 // indirect 13 | github.com/json-iterator/go v1.1.12 // indirect 14 | github.com/mmcdole/goxpp v1.1.0 // indirect 15 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 16 | github.com/modern-go/reflect2 v1.0.2 // indirect 17 | golang.org/x/text v0.5.0 // indirect 18 | ) 19 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= 2 | github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= 3 | github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= 4 | github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= 5 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 6 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 7 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 8 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 9 | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 10 | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 11 | github.com/mmcdole/gofeed v1.2.1 h1:tPbFN+mfOLcM1kDF1x2c/N68ChbdBatkppdzf/vDe1s= 12 | github.com/mmcdole/gofeed v1.2.1/go.mod h1:2wVInNpgmC85q16QTTuwbuKxtKkHLCDDtf0dCmnrNr4= 13 | github.com/mmcdole/goxpp v1.1.0 h1:WwslZNF7KNAXTFuzRtn/OKZxFLJAAyOA9w82mDz2ZGI= 14 | github.com/mmcdole/goxpp v1.1.0/go.mod h1:v+25+lT2ViuQ7mVxcncQ8ch1URund48oH+jhjiwEgS8= 15 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 16 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 17 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 18 | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 19 | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 20 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 21 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 22 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 23 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 24 | github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= 25 | golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 26 | golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= 27 | golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= 28 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 29 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 30 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 31 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 32 | golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= 33 | golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 34 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 35 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 36 | -------------------------------------------------------------------------------- /images/README/image-20230804150510583.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProbiusOfficial/helloCTF-CTFerlink/28a8c99a06a9f08fc60c9991616e36a6cf6cca96/images/README/image-20230804150510583.png -------------------------------------------------------------------------------- /images/demo.v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProbiusOfficial/helloCTF-CTFerlink/28a8c99a06a9f08fc60c9991616e36a6cf6cca96/images/demo.v1.png -------------------------------------------------------------------------------- /images/logic.v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ProbiusOfficial/helloCTF-CTFerlink/28a8c99a06a9f08fc60c9991616e36a6cf6cca96/images/logic.v1.png -------------------------------------------------------------------------------- /input/friends.json: -------------------------------------------------------------------------------- 1 | { 2 | "friends": [ 3 | { 4 | "name": "ek1ng", 5 | "description": "Hidden Gem", 6 | "avatar": "https://avatars.hdu-cs.wiki/ek1ng", 7 | "url": "https://ek1ng.com/", 8 | "rss": "https://ek1ng.com/atom.xml", 9 | "direction":"Web" 10 | }, 11 | { 12 | "name": "曾哥", 13 | "description": "弱小和无知不是生存的障碍,傲慢才是!", 14 | "avatar": "https://blog.zgsec.cn/favicon.ico", 15 | "url": "https://blog.zgsec.cn/", 16 | "rss": "https://blog.zgsec.cn/index.php/feed/", 17 | "direction":"Web" 18 | }, 19 | { 20 | "name": "Y4tacker", 21 | "description": "宁静致远,淡泊明志", 22 | "avatar": "https://y4tacker.github.io/images/me.jpeg", 23 | "url": "https://y4tacker.github.io", 24 | "rss": "https://y4tacker.github.io/atom.xml", 25 | "direction":"Web" 26 | }, 27 | { 28 | "name": "4ra1n", 29 | "description": "许少!", 30 | "avatar": "https://4ra1n.github.io/img/av.jpg", 31 | "url": "https://4ra1n.github.io/", 32 | "rss": "", 33 | "direction":"Web" 34 | }, 35 | { 36 | "name": "crazymanarmy", 37 | "description": "A Noob's Learning Record", 38 | "avatar": "https://s2.loli.net/2023/01/27/XA2Yr7TuwcNWhOp.jpg", 39 | "url": "https://crazymanarmy.github.io/", 40 | "rss": "https://crazymanarmy.github.io/atom.xml", 41 | "direction":"MISC" 42 | }, 43 | { 44 | "name": "xia0ji233", 45 | "description": "Nepnep team", 46 | "avatar": "https://xia0ji233.pro/img/avatar.png", 47 | "url": "https://xia0ji233.pro/", 48 | "rss": "https://xia0ji233.pro/atom.xml", 49 | "direction":"Web" 50 | }, 51 | { 52 | "name": "Steven Lynn's Blog", 53 | "description": "Steven的个人博客", 54 | "avatar": "https://blog.stv.lol/favicon.ico", 55 | "url": "https://blog.stv.lol", 56 | "rss": "https://blog.stv.lol/feed/", 57 | "direction":"Other" 58 | } 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mmcdole/gofeed" 6 | "log" 7 | ) 8 | 9 | type Friend struct { 10 | Name string `json:"name"` 11 | Description string `json:"description"` 12 | Avatar string `json:"avatar"` 13 | URL string `json:"url"` 14 | RSS string `json:"rss"` 15 | Direction string `json:"direction"` 16 | Feed *gofeed.Feed `json:"-"` // RSS Content 17 | } 18 | 19 | type FriendsData struct { 20 | Friends []*Friend `json:"friends"` 21 | } 22 | 23 | type Post struct { 24 | Title string 25 | Author string 26 | Date string // YYYY-MM-DD 27 | Content string // 保留前 200 字 28 | PostURL string // 文章链接 29 | AuthorURL string // 作者链接 30 | Direction string // 擅长方向 31 | } 32 | 33 | func main() { 34 | // 读取有哪些朋友 35 | friends := Read(Config.InputPath) 36 | 37 | // 获取朋友的RSS内容 38 | for _, friend := range friends.Friends { 39 | err := friend.FetchFeed() 40 | if err != nil { 41 | log.Printf("Error fetching feed for %s with %s : %v", friend.Name, friend.RSS, err) 42 | } 43 | } 44 | 45 | // 从 RSS 中解析文章 46 | posts := GetPosts(friends) 47 | for _, post := range posts { 48 | fmt.Printf("标题:%s\n", post.Title) 49 | fmt.Printf("作者:%s\n", post.Author) 50 | fmt.Printf("日期:%s\n", post.Date) 51 | fmt.Printf("内容:%s\n", post.Content) 52 | fmt.Printf("文章链接:%s\n", post.PostURL) 53 | fmt.Printf("作者链接:%s\n", post.AuthorURL) 54 | fmt.Printf("擅长方向:%s\n", post.Direction) 55 | fmt.Println("---------------------") 56 | } 57 | 58 | // 渲染 markdown 和 json 59 | markdownBytes := RenderMarkdown(friends.Friends, posts) 60 | jsonBytes := RenderJson(friends.Friends, posts) 61 | //fmt.Println(string(markdownBytes)) 62 | 63 | // 写入文件 64 | err := Write(markdownBytes, Config.OutputMarkdownPath) 65 | if err != nil { 66 | log.Fatalf("Failed to write file: %v", err) 67 | } 68 | fmt.Println("Markdown content written to file successfully!") 69 | 70 | err = Write(jsonBytes, Config.OutputJsonPath) 71 | if err != nil { 72 | log.Fatalf("Failed to write file: %v", err) 73 | } 74 | 75 | fmt.Println("Json content written to file successfully!") 76 | } 77 | -------------------------------------------------------------------------------- /output/friends.json: -------------------------------------------------------------------------------- 1 | { 2 | "friends": [ 3 | { 4 | "name": "ek1ng", 5 | "description": "Hidden Gem", 6 | "avatar": "https://avatars.hdu-cs.wiki/ek1ng", 7 | "url": "https://ek1ng.com/", 8 | "rss": "https://ek1ng.com/atom.xml", 9 | "direction": "Web" 10 | }, 11 | { 12 | "name": "曾哥", 13 | "description": "弱小和无知不是生存的障碍,傲慢才是!", 14 | "avatar": "https://blog.zgsec.cn/favicon.ico", 15 | "url": "https://blog.zgsec.cn/", 16 | "rss": "https://blog.zgsec.cn/index.php/feed/", 17 | "direction": "Web" 18 | }, 19 | { 20 | "name": "Y4tacker", 21 | "description": "宁静致远,淡泊明志", 22 | "avatar": "https://y4tacker.github.io/images/me.jpeg", 23 | "url": "https://y4tacker.github.io", 24 | "rss": "https://y4tacker.github.io/atom.xml", 25 | "direction": "Web" 26 | }, 27 | { 28 | "name": "4ra1n", 29 | "description": "许少!", 30 | "avatar": "https://4ra1n.github.io/img/av.jpg", 31 | "url": "https://4ra1n.github.io/", 32 | "rss": "", 33 | "direction": "Web" 34 | }, 35 | { 36 | "name": "crazymanarmy", 37 | "description": "A Noob's Learning Record", 38 | "avatar": "https://s2.loli.net/2023/01/27/XA2Yr7TuwcNWhOp.jpg", 39 | "url": "https://crazymanarmy.github.io/", 40 | "rss": "https://crazymanarmy.github.io/atom.xml", 41 | "direction": "MISC" 42 | }, 43 | { 44 | "name": "xia0ji233", 45 | "description": "Nepnep team", 46 | "avatar": "https://xia0ji233.pro/img/avatar.png", 47 | "url": "https://xia0ji233.pro/", 48 | "rss": "https://xia0ji233.pro/atom.xml", 49 | "direction": "Web" 50 | }, 51 | { 52 | "name": "Steven Lynn's Blog", 53 | "description": "Steven的个人博客", 54 | "avatar": "https://blog.stv.lol/favicon.ico", 55 | "url": "https://blog.stv.lol", 56 | "rss": "https://blog.stv.lol/feed/", 57 | "direction": "Other" 58 | } 59 | ], 60 | "posts": [ 61 | { 62 | "Title": "某系统前台RCE浅析", 63 | "Author": "Y4tacker", 64 | "Date": "2025-04-16", 65 | "Content": "0a2416636d8596a6d89c133c7b60f6971ce99630884cdf6afd1d97649cdbe39606893f02e42a381ce0a49fc7535b4f6324e067de6d706384b3635b1ce021ea9edb6c0e081168a4c4fec62a99b6b4bc15b79e3a3b96705b7933478cec4f488c764ce87c", 66 | "PostURL": "https://y4tacker.github.io/2025/04/16/year/2025/04/%E6%9F%90%E7%B3%BB%E7%BB%9F%E5%89%8D%E5%8F%B0RCE%E6%B5%85%E6%9E%90/", 67 | "AuthorURL": "https://y4tacker.github.io", 68 | "Direction": "" 69 | }, 70 | { 71 | "Title": "腾讯游戏安全竞赛2025决赛题解", 72 | "Author": "xia0ji233", 73 | "Date": "2025-04-14", 74 | "Content": "记录一下今年 2025 决赛过程题目描述(1)在intel CPU/64位Windows10系统上运行sys,成功加载驱动(0.5分)(2)能在双机环境运行驱动并调试(1分)(3)优化驱动中的耗时算法,并给出demo能快速计算得出正确的key(1分)(4)分析并给出flag的计算执行流程(1.5分),能准确说明其串联逻辑(0.5分)(5)正确解出flag(1分)(6)该题目使用了一种外挂常用的隐藏", 75 | "PostURL": "https://xia0ji233.github.io/2025/04/14/tencent-race-2025-final/", 76 | "AuthorURL": "https://xia0ji233.pro/", 77 | "Direction": "" 78 | }, 79 | { 80 | "Title": "腾讯游戏安全大赛2025初赛题解", 81 | "Author": "xia0ji233", 82 | "Date": "2025-03-31", 83 | "Content": "记录一下今年 2025 初赛过程参赛选手信息题目描述小Q是一位热衷于PC客户端安全的技术爱好者,为了不断提升自己的技能,他经常参与各类CTF竞赛。某天,他收到了一封来自神秘人的邮件,内容如下:“我可以引领你进入游戏安全的殿堂,但在此之前,你需要通过我的考验。打开这扇大门的钥匙就隐藏在附件中,你有能力找到它吗?找到正确的flag(2分)flag:flag{ACE_We1C0me!T0Z0Z5GamE", 84 | "PostURL": "https://xia0ji233.github.io/2025/03/31/tencent-race-2025-pre/", 85 | "AuthorURL": "https://xia0ji233.pro/", 86 | "Direction": "" 87 | }, 88 | { 89 | "Title": "从CVE-2025-30208看任意文件读取利用", 90 | "Author": "曾哥", 91 | "Date": "2025-03-30", 92 | "Content": "0# 概述师傅们好久不见!最近不是特别忙,就研究研究最新的漏洞。刚好最近一大批漏洞都爆出来了,比如 CVE-2025-1097, CVE-2025-1098, CVE-2025-24514, CVE-2025-1974 Kubernetes Ingress-Nginx Admission Controller RCE Escalation,是危害性极大的高危漏洞,在内网渗透中能直接击穿K8S集群。", 93 | "PostURL": "https://blog.zgsec.cn/archives/713.html", 94 | "AuthorURL": "https://blog.zgsec.cn/", 95 | "Direction": "" 96 | }, 97 | { 98 | "Title": "【白帽访谈录】云安全将成为未来安全研究主战场-会议纪要", 99 | "Author": "曾哥", 100 | "Date": "2025-02-28", 101 | "Content": "{bilibili bvid=\"BV19T9gY4ETm\" page=\"\"/}很高兴能参与这期白帽访谈录,也感谢各位师傅的支持~也随时欢迎各位师傅和我友好交流哈哈!本期访谈的回放直播已经上传B站,链接: https://www.bilibili.com/video/BV19T9gY4ETm,感谢各位师傅的一键三连!!!欢迎大家关注渊龙Sec安全团队公众号,干货满满哦~{dotted startCo", 102 | "PostURL": "https://blog.zgsec.cn/archives/711.html", 103 | "AuthorURL": "https://blog.zgsec.cn/", 104 | "Direction": "" 105 | }, 106 | { 107 | "Title": "某系统前台组合拳RCE", 108 | "Author": "Y4tacker", 109 | "Date": "2025-02-23", 110 | "Content": "8133babd8f05e144d8e8c2c4c8ee0fb3d40c2c031c3925709b74cb30c7b27fca92bfd93cf7cf65a6834a805821993b6c9674428ad9fdcf275cf47eb5e07cfd2d776e01401bdf1c9d1052d24b573abb3ff41508c0d801b0496ab9e4257b11885ae0e4bf", 111 | "PostURL": "https://y4tacker.github.io/2025/02/23/year/2025/02/%E6%9F%90%E7%B3%BB%E7%BB%9F%E5%89%8D%E5%8F%B0%E7%BB%84%E5%90%88%E6%8B%B3RCE/", 112 | "AuthorURL": "https://y4tacker.github.io", 113 | "Direction": "" 114 | }, 115 | { 116 | "Title": "windowsAPC学习(2)——APC挂入与执行", 117 | "Author": "xia0ji233", 118 | "Date": "2025-02-17", 119 | "Content": "今天详细了解一下 APC 到底是怎么工作的。APC挂入在 APC 挂入的时候,内核会准备一个 _KAPC 结构体,将该结构体挂入线程的 APC 队列中。KAPC结构体介绍先在 windbg 中查看一下:123456789101112131415161718kd\u003e dt _KAPCntdll!_KAPC +0x000 Type : UChar +0x001 Spare", 120 | "PostURL": "https://xia0ji233.github.io/2025/02/17/WindowsAPC2/", 121 | "AuthorURL": "https://xia0ji233.pro/", 122 | "Direction": "" 123 | }, 124 | { 125 | "Title": "某二次元开放世界冒险游戏反作弊分析报告", 126 | "Author": "xia0ji233", 127 | "Date": "2025-02-14", 128 | "Content": "好久没碰某二次元开放世界冒险游戏了,听说新升级了反作弊,故来一探究竟,并尝试实现一些简单的功能。基本保护分析这种级别的游戏首先不考虑静态分析,直接跑起来。不出意外肯定不能直接内存读写,想附加调试器也是附加不上的,所以选择先从驱动入手,游戏加载时会加载驱动。先尝试简单的拦截,方法很多:注册 LoadImage 回调拦截,改驱动名等等等。后者比较好实现,但是运行游戏一段时间会弹窗强制退出。而如果说让保", 129 | "PostURL": "https://xia0ji233.github.io/2025/02/14/Game6/", 130 | "AuthorURL": "https://xia0ji233.pro/", 131 | "Direction": "" 132 | }, 133 | { 134 | "Title": "windowsAPC学习(1)——APC简介", 135 | "Author": "xia0ji233", 136 | "Date": "2025-02-09", 137 | "Content": "来了解一下Windows的APC机制。APCAPC介绍APC 即 Asyncroneus Procedure Call,异步过程调用。学过之前的知识我们知道,线程是不能被杀掉、挂起和恢复的,线程在执行的时候自己占据着CPU,其他线程如何控制它呢?改变一个线程的行为,这就需要APC了。APC结构体APC的结构体如下所示123456789101112131415161718kd\u003e dt _KAPCnt", 138 | "PostURL": "https://xia0ji233.github.io/2025/02/09/WindowsAPC1/", 139 | "AuthorURL": "https://xia0ji233.pro/", 140 | "Direction": "" 141 | }, 142 | { 143 | "Title": "windows句柄表学习(1)", 144 | "Author": "xia0ji233", 145 | "Date": "2025-01-26", 146 | "Content": "来了解一下Windows内核的句柄表。句柄句柄就类似 Linux 的文件描述符,指示了某个进程在内核对象的偏移,内核可以通过这个下标找到对应的内核对象。1234HANDLE g_hMutex = ::CreateMutex( NULL , FALSE, \"XYZ\");HANDLE g_hMutex = ::OpenMutex( MUTEX_ALL_ACCESSFALSE, \"XYZ\");HANDL", 147 | "PostURL": "https://xia0ji233.github.io/2025/01/26/WindowsObjectTable1/", 148 | "AuthorURL": "https://xia0ji233.pro/", 149 | "Direction": "" 150 | }, 151 | { 152 | "Title": "windows进程与线程学习——深入研究线程调度(2)", 153 | "Author": "xia0ji233", 154 | "Date": "2025-01-25", 155 | "Content": "深入研究一下线程调度,由于篇幅较多,分章节分析,第二篇。进程挂靠一个进程可以包含多个线程,线程结构体中会指向自己所属的进程。切换到这个线程的时候,会将对应的 cr3 切换到该进程的页目录基址,那么这个线程就可以访问这个进程的所有资源了。前面逆向的时候看到过,在切换 cr3 的时候,是拿到了 KTHREAD.ApcState.Process,而并不是 KTHREAD.Process,这个因为没学 A", 156 | "PostURL": "https://xia0ji233.github.io/2025/01/25/WindowsProcess5/", 157 | "AuthorURL": "https://xia0ji233.pro/", 158 | "Direction": "" 159 | }, 160 | { 161 | "Title": "windows进程与线程学习——深入研究线程调度(1)", 162 | "Author": "xia0ji233", 163 | "Date": "2025-01-24", 164 | "Content": "深入研究一下线程调度,由于篇幅较多,分章节分析SwapContext首先研究一下 SwapContext 函数的实现。伪代码分析这里我们不去分析汇编代码,而是直接用 IDA + F5,把定义还原回去即可清晰地看出逻辑12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505", 165 | "PostURL": "https://xia0ji233.github.io/2025/01/25/WindowsProcess4/", 166 | "AuthorURL": "https://xia0ji233.pro/", 167 | "Direction": "" 168 | }, 169 | { 170 | "Title": "windows进程与线程学习——调度实现的学习", 171 | "Author": "xia0ji233", 172 | "Date": "2025-01-24", 173 | "Content": "来学习一下 Windows 线程调度的实现Windows中有一个函数SwapContext用来实现线程切换,我们先得了解一下什么情况下会引发线程切换。线程切换途径分主动切换和被动切换,很好理解,主动切换就是线程主动让出 CPU 执行,被动就是被打断而不得不让出 CPU。在做实验的时候,多核真的是很困扰的一个问题,想了半天想不明白多核怎么工作的,为了好理解线程切换,建议虚拟机都换成单核的,线程大多数", 174 | "PostURL": "https://xia0ji233.github.io/2025/01/24/WindowsProcess3/", 175 | "AuthorURL": "https://xia0ji233.pro/", 176 | "Direction": "" 177 | }, 178 | { 179 | "Title": "windows进程与线程学习——调度相关结构学习", 180 | "Author": "xia0ji233", 181 | "Date": "2025-01-24", 182 | "Content": "来学习一下调度相关的结构很早就听说过断链隐藏的操作,因为 Windows 都是使用链表去管理进程,线程等结构的,所以断链可以达到隐藏自身的目的。那么这里就引申出来一个问题,为什么断链可以隐身且不破坏大部分的功能呢,下面的线程调度会给出答案。线程调度操作系统的一些理论,线程有三种状态:就绪(ready)、等待(wait)、运行(running)。至于为什么进程/线程断链可以达到隐藏且继续执行的目的,", 183 | "PostURL": "https://xia0ji233.github.io/2025/01/24/WindowsProcess2/", 184 | "AuthorURL": "https://xia0ji233.pro/", 185 | "Direction": "" 186 | }, 187 | { 188 | "Title": "windows进程与线程学习——基本结构", 189 | "Author": "xia0ji233", 190 | "Date": "2025-01-24", 191 | "Content": "来学习一下进程与线程的结构EPROCESS定义描述先来看看结构体的描述123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687", 192 | "PostURL": "https://xia0ji233.github.io/2025/01/24/WindowsProcess1/", 193 | "AuthorURL": "https://xia0ji233.pro/", 194 | "Direction": "" 195 | }, 196 | { 197 | "Title": "windows系统调用学习——系统描述符表", 198 | "Author": "xia0ji233", 199 | "Date": "2025-01-24", 200 | "Content": "来学习一下系统描述符表这个结构SSDTSSDT的全称是System Services Descriptor Table,意为系统服务描述符表。我们可以通过ETHREAD结构体加偏移的方式进行访问。在内核文件中,有一个变量是导出的:KeServiceDescriptorTable。通过它我们可以访问SSDT。可以看看在内核中看看 SSDT 是什么样的。123456789kd\u003e dd KeServic", 201 | "PostURL": "https://xia0ji233.github.io/2025/01/24/WindowsSyscall4/", 202 | "AuthorURL": "https://xia0ji233.pro/", 203 | "Direction": "" 204 | }, 205 | { 206 | "Title": "windows系统调用学习——调用细节与系统服务表", 207 | "Author": "xia0ji233", 208 | "Date": "2025-01-22", 209 | "Content": "来深入挖掘一下Windows系统调用的过程KiSystemService分析这个函数是通过中断门进的,中断门本身保存了 CS 和 EIP,跨段提权后通过 TSS 拿到零环的 SS 和 ESP。此时为了维护三环的上下文状态,则会将各种寄存器保存到堆栈,也就是 Trap_Frame 结构体,中断门提权之后本身就会按顺序压入 SS,ESP,ELFAGS,CS,EIP。此时比较一下上一篇文章中提到的 Tr", 210 | "PostURL": "https://xia0ji233.github.io/2025/01/22/WindowsSyscall3/", 211 | "AuthorURL": "https://xia0ji233.pro/", 212 | "Direction": "" 213 | }, 214 | { 215 | "Title": "windows系统调用学习——调用相关结构体学习", 216 | "Author": "xia0ji233", 217 | "Date": "2025-01-22", 218 | "Content": "来深入挖掘一下Windows系统调用的过程相关结构体介绍Trap_Frame首先第一个要讲的是 Trap_Frame 结构,如下图所示。栈帧结构体,用于 Windows API 保存现场。经过提权进入0环的时候,Windows就会遵守这个结构体保存一系列的数据,最后四个成员用于虚拟8086模式下,不属于保护模式的范畴。中断发生时,若发生权限变换,则要保存旧堆栈,CPU压入的,由 HardwareE", 219 | "PostURL": "https://xia0ji233.github.io/2025/01/22/WindowsSyscall2/", 220 | "AuthorURL": "https://xia0ji233.pro/", 221 | "Direction": "" 222 | }, 223 | { 224 | "Title": "windows系统调用学习——R3到R0", 225 | "Author": "xia0ji233", 226 | "Date": "2025-01-21", 227 | "Content": "来学习一下windows的系统调用简介API,应用程序接口(Application Programming Interface)。Windows API 顾名思义就是 Windows 提供的应用程序接口,为了在 Windows 上实现一定的功能,我们需要学习 API 的用途、传参、返回值等,微软对这部分都提供了大量的文档说明,因此详细学习 API 的实现原理对我们而言是很有必要的。Windows", 228 | "PostURL": "https://xia0ji233.github.io/2025/01/21/WindowsSyscall1/", 229 | "AuthorURL": "https://xia0ji233.pro/", 230 | "Direction": "" 231 | }, 232 | { 233 | "Title": "2024不是年终总结的总结", 234 | "Author": "Y4tacker", 235 | "Date": "2024-12-31", 236 | "Content": "2024不是年终总结的总结今年总体而言都和计划差不多走了下去,差不多做到了心若止水,心里基本没什么情绪波动了博客里不想分享过多的生活(娱乐活动多,玩得很爽🤪)让博客一直纯粹下去,简单总结下今年的技术进展吧博客博客上差不多算是“大满贯”吧,差不多每个月都坚持写了点东西Github与漏洞研究Github也罕见的做到了每月有更新🤪说到这当然也就离不开年初定下的flag🚩,不然没事谁天天往Github上P", 237 | "PostURL": "https://y4tacker.github.io/2024/12/31/year/2024/12/2024%E4%B8%8D%E6%98%AF%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93%E7%9A%84%E6%80%BB%E7%BB%93/", 238 | "AuthorURL": "https://y4tacker.github.io", 239 | "Direction": "" 240 | } 241 | ] 242 | } -------------------------------------------------------------------------------- /output/friends.md: -------------------------------------------------------------------------------- 1 | --- 2 | isarchive: true 3 | comments: true 4 | glightbox: false 5 | hide: 6 | - footer 7 | - toc 8 | - edit 9 | - view 10 | --- 11 | 12 |