前言
国外的比赛确实要不一样一点,有机会多打打。
而且,u1s1,这比赛平台的前端是真的帅!!!
padlock
附件是c文件,还是个锁状。(很好,下次校赛出题我知道怎么搞了,嘿嘿嘿。)
直接一手编译。
运行exe,随便输入有发现回显,而且这提示的也太明显了吧…
直接一手subprocess逐位爆破
import subprocess
import time
flag=b""
tmp=b""
for j in range(100):
for i in range(32,128):
flag=tmp+bytes([i])
p = subprocess.Popen(["./quine.exe",flag], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
output = p.communicate()[0].decode()
if ( 'O'*(j+1) == output[2:3+j]):
tmp+=bytes([i])
break
print(tmp)
print(tmp)
官方wp好像是用pwntools解的,感觉也是一个很好的解题方法
chicago
这道题出的不好,好像有些人是一开始想看回显的时候,随手构造了一串数字,结果阴差阳错,直接出flag了…
主逻辑
如果输入的是0,那么不管你什么奇数不奇数位,乘不乘2,最后都是0。最后0==0,直接cat flag。
EXP?10个0!
直接构造10个0
babynaoh
看了最久的一题,可惜比赛没有解出来。
表面上是个地图题?感觉就是一个vm题。
注意:这题nc环境最多只让你输入8行。
主逻辑
前面的代码就不贴了,因为这题是nc环境,前面代码就是读远程目录下的flag.txt。如果你想本地跑,记得加上两个参数 max_row_num xxx.txt
指令集
instance = map[24 * row + col];
switch ( map[24 * row + col] )
{
case '!':
if ( tos <= 0 )
return 2LL;
v4 = valye_24;
v5 = offset_row;
v6 = value_50;
stack[tos - 1] = stack[tos - 1] == 0; // if is zero?
v3 = offset_col;
goto LABEL_6;
case '#':
v1 = tos;
if ( tos <= 0 )
return 2LL;
stack[tos] = stack[tos - 1];
goto LABEL_4;
case '%':
if ( tos <= 1 )
return 2LL;
v17 = tos - 1;
stack[tos - 2] %= stack[tos - 1];
goto LABEL_35;
case '&':
if ( tos <= 1 )
return 2LL;
v17 = tos - 1;
stack[tos - 2] &= stack[tos - 1];
goto LABEL_35;
case '*':
v20 = tos;
if ( tos <= 1 )
return 2LL;
v5 = offset_row;
--tos;
v6 = value_50;
stack[v20 - 2] *= stack[v20 - 1];
v3 = offset_col;
v4 = valye_24;
goto LABEL_6;
case '+':
if ( tos <= 1 )
return 2LL;
v17 = tos - 1;
stack[tos - 2] += stack[tos - 1];
goto LABEL_35;
case ',':
if ( tos <= 1 )
return 2LL;
v18 = tos - 1;
v19 = stack[tos - 2];
stack[tos - 2] = stack[tos - 1];
v4 = valye_24;
stack[v18] = v19;
v5 = offset_row;
v3 = offset_col;
v6 = value_50;
goto LABEL_6;
case '-': //构造循环时需要
if ( tos <= 1 )
return 2LL;
v2 = tos - 1;
stack[tos - 2] -= stack[tos - 1];
goto LABEL_5;
case '.':
if ( tos <= 0 )
return 2LL;
putc(stack[tos - 1], stdout);
v3 = offset_col;
v4 = valye_24;
v5 = offset_row;
v6 = value_50;
goto LABEL_6;
case '/':
if ( tos <= 1 )
return 2LL;
v17 = tos - 1;
stack[tos - 2] /= stack[tos - 1];
LABEL_35:
tos = v17;
v3 = offset_col;
v4 = valye_24;
v5 = offset_row;
v6 = value_50;
goto LABEL_6;
case ':':
if ( tos <= 0 )
return 2LL;
__printf_chk(1LL, "%d", (unsigned int)stack[tos - 1]);
v3 = offset_col;
v4 = valye_24;
v5 = offset_row;
v6 = value_50;
goto LABEL_6;
case '<': // 左
v4 = valye_24;
v6 = value_50;
v5 = 0;
offset_col = -1;
offset_row = 0;
v3 = -1;
goto LABEL_6;
case '>': // 右
v4 = valye_24;
v6 = value_50;
v5 = 0;
offset_col = 1;
offset_row = 0;
v3 = 1;
goto LABEL_6;
case '@': // end
return 1LL;
case '^': // 上
v4 = valye_24;
v6 = value_50;
v5 = -1;
v3 = 0;
offset_col = 0;
offset_row = -1;
goto LABEL_6;
case '_':
if ( tos <= 0 )
return 2LL;
offset_row = 0;
v4 = valye_24;
v6 = value_50;
v5 = 0;
v3 = stack[tos - 1] == 0 ? 1 : -1;
offset_col = v3;
goto LABEL_6;
case 'g': //获得地图的值并存在stack数组里,设置循环时有用
if ( tos <= 1 )
return 2LL;
v13 = tos - 2;
v14 = stack[v13];
if ( v14 < 0 )
return 2LL;
v4 = valye_24;
v15 = v14;
if ( v14 >= valye_24 )
return 2LL;
v16 = stack[tos - 1];
if ( stack[tos - 1] < 0 )
return 2LL;
v6 = value_50;
if ( v16 >= value_50 )
return 2LL;
--tos;
v5 = offset_row;
v3 = offset_col;
stack[v13] = map[v15 + valye_24 * v16];
goto LABEL_6;
case 'p':
v8 = tos;
if ( tos <= 2 )
return 2LL;
v9 = stack[tos - 3];
if ( v9 < 0 )
return 2LL;
v4 = valye_24;
v10 = v9;
if ( v9 >= valye_24 )
return 2LL;
v11 = stack[tos - 2];
if ( v11 < 0 )
return 2LL;
v12 = v11;
v6 = value_50;
if ( v12 >= value_50 )
return 2LL;
tos -= 3;
map[v10 + valye_24 * v12] = stack[v8 - 1];
v3 = offset_col;
v5 = offset_row;
goto LABEL_6;
case 'v': // 向下移动
v4 = valye_24;
v6 = value_50;
v5 = 1;
v3 = 0;
offset_col = 0;
offset_row = 1;
goto LABEL_6;
case '|':
if ( tos <= 0 )
return 2LL;
offset_col = 0;
v4 = valye_24;
v6 = value_50;
v3 = 0;
v5 = stack[tos - 1] == 0 ? 1 : -1;
offset_row = v5; // 根据stack[tos-1]的值选择上下走
goto LABEL_6;
case '~':
if ( tos <= 0 )
return 2LL;
v2 = tos - 1;
goto LABEL_5;
default:
v1 = tos;
if ( tos > 99 )
return 2LL;
stack[tos] = 0;
LABEL_4:
v2 = v1 + 1;
LABEL_5:
tos = v2;
v3 = offset_col;
v4 = valye_24;
v5 = offset_row;
v6 = value_50;
LABEL_6:
col = (v4 + v3 + col) % v4;
mile += instance + 1;//注意这个+1,后面推算的时候老是忘记...
row = (v6 + v5 + row) % v6;
if ( mile > 0x313370 )//Tnnd,这里被骗了,做题的时候忘记前面的mile=0x31337,单看这里还以为最后要等于0x313370才正确,我还试了半天,发现mile很难达到这么大。
return 2LL;
else
return 0LL;
}
}
其他值:使stack[tos]=0(tos不能大于99),tos++。
方向值:只改变偏移
‘#’ :stack[tos]=stack[tos-1] tos=tos+1
‘|’ :如果stack[tos-1]=0 向下,!=0 向上
‘!’ :stack[tos-1]=0?1:0
‘g’ :stack[tos-2]=map[stack[tos-2]+24*stack[tos-1]] tos–
‘-’ :stack[tos-2]-=stack[tos-1] tos=tos-1
…很多没使用到的我就没写
需要你自己构造一个地图,终点是@,要求最后mile的值要等于0x31337。
地图最大是50x24,但是这题nc环境最多只允许你输入8行,即8*24=192。所以就算每个块都填0xff,乘以192也不可能达到0x31337。
其实解法很简单,就是要构造一个循环。后面自己悟吧,其实逻辑挺简单的。
这个是我自己构造出来的地图,仅供参考。
EXP
官方wp模板直接拿来用,不得不说,还是得会一手pwntools,交互场景下太好用了。
from pwn import *
r = remote("babynoah.bctf23-codelab.kctf.cloud", 1337)
r.recvuntil(b"voyage:")
payload = [
b">0#!g>>>0>>v ",
b"\xc4 ^ v ",
b" |-!<<< ",
b" >>>>>v ",
b" @c<<<<<<< ",
b" ",
b" ",
b" ",
]
payload = b"\n".join(payload)
r.sendline(payload)
r.interactive()
成功打通!
完结撒花✿✿ヽ(°▽°)ノ✿
评论区