package honeypot import ( "html" "net/http" "strings" ) // LoginPageVars 是假登录页的渲染参数。 type LoginPageVars struct { // Action 是表单提交地址(当前诱饵路径本身)。 Action string // Title / Heading 是页面标题与表单标题。 Title string Heading string // Notice 是提交失败后的提示语。 Notice string // Redir 为原始请求的查询串(WordPress 风格的 ?redirect_to=),原样回填。 Redir string } // RenderLoginPage 输出仿 WordPress 后台风格的假登录页(200,text/html)。 // // 页面刻意包含: // - 隐藏 canary 标记(HTML 注释 + meta),便于日后溯源; // - 经典 WP 字段名 log / pwd / redirect_to —— 让暴力破解脚本原样提交, // 我们就能拿到最干净的用户名与密码对; // - 一个 nginx/Apache 风格的 404 页脚,暗示「这个后台真的存在」, // 但正文是纯静态 HTML,不泄露任何版本、路径或真实凭据。 func RenderLoginPage(vars LoginPageVars) []byte { action := html.EscapeString(vars.Action) title := vars.Title if title == "" { title = "Log In ‹ WordPress" } heading := vars.Heading if heading == "" { heading = "WordPress" } notice := "" if vars.Notice != "" { notice = `
` + html.EscapeString(vars.Notice) + `
` } redir := html.EscapeString(vars.Redir) var b strings.Builder b.Grow(4096) b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + html.EscapeString(title) + `` + "\n") // 静态内联样式,避免蜜罐依赖站点静态资源(也避免污染真实缓存) b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`
` + "\n") b.WriteString(`

` + html.EscapeString(heading) + `

` + "\n") b.WriteString(notice + "\n") b.WriteString(`
` + "\n") b.WriteString(`

` + "\n") b.WriteString(`

` + "\n") b.WriteString(`

Remember Me

` + "\n") b.WriteString(`

` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`
` + "\n") b.WriteString(`` + "\n") b.WriteString(`
` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") b.WriteString(`` + "\n") return []byte(b.String()) } const honeypotCSS = `html{background:#f0f0f1}body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:14px;color:#3c434a} #login{border:1px solid #dcdcde;background:#fff;width:320px;margin:5em auto;padding:26px 24px 46px;box-shadow:0 1px 3px rgba(0,0,0,.04)} #login h1{text-align:center;margin:0 0 1em;font-size:24px;font-weight:400} #login h1 a{color:#444;text-decoration:none} #login form{margin-top:16px} #login label{display:block;font-size:14px} #login input[type=text],#login input[type=password]{width:100%;padding:5px 8px;border:1px solid #ddd;border-radius:3px;box-sizing:border-box;margin-top:4px} #login .button{width:100%;padding:7px 12px;background:#2271b1;border:1px solid #2271b1;border-radius:3px;color:#fff;cursor:pointer;font-size:13px} #login .submit{margin:16px 0 0} #login_error{border-left:4px solid #d63638;background:#fcf0f1;padding:10px 12px;margin:12px 0} #nav,.forgetmenot{font-size:13px;color:#50575e} #footer{text-align:center;color:#646970;font-size:12px;margin:24px auto;max-width:320px} ` // NotFoundFooter 是 404 假页脚,用于给扫描器「后台存在但资源不存在」的错觉。 const NotFoundFooter = "The requested resource was not found on this server." // LoginFailureNotice 是提交凭据后的统一提示(不区分「用户不存在」与「密码错误」, // 避免因响应差异让爆破脚本调整策略;同时这也是虚假后台「存在」的证据)。 const LoginFailureNotice = "ERROR: Invalid username or password." // WriteLoginPage 将假登录页写入响应。 func WriteLoginPage(w http.ResponseWriter, vars LoginPageVars) { body := RenderLoginPage(vars) h := w.Header() h.Set("Content-Type", "text/html; charset=utf-8") h.Set("Cache-Control", "no-store, no-cache, must-revalidate") // 诱饵页面绝不进入任何共享/边缘缓存,也不被中间层改写。 h.Set("X-Robots-Tag", "noindex, nofollow") w.WriteHeader(http.StatusOK) _, _ = w.Write(body) }