# DEF CON CTF Qualifier 2019 - nodb
>###### tags: `wasm`
>[name=whysw@PLUS]
## Attachments
- problem
- [index.html](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f#file-index-html)
- [wasm.js](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f#file-wasm-js)
- [wasm.wasm](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f#file-wasm-wasm)
- writeup
- [wasm.wat](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f#file-wasm-wat)
- [wasm_57.wat](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f#file-wasm_57-wat)
- [wasm_57.wasm](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f#file-wasm_57-wasm)
Attachments are uploaded on [gist](https://gist.github.com/YangSeungWon/5af37d55f65b44e7ddb027f84897956f).
If you want to run payload, you need to change `var wasmBinaryFile = 'wasm.wasm';` to `var wasmBinaryFile = 'wasm_57.wasm'` in `function integrateWasmJS()`, in wasm.js file.
## Challenge
![](https://i.imgur.com/T3lpCPY.png)
When you press the button **Submit**, the value in the password field goes to _authenticate function of WASM.
![](https://i.imgur.com/rM1izQM.png)
## Solution
### JEB demo
WASM can be decompiled using JEB > v3.0.0.
There is many limitations in demo version, but I can find out what _authenticate function does.
![](https://i.imgur.com/TNbzNgO.png)
So the length of the flag must be 69. And variable `v8` increases if v14 is 0.
In the end, `v8` must be 69 to return `success`, so `v8` contains the information about how many characters are same with the flag.
So we can use brute force to get the flag, if we know v8 for every input.
---
### patch WASM using WAT
#### wasm2wat
Using wasm2wat in [wabt](https://github.com/WebAssembly/wabt), you can get .WAT file(webassembly text file)
```bash
~/tools/wabt/build/wasm2wat wasm.wasm > wasm.wat
```
#### patch _authenticate function
_authenticate function is func25. (we can know it through dynamic debugging)
At the end of the _authenticate function, we can see what we analyzed in decompiled source.
```csharp:wasm.wat=448 //this is not csharp file, but for highlight :)
local.get 58
local.set 49
local.get 49 // this might be v8
i32.const 1 // because 1 is added
i32.add
local.set 50
local.get 50
local.set 58
br 1 (;@1;)
end
end // at the end of the for loop,
local.get 57
local.set 51
local.get 51
i32.const 69 // v8 is XORed with 69
i32.xor
local.set 52
local.get 52
i32.const 0
i32.ne // and tested if they are same.
local.set 53
local.get 53
if ;; label = @1 // if v8 != 69
i32.const 1245 // return 1245
local.set 1
local.get 1
local.set 54
local.get 61
global.set 12
local.get 54
return
else // if v8 == 69
i32.const 1237 // return 1237
local.set 1
local.get 1
local.set 54
local.get 61
global.set 12
local.get 54
return
end
unreachable
i32.const 0
return)
```
so we can patch it to return v8 no matter v8 == 69 or not.
```csharp:wasm_57.wat=470
if ;; label = @1
local.get 57 // local variable 57 has the value of v8. check above :)
local.set 1
local.get 1
local.set 54
local.get 61
global.set 12
local.get 54
return
else
local.get 57
local.set 1
local.get 1
local.set 54
local.get 61
global.set 12
local.get 54
return
end
unreachable
i32.const 0
return)
```
#### wat2wasm
Using wat2wasm (also) in [wabt](https://github.com/WebAssembly/wabt), you can get .WASM file again.
```bash
~/tools/wabt/build/wat2wasm wasm_57.wat
```
It generates wasm_57.wasm file.
---
### Brute Force
```javascript:sol.js=
flag=""
for(i=0; i<69; i++){
for(j=32; j<128; j++){
trial = flag + String.fromCharCode(j);
trial = trial.padEnd(69,'|');
res = _authenticate(allocate(intArrayFromString(trial),'i8',ALLOC_NORMAL));
if(res == i+1){
flag += String.fromCharCode(j);
break;
}
}
}
console.log(flag);
```
output : `OOO{ifthereisnodataontheserverthereisnodatabreachproblemsolvedkthxbb}`