# Grey Cat The Flag 2023 Qualifiers
# WEB
Long
https://github.com/longkd719/CTFWriteUps/tree/main/2023/Grey%20CTF%202023%20Quals
# CRYPTO
Quốc
https://hackmd.io/@GP1HnYyzQ3CATjnYWZeo4Q/BJ-H-sirn
# PWN
Quang
https://github.com/wan-hyhty/CTFs_competition/tree/main/grey_cat_2023#readme
# REV
## Crackme1
Đầu tiên deofuscation lại code:
```
window['addEventListener']('load', () => {
document['getElementById']('submitButton')['addEventListener']('click', buttonClick);
});
function buttonClick() {
var key = document['getElementById']('textKey')['value'];
// We replicate the key up to a length of 0x400
while (key['length'] < 0x400)
key = key + key;
key = key['substring'](0x0, 0x400);
display_image(key);
var cipher = [0xc3, 0xb8, 0xb3, 0x42, 0xb6, 0xc2, 0x1c, 0xa4, 0xce, 0x45, 0x6, 0x3b, 0x1f, 0x1c, 0x66, 0xb1, 0x6c, 0x9a, 0x36, 0xe5, 0x14, 0xbf, 0x18, 0x6e],
key_sched = rc4(key, 0x18),
flag = '';
for (var i = 0x0; i < 0x18; ++i) {
flag += String['fromCharCode'](cipher[i] ^ key_sched[i]);
}
if (flag['startsWith']('grey{')) document['querySelector']('#flag')['textContent'] = flag;
}
function rc4(key, len) {
var a = [],
j = 0x0,
tmp, permutation = [];
for (var i = 0x0; i < 0x100; i++) {
a[i] = i;
}
for (i = 0x0; i < 0x100; i++) {
j = (j + a[i] + key['charCodeAt'](i % key['length'])) % 0x100;
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
i = 0x0, j = 0x0;
for (var k = 0x0; k < len; k++) {
i = (i + 0x1) % 0x100;
j = (j + a[i]) % 0x100;
tmp = a[i];
a[i] = a[j];
a[j] = tmp;
permutation['push'](a[(a[i] + a[j]) % 0x100]);
}
return permutation;
}
```
Thực hiện check key trong hàm `display_image(key)`
Hàm display_image()
```
function display_image(input) {
var a = [0x0, 0x0, 0x0, 0x0],
b = [0x0, 0x0, 0x0, 0x0],
c = [0x0, 0x0, 0x0, 0x0],
d = [0x0, 0x0, 0x0, 0x0],
e = [0x41, 0x41, 0x41, 0x41];
for (var i = 0x0; i < 0x104; ++i) {
const _0x3d0205 = init_buffer_vertex(context_canvas, new Float32Array(a), a_shader),
_0x1bbc48 = init_buffer_vertex(context_canvas, new Float32Array(b), b_shader),
_0x12ff68 = init_buffer_vertex(context_canvas, new Float32Array(c), c_shader),
_0x358438 = init_buffer_vertex(context_canvas, new Float32Array(d), d_shader),
_0x31fd87 = init_buffer_vertex(context_canvas, new Float32Array(e), e_shader),
_0x5efde3 = context_canvas['createTransformFeedback']();
context_canvas['bindTransformFeedback'](context_canvas['TRANSFORM_FEEDBACK'], _0x5efde3);
const feedback_shader = init_buffer(context_canvas, a['length'] * 0x4);
context_canvas['bindBufferBase'](context_canvas['TRANSFORM_FEEDBACK_BUFFER'], 0x0, feedback_shader);
context_canvas['bindTransformFeedback'](context_canvas['TRANSFORM_FEEDBACK'], null);
context_canvas['bindBuffer'](context_canvas['ARRAY_BUFFER'], null);
context_canvas['useProgram'](program12);
context_canvas['bindVertexArray'](_0x37ea82);
context_canvas['bindTransformFeedback'](context_canvas['TRANSFORM_FEEDBACK'], _0x5efde3);
context_canvas['beginTransformFeedback'](context_canvas['POINTS']);
context_canvas['drawArrays'](context_canvas['POINTS'], 0x0, a['length']);
context_canvas['endTransformFeedback']();
context_canvas['bindTransformFeedback'](context_canvas['TRANSFORM_FEEDBACK'], null);
// We get the feedback from the WebGL shader
const f = new Float32Array(a['length']);
context_canvas['bindBuffer'](context_canvas['ARRAY_BUFFER'], feedback_shader);
context_canvas['getBufferSubData'](context_canvas['ARRAY_BUFFER'], 0x0, f);
for (var j = 0x0; j < 0x4; ++j) {
d[j] = Math['round'](f[j]) % 0x100;
e = e['fill'](input['charCodeAt'](d[j]));
a[j] = matrix1[d[0x0]][j];
b[j] = matrix2[d[0x0]][j];
c[j] = matrix3[d[0x0]][j];
}
context_canvas['uniform4fv'](s_shader, d);
context_query_c['clearColor'](0x0, 0x0, 0x0, 0x0), context_query_c['clear'](context_canvas['COLOR_BUFFER_BIT']);
context_query_c['useProgram'](program34);
context_query_c['activeTexture'](context_query_c['TEXTURE0'] + 0x1);
context_query_c['bindTexture'](context_query_c['TEXTURE_2D'], _0x3d5c0d);
context_query_c['texParameteri'](context_query_c['TEXTURE_2D'], context_query_c['TEXTURE_WRAP_S'], context_query_c['CLAMP_TO_EDGE']);
context_query_c['texParameteri'](context_query_c['TEXTURE_2D'], context_query_c['TEXTURE_WRAP_T'], context_query_c['CLAMP_TO_EDGE']);
context_query_c['texParameteri'](context_query_c['TEXTURE_2D'], context_query_c['TEXTURE_MIN_FILTER'], context_query_c['NEAREST']);
context_query_c['texParameteri'](context_query_c['TEXTURE_2D'], context_query_c['TEXTURE_MAG_FILTER'], context_query_c['NEAREST']);
// We need to have d[0x1] = 1 to display the good image!
context_query_c['activeTexture'](context_query_c['TEXTURE0']), context_query_c['bindTexture'](context_query_c['TEXTURE_2D'], array_images[d[0x1]]);
context_query_c['bindVertexArray'](_0x5745db), context_query_c['drawArrays'](context_query_c['TRIANGLES'], 0x0, 0x6);
}
}
```
Script tìm key:
```
import sys
matrix1 = [[0x1, 0x0, 0x1, 0x1], ...]
matrix2 = [[0xe5, 0x0, 0x0, 0x0], ...]
matrix3 = [[0x0, 0x0, 0x0, 0x0], ...]
def compute(a,b,c,d,e):
res = a * d + b + c * e
#print(res)
if res >= 0:
return res % 256
else:
return - ((-res) % 256)
if __name__ == '__main__':
key = bytearray([0 for i in range(20)])
a = [0x0, 0x0, 0x0, 0x0]
b = [0x0, 0x0, 0x0, 0x0]
c = [0x0, 0x0, 0x0, 0x0]
d = [0x0, 0x0, 0x0, 0x0]
e = [0x41, 0x41, 0x41, 0x41]
for i in range(0x104):
if b[2] != 0:
key[d[3]] = -b[2]
e = [key[d[3]] for j in range(4)]
if d[2]:
d = [0 for j in range(4)]
else:
d = [compute(a[j],b[j],c[j],d[j],e[j]) for j in range(4)]
a = matrix1[d[0]].copy()
b = matrix2[d[0]].copy()
c = matrix3[d[0]].copy()
key_string = key.decode('utf-8')
print("The key is: " + key_string)
```
Key:`REDchickenPIE`
Flag:`grey{y0u_h4d_fun?_e4a3d}`
## Crackme3
Scirpt
Dùng angr để giải:
```
import angr
import claripy
import logging
#logging.getLogger('angr.sim_manager').('DEBUG')
p = angr.Project("./crackme3", auto_load_libs = False)
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(24)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')])
st = p.factory.entry_state(
args=['./crackme3'],
add_options=angr.options.unicorn,
stdin=flag
)
sm = p.factory.simulation_manager(st)
while True:
#print(sm)
sm.run(until=lambda sm_: len(sm_.active) > 1)
for i in sm.active:
i.add_constraints(i.mem[0x408184].uint16_t.resolved == 0)
if len(sm.active) == 0:
break
print(sm)
y = []
for x in sm.deadended:
if b"Wrong" not in x.posix.dumps(1):
y.append(x)
print(y[0].posix.dumps(0))
```
Flag: `grey{r_y0u_d1zzy?_9bfad}`
# misc
## beepboop
https://github.com/KMANVK/CTF_Wu/tree/main/Greycat%20CTF%20Quals%202023/Misc