結合CVE-2019-14809的一道go語言CTF

題目

繞過下列過濾函數

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strings"
)
func SanCheck(input string) error {
	u, err := url.Parse(input)

	if err != nil {
		return err
	}

	if u.Scheme != "http" {
		return fmt.Errorf("err: Invalid Scheme [%s]", u.Scheme)
	}

	if u.Opaque != "" {
		return fmt.Errorf("err: WHAT AER YOU DOING ?!!! (%s)", u.Opaque)
	}

	if u.Hostname() != "127.0.0.1" {
		return fmt.Errorf("err: Invalid Hostname [%s]", u.Hostname())
	}

	if u.Port() != "" && u.Port() != "80" {
		return fmt.Errorf("err: Invalid Port [%s]", u.Port())
	}

	if u.User == nil {
		return fmt.Errorf("err: Authorization Required")
	}

	if u.User.Username() != "root" {
		return fmt.Errorf("err: Invalid Username [%s]", u.User.Username())
	}

	if password, set := u.User.Password(); !set || password != "P@ssw0rd!" {
		return fmt.Errorf("err: Invalid Password [%s]", password)
	}

	if u.RequestURI() != "/flag.php" {
		return fmt.Errorf("err: Invalid RequestURI [%s]", u.RequestURI())
	}

	if u.Fragment != "" {
		return fmt.Errorf("err: Invalid Fragment [%s]", u.Fragment)
	}

	if !strings.Contains(u.String(), "'Pwned!'") {
		fmt.Println(u.String())
		return fmt.Errorf("err: San Check failed" + u.String())
	}

	return nil
}

解決方法

考慮應該是net/url庫可能存在問題,搜一下CVE,發現有CVE-2019-14809是說Host字段有解析錯誤,看到下面還有GitHub的issues,反映下列URI解析出來的Host都是google.com

javascript://%250aalert(1)+'[email protected]/a'a
http://[google.com]:80
http://google.com]:80
http://google.com]:80__Anything_you'd_like_sir
http://[google.com]FreeTextZoneHere]:80

這裏聯繫之前Apache中常見的多個參數導致解析錯誤的洞,嘗試加入兩個用中括號包裹的host,發現就可以繞過:

http://root:P@ssw0rd!@[127.0.0.1]['Pwned!']:80/flag.php

當然這個洞在最新版本的Go語言中已經修復了,可以下載 1.11.13 和1.12.8以前的版本復現:P

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章