English
Engineering Challenges in Domain Hijacking Detection: Lessons from a Real-World Case in Combating Dynamic Malicious Sites
1. Introduction: A “Failed” Detection Experience
In security analysis, we often encounter situations like this:Even though malicious content can be seen when accessed manually, automated tools detect nothing at all..
This article documents the analysis of a real-world domain hijacking incident. The domain timessky.com When the user visits, it will redirect to bxo.lcsylbx.com(an adult video navigation site), but when we wrote an automated detection tool in Go, we found:
No adult keywords detected on the page
Unable to extract the redirect target URL
Obfuscated code features are sometimes present and sometimes absent.
This is not because the tool is poorly written, but because malicious sites are fighting against us.
This article will share, from the perspective of a Golang security development engineer:
Analysis of Dynamic Adversarial Behavior of Malicious Websites
Why does simple regex detection fail?
A practical, implementable multi-strategy detection solution
Best practices for engineering deployment
Forward declaration: All code in this article is based on summaries of real adversarial scenarios; the example output is in a generic format, and actual detection results will vary due to the dynamic behavior of the target site.
2. Phenomenon description: a malicious site that can "change its face"
2.1 Manual Access Phenomenon
When using a real browser to access https://timessky.com Time:
The page redirects immediately (or displays a "Click to Enter" button)
Ultimately implemented in
https://bxo.lcsylbx.com/The target page title is "Midnight Passion Instant Streaming Video" or similar adult content.
2.2 The Phenomenon of Automated Tool Access
When using curl or Go's net/http When accessing the same domain, the content returned is completely different:
bash
curl -sI https://bxo.lcsylbx.com --max-time 5May return:
The title is Shishou City Taoqian Network Co., Ltd.
The content is training-related keywords.
Does not contain adult content.
| Access method | Characteristics of the returned content |
|---|---|
| real browser | Adult content, automatic redirect |
| curl / Simple HTTP client | Harmless content, no redirects. |
2.3 Why is there such a difference?
Malicious websites identify the source of visits through the following techniques:
| Detection dimension | Countermeasures |
|---|---|
| User-Agent | Non-browser UAs return harmless content |
| JavaScript execution capabilities | Return a static page when JavaScript is unavailable |
| browser fingerprint | Detect Headless browsers |
| IP source | Scanner IP returns empty content |
| Time/Frequency | High-frequency requests trigger anti-scraping. |
Conclusion: This is not a simple static hijacking, but a Dynamic adversarial system.
3. Analysis of Malicious Code Obfuscation Techniques
When a malicious site believes the visitor is a "real user," it returns obfuscated redirect code. The following are obfuscation characteristics from real cases:
3.1 String Splitting and Concatenation
javascript
// original code
m_9_j_o_h_4 = 'r'+['e','p','l']['join']('')+'ace';
// equivalent to
m_9_j_o_h_4 = 'replace';3.2 Regular expression replacement decoding
javascript
// Decode obfuscated strings via regex replacement
yu4['my8ay8ty8cy8h'[...]](/[$]\d+/g)3.3 Dynamic Execution
javascript
// Finally execute the decoded code
window['eg1vg1ag1l'[...]](yu4); // Equivalent to window.eval(yu4)3.4 Digital Coding
javascript
// The jump target is encoded as a numeric string and decoded at runtime.
'$111$122$110$128...' // Decoded as bxo.lcsylbx.comThe purpose of these obfuscation techniques is: Bypass static detection tools based on string matching.
4. Engineering Detection Solution: Multi-Strategy Adversarial
In the face of dynamically adversarial malicious sites, a single detection strategy is bound to fail. We need Multi-strategy portfolio.
4.1 Core Design Approach
4.2 Go Implementation: Multi-Strategy Detection Engine
go
package main
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"net/http"
"regexp"
"strings"
"time"
)
type DetectionResult struct {
URL string `json:"url"`
Timestamp time.Time `json:"timestamp"`
UserAgent string `json:"user_agent"`
StatusCode int `json:"status_code"`
Title string `json:"title"`
BodyHash string `json:"body_hash"`
SuspicionScore int `json:"suspicion_score"` // 0-100
Findings []string `json:"findings"`
}
// Multiple User-Agent list
var userAgents = []string{
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/120.0.0.0 Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15",
"Mozilla/5.0 (Linux; Android 10; SM-G973F) AppleWebKit/537.36",
"curl/7.68.0",
}
// Suspicious feature pattern
var suspiciousPatterns = []struct {
Pattern string
Score int
Desc string
}{
{`eval\s*\(`, 15, "Detected eval() execution"},
{`window\s*\[\s*['"][^'"]+['"]\s*\]\s*\(`, 15, "dynamic window call"},
{`\['r','e','p','l'\]`, 20, "string splitting obfuscation"},
{`\$\d+\$`, 10, "numeric encoding obfuscation"},
{`\d+ years or older`, 20, "Age verification prompt"},
{`Click to enter`, 15, "Interactive redirect prompt"},
{`Anti-ban`, 15, "Anti-ban prompt"},
{`Latest URL`, 10, "Dynamic URL hint"},
{`bxo\.lcsylbx\.com`, 30, "known malicious domain"},
}
// Extract title
func extractTitle(body string) string {
re := regexp.MustCompile(`<title>(.*?)</title>`)
matches := re.FindStringSubmatch(body)
if len(matches) > 1 {
return matches[1]
}
return ""
}
// Single detection
func detectWithUA(url, ua string) DetectionResult {
client := &http.Client{Timeout: 10 * time.Second}
req, _ := http.NewRequest("GET", url, nil)
req.Header.Set("User-Agent", ua)
req.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
req.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8")
start := time.Now()
resp, err := client.Do(req)
ttfb := time.Since(start)
result := DetectionResult{
URL: url,
Timestamp: time.Now(),
UserAgent: ua,
Findings: []string{},
}
if err != nil {
result.Findings = append(result.Findings, "Request failed: "+err.Error())
return result
}
defer resp.Body.Close()
result.StatusCode = resp.StatusCode
body, _ := io.ReadAll(resp.Body)
bodyStr := string(body)
result.Title = extractTitle(bodyStr)
hash := sha256.Sum256(body)
result.BodyHash = hex.EncodeToString(hash[:])
// Calculate suspiciousness
score := 0
for _, p := range suspiciousPatterns {
if matched, _ := regexp.MatchString(p.Pattern, bodyStr); matched {
score += p.Score
result.Findings = append(result.Findings, p.Desc)
}
}
// Extra: Check whether the title contains abnormal keywords
suspiciousTitles := []string{"adult", "midnight", "passion", "instant playback", "video platform"}
for _, kw := range suspiciousTitles {
if strings.Contains(result.Title, kw) {
score += 15
result.Findings = append(result.Findings, "Title contains suspicious keyword: "+kw)
break
}
}
result.SuspicionScore = min(score, 100)
result.Findings = append(result.Findings, fmt.Sprintf("TTFB: %v", ttfb))
return result
}
// Multi-strategy comprehensive detection
func DetectDomain(url string) []DetectionResult {
results := []DetectionResult{}
for _, ua := range userAgents {
result := detectWithUA(url, ua)
results = append(results, result)
}
return results
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func main() {
targets := []string{
"https://timessky.com",
"https://bxo.lcsylbx.com",
}
for _, target := range targets {
fmt.Printf("\n=== Detection target: %s ===\n", target)
results := DetectDomain(target)
// Output the result with the highest suspicion score
maxScore := 0
var bestResult DetectionResult
for _, r := range results {
if r.SuspicionScore > maxScore {
maxScore = r.SuspicionScore
bestResult = r
}
}
data, _ := json.MarshalIndent(bestResult, "", " ")
fmt.Println(string(data))
// Output suggestions
if bestResult.SuspicionScore >= 50 {
fmt.Printf("⚠️ Suspicion score: %d/100 - further manual confirmation recommended\n", bestResult.SuspicionScore)
} else {
fmt.Printf("✅ Suspicion score: %d/100 - Currently no obvious abnormalities\n", bestResult.SuspicionScore)
}
}
}4.3 Advanced Solution: Browser Automation
For highly adversarial sites, HTTP requests alone cannot retrieve the real content; browser automation tools (such as chromedp) are required:
go
package main
import (
"context"
"fmt"
"time"
"github.com/chromedp/chromedp"
)
func getRenderedPage(url string) (string, error) {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
defer cancel()
var html string
err := chromedp.Run(ctx,
chromedp.Navigate(url),
chromedp.Sleep(3*time.Second), // Wait for JS execution
chromedp.OuterHTML("html", &html),
)
if err != nil {
return "", err
}
return html, nil
}5. Suspiciousness score of the test result
Because malicious sites change dynamically, we No longer output definitive conclusions., but rather output Suspicion score:
| Score range | meaning | Recommended actions |
|---|---|---|
| 0-20 | No obvious abnormalities | Continue routine monitoring |
| 21-50 | Suspicious features present | Manual review |
| 51-80 | Highly suspicious | Immediately conduct an in-depth analysis |
| 81-100 | Extremely likely to be malicious | Block/Alert |
6. Engineering Deployment Recommendations
6.1 定时巡检
go
// Daily multi-period detection
func scheduledDetection(domain string) {
times := []string{"02:00", "10:00", "14:00", "20:00"}
for _, t := range times {
// Perform detection at the specified time
}
}6.2 Distributed Detection
yaml
# Use multiple cloud regions to initiate detection.
regions:
- us-east-1
- eu-west-1
- ap-northeast-1
- ap-southeast-16.3 Alarm Threshold
go
// Trigger an alert when the suspicion score is > 50 for 3 consecutive detections
if consecutiveHighScore >= 3 {
sendAlert(domain, "Suspicious content continuously detected")
}7. Summary: From Certainty to Probability
| traditional thinking | Thinking in adversarial environments |
|---|---|
| Expect exact match | Accept probabilistic judgments |
| Single detection strategy | Multi-strategy portfolio |
| Static rules | Dynamic assessment |
| Output a definitive conclusion. | Output suspiciousness score |
Core principles:
Do not trust a single test result.: Multiple User-Agents, multiple time points, multiple regions
Acknowledge the existence of confrontation: Malicious sites will take special measures against automated tools
From "detection" to "assessment": Output a suspicion score rather than definitive conclusions
Human-machine integration: Trigger manual review when suspicion is high
8. References
The following resources provide more in-depth references for the technologies and tools covered in this blog post:
Core Tools and Documentation
chromedp official documentation and repository—— A standard library in Go for driving browsers that support the Chrome DevTools Protocol, and a core tool for implementing browser automation and retrieving dynamically rendered page content.
Chrome DevTools Protocol (CDP) Official Reference—— An important document for understanding the underlying protocol of chromedp, defining all programmable control interfaces of the Chrome browser.
Adversarial strategies and anti-detection techniques
User-Agent and anti-detection: MDN Web Docs provides information about
User-AgentRequest headers and Browser fingerprint The detailed explanation is the foundation for understanding automated tools for identifying malicious websites.JavaScript obfuscation techniques: Obfuscator.io is an open-source JS code obfuscation tool, its GitHub repository It demonstrates multiple obfuscation techniques, including string splitting and encoding conversion, which are highly relevant to the malicious code characteristics in this article's case study.
Related Practices and Discussion
chromedp example repository—— Includes complete examples of complex operations such as full-page screenshots, form submission, and waiting for elements, and can be directly used to build detection collectors for highly adversarial sites.
Black Hat SEO and Malicious Redirect Analysis:Sucuri Blog Long-term tracking of malicious domain hijacking and blackhat SEO redirects has provided numerous real-world case analyses. Search for "malicious redirect" or "blackhat SEO" on the site to obtain detailed attack chain analyses and technical reports.
Usage recommendations: In practical engineering, it is recommended to prioritize reading chromedp the official documentation and examples, and combine them with the CDP protocol to understand the principles of browser automation detection. For obfuscated code analysis, you can use AST Online Parsing Tool Assisted reverse engineering.
📌Afterword: This article no longer provides "deterministic" detection examples, because in real adversarial environments, that is misleading. The value of security tools lies in Provide clues rather than absolute answers. If readers have a better detection solution in practice, we welcome discussion.