Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 64cfeee
Showing
13 changed files
with
862 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# WCTF2019: Gyotaku The Flag | ||
here I present new technique: abusing Windows Defender engine to leak secret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
db/ | ||
gyotaku/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
GOOS := linux | ||
GOARCH := amd64 | ||
|
||
BUILD := $(shell git rev-parse --short HEAD) | ||
LDFLAGS = -ldflags "-X=main.Build=$(BUILD)" | ||
|
||
|
||
.PHONY: build | ||
build-api: | ||
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o ./bin/gyotaku $(LDFLAGS) -v ./src | ||
|
||
.PHONY: windows | ||
windows: | ||
GOOS=windows GOARCH=$(GOARCH) go build -o ./bin/gyotaku.exe $(LDFLAGS) -v ./src | ||
|
||
.PHONY: clean | ||
clean: | ||
rm -f bin/* |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
WCTF{testflag} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
module gyotaku | ||
|
||
go 1.12 | ||
|
||
require ( | ||
github.com/casbin/casbin v1.8.2 // indirect | ||
github.com/denisenkom/go-mssqldb v0.0.0-20190423183735-731ef375ac02 // indirect | ||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect | ||
github.com/golang/protobuf v1.3.1 // indirect | ||
github.com/golang/snappy v0.0.1 // indirect | ||
github.com/google/btree v1.0.0 // indirect | ||
github.com/google/pprof v0.0.0-20190404155422-f8f10df84213 // indirect | ||
github.com/gorilla/sessions v1.1.3 | ||
github.com/hashicorp/golang-lru v0.5.1 // indirect | ||
github.com/jinzhu/gorm v1.9.4 | ||
github.com/jinzhu/now v1.0.0 // indirect | ||
github.com/labstack/echo v3.3.10+incompatible | ||
github.com/labstack/echo-contrib v0.0.0-20190220224852-7fa08ffe9442 | ||
github.com/labstack/echo/v4 v4.1.5 | ||
github.com/lib/pq v1.1.0 // indirect | ||
github.com/mattn/go-colorable v0.1.2 // indirect | ||
github.com/onsi/ginkgo v1.8.0 // indirect | ||
github.com/onsi/gomega v1.5.0 // indirect | ||
github.com/stretchr/objx v0.2.0 // indirect | ||
github.com/syndtr/goleveldb v1.0.0 | ||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f | ||
golang.org/x/exp v0.0.0-20190426045226-199475d76704 // indirect | ||
golang.org/x/image v0.0.0-20190424155947-59b11bec70c7 // indirect | ||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 // indirect | ||
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6 // indirect | ||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect | ||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a | ||
golang.org/x/sys v0.0.0-20190527104216-9cd6430ef91e // indirect | ||
golang.org/x/text v0.3.2 // indirect | ||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect | ||
golang.org/x/tools v0.0.0-20190525145741-7be61e1b0e51 // indirect | ||
google.golang.org/api v0.4.0 // indirect | ||
google.golang.org/appengine v1.5.0 // indirect | ||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb // indirect | ||
google.golang.org/grpc v1.20.1 // indirect | ||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a // indirect | ||
) |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/gob" | ||
|
||
"github.com/syndtr/goleveldb/leveldb" | ||
"golang.org/x/crypto/bcrypt" | ||
) | ||
|
||
type DBConn struct { | ||
DB *leveldb.DB | ||
} | ||
|
||
func (dbconn *DBConn) UserExists(username string) (bool, error) { | ||
ret, err := dbconn.DB.Has([]byte("user-"+username), nil) | ||
if err != nil { | ||
return false, err | ||
} | ||
return ret, nil | ||
} | ||
|
||
func (dbconn *DBConn) VerifyUser(username, password string) (bool, error) { | ||
snapshot, err := dbconn.DB.GetSnapshot() | ||
defer snapshot.Release() | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
data, err := snapshot.Get([]byte("user-"+username), nil) | ||
if err != nil { | ||
return false, err | ||
} | ||
|
||
err = bcrypt.CompareHashAndPassword(data, []byte(password)) | ||
if err != nil { | ||
return false, nil | ||
} | ||
|
||
return true, nil | ||
} | ||
|
||
func (dbconn *DBConn) CreateUser(username, password string) error { | ||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) | ||
if err != nil { | ||
return err | ||
} | ||
tx, err := dbconn.DB.OpenTransaction() | ||
if err != nil { | ||
return err | ||
} | ||
tx.Put([]byte("user-"+username), []byte(hash), nil) | ||
return tx.Commit() | ||
} | ||
|
||
func (dbconn *DBConn) GetGyotakuList(username string) ([]string, error) { | ||
ret, err := dbconn.DB.Has([]byte("gyotaku-"+username), nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if !ret { | ||
return []string{}, nil | ||
} | ||
|
||
data, err := dbconn.DB.Get([]byte("gyotaku-"+username), nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
var gyotaku []string | ||
buf := bytes.NewBuffer(data) | ||
err = gob.NewDecoder(buf).Decode(&gyotaku) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return gyotaku, nil | ||
} | ||
|
||
func (dbconn *DBConn) AddGyotakuList(username, gid string) error { | ||
tx, err := dbconn.DB.OpenTransaction() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ret, err := tx.Has([]byte("gyotaku-"+username), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var gyotaku []string | ||
|
||
if ret { | ||
data, err := tx.Get([]byte("gyotaku-"+username), nil) | ||
if err != nil { | ||
return err | ||
} | ||
buf := bytes.NewBuffer(data) | ||
err = gob.NewDecoder(buf).Decode(&gyotaku) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
gyotaku = append(gyotaku, gid) | ||
buf := bytes.NewBuffer(nil) | ||
err = gob.NewEncoder(buf).Encode(&gyotaku) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = tx.Put([]byte("gyotaku-"+username), buf.Bytes(), nil) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return tx.Commit() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"crypto/sha256" | ||
"encoding/gob" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"os" | ||
"path" | ||
|
||
"github.com/labstack/echo-contrib/session" | ||
"github.com/labstack/echo/v4" | ||
) | ||
|
||
func IndexHandler(db *DBConn) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
banner := ` | ||
,、 __ | ||
//,\ ///\ | ||
__,..-‐‐'..'..'─‐‐─'--'.'--.、`= 、__ , - ア | ||
_,..-‐::´;;;;;;;;:::::::::: :::;:::;;;;;:`::‐.-..、__,.-‐ニ-/ | ||
_,..-´__ ::::、:.丶 :::::::::::__ -‐ァ :::::;;;;;;;;;::::::::__ !三 〈 | ||
.∠_ = 〈●〉 ...〉....〕-‐ '´ミ_, -‐´ ::::::::::::::_,-‐'´ ̄ `\ミ、 ヽ | ||
.\ ミヽ, 、_, .....Z../....... ̄.´................_. _,....ァ'´ `‐- ゝ | ||
`゙‐- __ /」:::::::::::::::___ ,, -‐ヘ、、、ヽ`‐ '´ | ||
 ̄ ̄ \ヽ.l ヽ、/ | ||
\| | ||
Welcome to Gyotaku service! | ||
` | ||
return c.String(http.StatusOK, banner) | ||
} | ||
} | ||
|
||
func LoginHandler(db *DBConn) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
sess, _ := session.Get(SessionName, c) | ||
if ok := sess.Values["username"]; ok != nil { | ||
return c.JSON(http.StatusOK, "alreday logged in") | ||
} | ||
|
||
username := c.FormValue("username") | ||
password := c.FormValue("password") | ||
|
||
if len(username) < 8 || len(password) < 8 { | ||
return c.JSON(http.StatusBadRequest, "both username and password must have 8 characters at least") | ||
} | ||
|
||
ret, err := db.UserExists(username) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !ret { // create new user | ||
err := db.CreateUser(username, password) | ||
if err != nil { | ||
return err | ||
} | ||
sess.Values["username"] = username | ||
sess.Save(c.Request(), c.Response()) | ||
return c.JSON(http.StatusOK, "success") | ||
} | ||
|
||
// verify user credentials | ||
ret, err = db.VerifyUser(username, password) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !ret { | ||
return c.JSON(http.StatusBadRequest, "invalid username or password") | ||
} | ||
|
||
// success | ||
sess.Values["username"] = username | ||
sess.Save(c.Request(), c.Response()) | ||
return c.JSON(http.StatusOK, "success") | ||
} | ||
} | ||
|
||
func GyotakuListHandler(db *DBConn) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
sess, _ := session.Get(SessionName, c) | ||
username := sess.Values["username"].(string) | ||
|
||
gyotaku, err := db.GetGyotakuList(username) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.JSON(http.StatusOK, gyotaku) | ||
} | ||
} | ||
|
||
type GyotakuData struct { | ||
URL string `json:"url"` | ||
Data string `json:"data"` | ||
UserName string `json:"username"` | ||
} | ||
|
||
func GyotakuHandler(db *DBConn) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
sess, _ := session.Get(SessionName, c) | ||
username := sess.Values["username"].(string) | ||
|
||
url := c.FormValue("url") | ||
|
||
// generate gyotaku id | ||
gid := fmt.Sprintf("%x", sha256.Sum256([]byte(url))) | ||
|
||
_, err := os.Stat(path.Join(GyotakuDir, gid)) | ||
if !os.IsNotExist(err) { | ||
return c.JSON(http.StatusConflict, "this gyotaku has already been taken") | ||
} | ||
|
||
resp, err := http.Get(url) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() | ||
|
||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// save gyotaku | ||
gyotakudata := &GyotakuData{ | ||
URL: url, | ||
Data: string(body), | ||
UserName: username, | ||
} | ||
|
||
buf := bytes.NewBuffer(nil) | ||
err = gob.NewEncoder(buf).Encode(gyotakudata) | ||
if err != nil { | ||
return err | ||
} | ||
err = ioutil.WriteFile(path.Join(GyotakuDir, gid), buf.Bytes(), 0644) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = db.AddGyotakuList(username, gid) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.JSON(http.StatusOK, gid) | ||
} | ||
} | ||
|
||
func GyotakuViewHandler(db *DBConn) echo.HandlerFunc { | ||
return func(c echo.Context) error { | ||
// sess, _ := session.Get(SessionName, c) | ||
// username := sess.Values["username"].(string) | ||
gid := c.Param("gid") | ||
|
||
_, err := os.Stat(path.Join(GyotakuDir, gid)) | ||
if os.IsNotExist(err) { | ||
return c.JSON(http.StatusNotFound, "no such gyotaku") | ||
} | ||
|
||
_, err = ioutil.ReadFile(path.Join(GyotakuDir, gid)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return c.JSON(http.StatusNotImplemented, "sorry but I couldn't make it by the submission deadline :P") | ||
|
||
// var gyotakudata GyotakuData | ||
// buf := bytes.NewBuffer(data) | ||
// err = gob.NewDecoder(buf).Decode(&gyotakudata) | ||
// if err != nil { | ||
// return err | ||
// } | ||
|
||
// if username != gyotakudata.UserName { | ||
// return c.JSON(http.StatusForbidden, "this is not your gyotaku") | ||
// } | ||
} | ||
} | ||
|
||
func FlagHandler(c echo.Context) error { | ||
data, err := ioutil.ReadFile("flag") | ||
if err != nil { | ||
return err | ||
} | ||
return c.String(http.StatusOK, string(data)) | ||
} |
Oops, something went wrong.