Go - Context

控制 Goroutine 的方式有 Waitgroup 和 Context,前面有講過 Waitgroup 簡單來說是可以指定一個數量,等到這個數量的 job 都執行完了之後再繼續執行主程式。

Context 的話,goroutine 內可能又有多個 goroutine,背景又有別的 goroutine,取消就會變得很麻煩,這就是 Context 常見的使用場景,在複雜的 goroutine 場景進行取消非常好用,又可以理解成:多個或有上下層關係的 goroutine 同步請求、處理請求、取消。

建立 Context 的方法:

  • context.Backgroud(), 較常使用
  • context.TODO()

With 函數(使用時需要從父 Context 衍生):

  • func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
  • func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
  • func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
  • func WithValue(parent Context, key, val interface{}) Context

WithTimeout,超時取消範例:

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	HttpHandler()
}

func HttpHandler() {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) 
        // cancel 其實沒被使用到 context 就結束了,但必須 defer cancel() 來避免 context leak
	defer cancel()
	deal(ctx)
}

func deal(ctx context.Context) {
	for i := 0; i < 10; i++ {
		time.Sleep(1 * time.Second)
		select {
		case <-ctx.Done(): // 三秒後context被關閉,執行此處
			fmt.Println(ctx.Err()) 
			return
		default: // 前三秒時
			fmt.Printf("deal time is %d\n", i)
		}
	}
}

WithCancel,取消範例:

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	go Talk(ctx)

	time.Sleep(10 * time.Second)
	cancel() // 十秒後閉嘴
	time.Sleep(1 * time.Second)
}

package main

import (
	"context"
	"fmt"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	go Talk(ctx)

	time.Sleep(10 * time.Second)
	cancel()
	time.Sleep(1 * time.Second)
}

func Talk(ctx context.Context) {
	for range time.Tick(time.Second) {
		select {
		case <-ctx.Done():
			fmt.Println("我要閉嘴了")
			return
		default:
			fmt.Println("balabalabalabala")
		}
	}
}

Reference

【Go语言】小白也能看懂的context包详解:从入门到精通 用 10 分鐘了解 Go 語言 context package 使用場景及介紹

MySQL - Explicit Commit / Implicit Commit / Autocommit

資料庫提交數據的三種類型:

顯式提交 (Explicit Commit)

COMMIT 命令完成提交,例如:

select * from dept;
commit;

隱式提交 (Implicit Commit)

運行某些指令之後資料庫自動完成,不需要再做 COMMIT,例如:

CREATE TABLE Persons (
    PersonID int,
    LastName varchar(255),
    FirstName varchar(255),
    Address varchar(255),
    City varchar(255)
);

隱式提交的指令有:CREATE TABLEDROP TABLE 等,這些指令各自被視作單一的 transaction,因此執行完畢做 ROLLBACK 不會有用。更多可以參考 Statements That Cause an Implicit Commit

自動提交 (Autocommit)

如果 autocommit mode 開啟的話,每一個 SQL statement 都將被視作單一的 transaction,不需要 COMMIT,會自動完成提交。MySQL 默認 autocommit mode 開啟。

可以用 SELECT @@autocommit 指令確認 autocommit mode 是否開啟,是的話值為 1。

Reference

autocommit, Commit, and Rollback MYSQL的COMMIT和ROLLBACK使用讲解

MySQL command category

常見的 Structured Query Language 指令有 Create, Drop, Insert 等,而這些指令又可以細分為幾個種類:

DDL (Data Definition Language)

這個種類的指令大多用來建立、變更、刪除資料庫物件的結構或 schema,例如:

  1. CREATE
  2. DROP
  3. ALTAR
  4. TRUNCATE
  5. RENAME

DQL – Data Query Language

一言以蔽之,用來查詢資料庫的資料,例如 SELECT。

DML – Data Manipulation Language

操作和修改資料庫中的資料,常見的有:

  1. INSERT
  2. UPDATE
  3. DELETE

DCL – Data Control Language

與權限、授權、許可相關的指令,例如:

  1. GRANT
  2. REVOKE

TCL – Transaction Control Language

與控制、管理事務(Transaction)相關,例如:

  1. BEGIN
  2. COMMIT
  3. ROLLBACK

Reference

PicoCTF - SOAP

Challenge

Tags

PicoCTF 2023 / Web Exploitation / XXE

Description

The web project was rushed and no security assessment was done. Can you read the /etc/passwd file?

Writeup

  1. Launch Instance 後,進入網站點選其中一項 detail,發現網站 POST 網址 http://saturn.picoctf.net:56031/data,要求酬載如下:
      <?xml version="1.0" encoding="UTF-8"?><data><ID>1</ID></data> 
    
  2. 所以我們的 xml injection 如下:
    Headers pico Body pico
  3. 將請求送出後,可以在 response 找到我們的 flag! pico

PicoCTF - Java Code Analysis!?!

Challenge

Tags

PicoCTF 2023 / Web Exploitation

Description

BookShelf Pico, my premium online book-reading service. I believe that my website is super secure. I challenge you to prove me wrong by reading the ‘Flag’ book!
Here are the credentials to get you started:
Username: “user”
Password: “user”

Writeup

觀察網站

  1. 依照預設的帳號密碼登入後,先檢視網站,會發現,每次進行 request 都會戴上 jwt
  2. 去 jwt.io 進行解碼後,可以發現裡面的內容包含 Role 等資訊:

觀察下載的原始碼

  1. 用來簽名的 key 其實就存在 server_secret.txt 這個檔案中,內容是 1234。
  2. role 分四個等級,最高權限是 Admin,從網頁書架的標籤與程式碼很多地方都可以看出來這點
  3. 初始化有兩個帳戶,一個是 user,UserID = 1,第二個是 admin,UserID = 2,後者有最高的 Admin 權限
  4. 得到書本內容的 api :
  5. 檢查權限的方式是看 jwt

偽造 jwt

  1. 帶原本的 jwt POST /base/books/pdf/5,會被告知無權限
  2. 在 jwt.io 中修改內容如下,用已知的秘密鑰匙簽名,複製左邊偽造的 jwt
  3. 帶著偽造的 jwt 再 POST /base/books/pdf/5,成功了!將 flag pdf 儲存下來即可
  4. Flag