CTF预备队考核赛
比赛网址:http://47.96.150.181:8000
WEB
逆转思维
参考这个:https://xz.aliyun.com/t/6458
原题,一模一样。
easyphp
<?php
if(isset($_GET['password'])){
if(strcmp($_GET['password'],"******") == 0){ //上传一个password,随便传啥都行
if(isset($_GET['a']) && md5($_GET['a'])==0){ //a不为空,而且md5值以'0e'开头
system($_GET['cmd']); //满足条件就执行cmd
}
else
die("funny_md5!"); //以下的三个else分别对应三个if
}
else
die("wrong password!");
}
else {
die("password!");
}
?>
分析一下php代码:
1.strcmp()
是比较两个字符串:
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str2 小于 str1。
如果返回值 = 0,则表示 str1 等于 str2。
而数组跟任意字符的比较都为True,所以这里用数组绕过。
if(isset($_GET['a']) && md5($_GET['a'])==0){ //a不为空,而且md5值以'0e'开头
system($_GET['cmd']); //满足条件就执行cmd
}
isset()
函数判断上传是否为空,不空则返回True。
后面的md5($_GET['a'])==0
,只需要a的md5值是以0e开头,因为在识别的时候当做数字识,都是0。这里我利用1tm
的md5值为0ec66b3cfa13b8778caf01be
来绕过。
3.绕过之后,需要利用system函数。先ls一下,判断出具体有哪几个文件,再cat。
这里先构造url:http://47.96.150.181:5002/?password[]=11&a=1tm&cmd=ls
但是接下来我在cat的时候居然cat不出来: 图片.png
然后盲猜这些都是目录,于是用
ls /
试试:http://47.96.150.181:5002/?password[]=11&a=1tm&cmd=ls%20/
图片.png
这里出现了flag字样,开心。于是:
http://47.96.150.181:5002/?password[]=11&a=1tm&cmd=cat /flag
flag{I_think_it_is_easy}
flag{I_think_it_is_easy}
MISC
checkin
首先下载文件,是一张图片。放kali里面binwalk一下,有一个压缩包zip
图片.png
利用命令把压缩包分离: 图片.png
得到一个新的压缩包 图片.png
然后解压得到一个word文档,flag就在那里,看不到,但是把画红色下划线的部分复制出来就行了
{lalala_mhtzjl}
然后前面加上flag:flag{lalala_mhtzjl}
password and no password
下载文件,得到一个压缩包,解压需要密码,但是部分文件不需要密码也能查看 图片.pngwinhex打开图片,拉到底,看到 图片.png
密码到手,解压得到flag.zip压缩包。根据题目提示,no password,伪加密?试了一下,successful。 把这里改成0000
图片.png
保存
flag{zjnu_hahaha_surprise_huanqi12387}
CRYPTO
Ook
首先下载文件,得到1.TXT,里面是一串brainfuck代码。
https://tool.bugku.com/brainfuck/
利用改网站解码,把密文复制进去,点击brainfuck TO text,得到ook,然后点 ook TO text,得到flag,但是出题人脑子有坑,zjnu搞成了ZNJU,位置变一下就行了。
RE
adultre
下载文件,文本方式打开后,是一个java的源码。没经过编译,看不懂但是能猜测大概意思。
import java.util.Scanner;
public class Main {
private static int[] enc = { //定义了enc是啥(一个数组)
112, 118, 107, 113, 133,
116, 107, 96, 107, 105,
59, 125, 105, 126, 114,
111, 105, 108, 61, 125,
126, 105, 118, 107, 120,
113, 127, 107, 113, 111,
105, 59, 120, 105, 126,
114, 111, 105, 129, 58,
124, 59, 110, 135
};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in); //这一块不知道在干啥,但是应该是输入之类的
System.out.println("Please input the flag: ");
String str = sc.nextLine();
boolean f = false;
if (str.length() != 44) { //str.length不能超过44(不太懂)
System.out.println("Wrong Answer");
System.exit(0);
}
for (int i = 0; i < str.length(); i++) { //这里才是重点,前面已经输入了一个str,str的每一位都加了10(ASCII码),如果等于数组中的元素,那f为false,不然就为True
if ((str.charAt(i)) + 10 != enc[i]) {
f = true;
break;
}
}
if (f) {
System.out.println("Wrong Answer"); //这里我们知道如果是True,那就不是正确的flag,所以必须是false。而要false的话,根据上一块,可以知道flag的每一位加上10之后都等于数组,所以逆过来想,数组的每一位减去10就是flag
} else {
System.out.println("Right! This is the flag!");
}
}
}
所以我们来写脚本(C语言写比较方便)
#include <stdio.h>
int main()
{
int enc[] = {
112, 118, 107, 113, 133,
116, 107, 96, 107, 105,
59, 125, 105, 126, 114,
111, 105, 108, 61, 125,
126, 105, 118, 107, 120,
113, 127, 107, 113, 111,
105, 59, 120, 105, 126,
114, 111, 105, 129, 58,
124, 59, 110, 135
};
for (int i=0;i<100;i++) //这里不知道有几位,多一点所以放了100,当然也可以数一下
printf("%c",char(enc[i]-10));
return 0;
}
运行结果:
图片.png
因为脚本上写的是100,所以后面会多出一堆无意义字符。flag:flag{jaVa_1s_the_b3st_language_1n_the_w0r1d}