Mas0n
to be reverse engineer🐧
翻车鱼

福建省省赛2021 闽盾杯黑盾赛道

题目名字应该是ext,听说是0解题。

某个师傅赛后发我的题,说没做出来,让我康康。

ext

拿到文件是一个mips64 golang编译的程序,另外还给了一个加密后的文件。

https://cdn.shi1011.cn/2021/12/51410fe523e72814807c0dcd401cc4af.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

要注意此程序为大端序。

符号没去,IDA只能看到汇编代码,没有变量和引用极其难读。

不怎么熟悉MIPS,偷懒开了个auto comments

https://cdn.shi1011.cn/2021/12/da9c5b09a959ca223d9510bc99c24c12.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

这里可以改用Ghidra,相比IDA效果好上一点,但是依然难看。

简单啃下汇编和函数名,能确定大致逻辑和引用的第三方库

跑起来调试

qemu模拟动调

mips64逆向新手入门(从jarvisoj一道mips64题目说起)

RCTF2020逆向cipher(mips64&qemu&动态调试&ghidra

sudo apt-get install qemu qemu-system qemu-user-static qemu-user 

这里直接IDA gdb调了,或者直接gdb-multiarch

qemu-mips64 -g 8890 ./main

main_main总体逻辑还是清晰的

读取图片文件内容而后rc6+base128写出文件

https://cdn.shi1011.cn/2021/12/7f5228626a5d915f1175ab882523515d.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

先分析main_Rc6Enc

调试得到key,参考偏移0C9DB0

https://cdn.shi1011.cn/2021/12/cad281e11d42c7bfa4537482cced7d11.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

对照源码时发现有个sbox,留意对其修改的可能性

https://cdn.shi1011.cn/2021/12/9de15d2cb3e06cec7860b0be8b348b0f.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

单步调试时注意不要碰到$a4寄存器,会直接炸掉…

https://cdn.shi1011.cn/2021/12/1fe01e60c60eb1db1750387141520907.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

改了sbox,参考偏移0C9EB8

https://cdn.shi1011.cn/2021/12/e1b1adbbc46daa37aa33529591a469d2.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

注意到有个填充main_pKCS7Padding

而后看到CBC填了iv

https://cdn.shi1011.cn/2021/12/b9d4d0b959aa791f49418fb0a1b022cc.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

如下

https://cdn.shi1011.cn/2021/12/1ffc86f669f1bcba27309428b97a5bbe.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5

第一部分分析完成

简单测试下第二部分,发现base128为标准调用

直接撸脚本就可以了

修改box

// modify
var skeytable = []uint32{
	0xB8E35263, 0x541BCD1C, 0xEF5447D5, 0x8A8CC28E, 0x25C53D47, 0xC0FDB800,
	0x5C3632B9, 0xF76EAD72, 0x92A7282B, 0x2DDFA2E4, 0xC9181D9D, 0x64509856,
	0xFF89130F, 0x9AC18DC8, 0x35FA0881, 0xD132833A, 0x6C6AFDF3, 0x7A378AC,
	0xA2DBF365, 0x3E146E1E, 0xD94CE8D7, 0x74856390, 0xFBDDE49, 0xAAF65902,
	0x462ED3BB, 0xE1674E74, 0x7C9FC92D, 0x17D843E6, 0xB310BE9F, 0x4E493958,
	0xE981B411, 0x84BA2ECA, 0x1FF2A983, 0xBB2B243C, 0x56639EF5, 0xF19C19AE,
	0x8CD49467, 0x280D0F20, 0xC34589D9, 0x5E7E0492, 0xF9B67F4B, 0x94EEFA04,
	0x302774BD, 0xCB5FEF76,
}

解码后分组解密

package main

import (
	"bytes"
	"crypto/cipher"
	"fmt"
	"github.com/Mas0nShi/MHttp"
	"github.com/dgryski/go-rc6"
	"github.com/dozen/encoding/base128"
	"io/ioutil"
	"os"
)

func Pad(data []byte, blockSize uint) ([]byte, error) {
	neededBytes := blockSize - (uint(len(data)) % blockSize)
	return append(data, bytes.Repeat([]byte{byte(neededBytes)}, int(neededBytes))...), nil

}

func reverse(s []byte) []byte {
	for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
		s[i], s[j] = s[j], s[i]
	}
	return s
}

func main() {
	iv := MHttp.Str2bytes("HPRBCxAy7ziE5tR8")
	key := []byte{0x67, 0x6F, 0x6C, 0x61, 0x6E, 0x67, 0x00, 0x67, 0x6F, 0x6C, 0x61, 0x6E, 0x67, 0x00, 0x00, 0x00}
	ins, _ := rc6.New(key)

	//encrypt
	//enc := []byte("123\n")
	//enc, _ = Pad(enc, 16)
	//var ct [16]byte
	//mode := cipher.NewCBCEncrypter(ins, iv)
	//mode.CryptBlocks(ct[:], enc[:])
	//enc = reverse(ct[:])
	//println(base128.StdEncoding.EncodeToString(enc))



	// decrypt
	//var decodeDec []byte
	//var tmp [16]byte
	//testDec := "VRjぽぷlbBLばぶだHべRをでしA"
	//
	//decodeDec, _ = base128.StdEncoding.DecodeString(testDec)
	//decodeDec = reverse(decodeDec[:])
	//mode := cipher.NewCBCDecrypter(ins, iv)
	//mode.CryptBlocks(tmp[:], decodeDec[:])
	//plainText, _ := pkcs7strip(tmp[:], 16)
	//fmt.Println(string(plainText))


	var decdata []byte
	f, err := os.OpenFile("goRev/out", os.O_RDONLY, 0755)
	defer f.Close()
	if err !=nil {
		fmt.Println(err.Error())
	} else {
		decdata, err=ioutil.ReadAll(f)
	}
	
	decdata, _ = base128.StdEncoding.DecodeString(string(decdata))
	mode := cipher.NewCBCDecrypter(ins, iv)
	
	length := len(decdata)
	var ct2 []byte
	var tmp [16]byte
	
	decdata = reverse(decdata)
	for i := 0; i < length / 16; i++ {
		var plainText = decdata[i*16:i*16+16]
		mode.CryptBlocks(tmp[:], plainText[:])
		ct2 = append(ct2, tmp[:]...)
	}
	
	fmt.Println(ct2)
	f, err = os.Create("goRev/flag.png")
	defer f.Close()
	if err !=nil {
		fmt.Println(err.Error())
	} else {
		_, err=f.Write(ct2[:])
	}

}

成功拿到图片

https://cdn.shi1011.cn/2021/12/a89c89ab0ea27c1d9b0879ffeb4a87ed.png?imageMogr2/format/webp/interlace/0/quality/90|watermark/2/text/wqlNYXMwbg/font/bXN5aGJkLnR0Zg/fontsize/14/fill/IzMzMzMzMw/dissolve/80/gravity/southeast/dx/5/dy/5
本文链接:https://blog.shi1011.cn/ctf/1919
本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可

Mas0n

文章作者

发表评论

textsms
account_circle
email

翻车鱼

福建省省赛2021 闽盾杯黑盾赛道
题目名字应该是ext,听说是0解题。 某个师傅赛后发我的题,说没做出来,让我康康。 ext 拿到文件是一个mips64 golang编译的程序,另外还给了一个加密后的文件。 要注意此…
扫描二维码继续阅读
2021-12-03