ACTF Junior 2019 Official WriteUP of mitu9527's Challenge

​ 鉴于本人的能力和时间问题,所以出的题目都蛮简单的,都算是入门题吧。

Misc

签到题————-听说长一点大家才看得见

​ 签到题,额,推广实验室的微信公众号,没啥好说的。

keypad

​ 这一题蛮简单的,题目(暴雪梗,你们没有手机吗?)和提示都基本是明示了。就是手机的九宫格键盘宫格密码:例如21表示a,33表示f。

base家族

​ 送分题+1,直接百度base解密,然后base64,32,16分别来一次就好了,算是为了科普base的编码吧。

wordHidden

​ 没啥好说的,flag分成两部分

上半部分:afctf{word_Hid存放在备注里面

下半部分:den_haaaaaaa}设置为隐藏字体

​ 但是我看到了一些神奇的操作,把word改名为.zip后居然可以在里面的xml配置文件中找到备注里的flag,貌似又懂了一点word的结构,感觉又是一个出题点。

Exhaustive

​ 压缩包字典攻击。使用的工具是ARCHPR,算是蛮常见的工具

​ 这一题纯粹是想要锻炼一下写脚本生成密码的能力,又或者是让新生了解一下穷举大法好。

1
2
3
4
5
6
7
8
9
import string
import itertools

with open("字典.txt",'w') as file:
charset = string.digits # + string.ascii_letters
nums = itertools.product(charset,repeat=5)
for i in nums:
num = "".join(i)
file.write('afctf{'+num+'}\n')

cheat

​ 题目算是说了找不到密码,就要想到可能是伪加密。(伪加密:实际上并没有加密,而只是修改了某个标志位,在window下显示被加密)

伪加密:下面的标志位为奇数则伪加密,为偶数则没有加密

1549521508334

​ 解决方式很简单,但是要记住,把图中的01改成偶数即可。

​ 解密后就很简单啦,只有点和线,就要脑补到摩尔斯密码,百度一下,解密完再base16解密一下即可。这里为什么要出题的时候要base16加密呢,是因为摩尔斯密码并没有区分什么大小写,和标点符号,所以要通过编码来解决这个问题。

difference

​ 这一题纯粹考验工具的使用,两个文件不一样的地方就是flag。这里可以使用010editor里的compare,当然还有很多别的工具。

xor

​ 这一题我来挨打了,我在比赛结束后看到你们交的wp,我才发现自己题目出的有问题,先说一下这道题目的思路:很简单,直接两个文件异或即可。然后我出题的方法就是先写好flag,然后再写一句长度和flag一样的语句flag_not_here_hhhhhaaaaaaa,而后两者异或,得到第三句话,然后题目提供的文件就是后两个语句的文件。具体代码如下:

1
2
3
4
5
def sxor(s1,s2):    
return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2))

with open('B.txt','w') as file:
file.write(sxor('afctf{sooooo_eeeeeasy_xor}','flag_not_here_hhhhhaaaaaaa'))

​ 这里的思路很没什么问题,但是出来的结果确实生成的文件B.txt的长度却比A.txt多了两个字节,这不科学啊!我当初没有仔细查看长度,然后直接运行了解决的代码,是可以正常跑出结果来的,所以这里疏忽了,让这个错误一直存活着。

​ 然后今天认真排查了半天,终于知道是什么问题了。原因是windows系统的锅,众所周知,windows下的换行符十六进制是0D0A,而我在windwos下异或出来中就恰好有换行符0A,并且我是转换成字符串写入文件中,所以本来一个字节的0A就变成了0D0A,而里面异或后有两个换行符,所以就多了两个字节,绝望脸。

​ 解决方式就是在linux中运行该python程序,毕竟linux中的换行符就是0A,所以不会出现这种神坑。。

​ 解决该题的代码

1
2
3
4
5
6
def sxor(s1,s2):    
return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2))

with open('A.txt','r') as file1:
with open('B.txt','r') as file2:
print(sxor(file1.read(),file2.read()))

Wireshark

​ 直接搜索afctf即可。

​ 但是这里也看到了一些骚操作,因为我当初是用get请求来保存flag的,所以可以用导出对象的方法来找到flag,更有人用string来找到flag。神奇的一匹。

draw

​ 这题不难,就单纯是为了考验写脚本能力的,题目给的文件是(R,G,B),只要把其转为图形即可,然后扫描二维码。一共67600,平分一下就是260。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding: utf-8 -*-
from PIL import Image
from operator import mod

width=260
heigh=260
im=Image.new('RGB', (heigh,width), '#ffffff')

with open('flag.txt','r') as file:
coordinate=[line.split(',') for line in file.readlines()]

num=0
for h in range(heigh):
for w in range(width):
pixel=im.getpixel((w,h))
im.putpixel((w,h),(int(coordinate[num][0]),int(coordinate[num][1]),int(coordinate[num][2])))
num += 1
im.save('111.png')
im.close()

Forensics

log

​ 这题其实很简单,直接查看系统日志,然后在里面寻找即可,分值高的原因是,windows的日志上限很小,就2M,要是最后在来弄这个的话,是有可能找不到的。

Visiting history

​ 简介和题目都说了是访问历史,然后也只有一个游览器edge,直接在edge里的访问历史看就好了,网页名字都直接是flag了,然后在注释中,查看源码即可。

Hidden

​ 啥也不好了,隐藏,隐藏文件,所以设置以下隐藏文件可见即可。内容是ascii码转为16进制。

jpg

​ jpg图片的结构特点,FFD8开头,FFD9作为图片的结束,在FFD9后面加入任何东西不会影响图片的显示。

​ 本题用010editor打开jpg图片,发现ffd9后面还有内容,再看内容的开头,发现是一个压缩包,将其拷出来即可,压缩包密码在备注里。

​ 打开后可以获得第一个flag,然后里面还有一张png图片。

​ 这张图片就纯粹靠经验,一个一个方法试过去,又或者可以通过16进制看图片,发现里面的结构有特殊的块,所以可以去想着去查看图层。

​ 这里还有个坑,要用Adobe Fireework CS6才能看到里面的图层没然后CS6居然停产了。。。好吧,是我坑爹了。这里还有最后一个坑,flag的图层透明度为100%,所以要修改后才能看见。

png

​ 作为中南大学的学生,发现校徽都不完整,所以要想到时图片的高度被人修改过了,所以修改图片的高度即可看到flag。

can’t

​ 这里可以通过命令行来创建文件,以此绕过文件名字限制。所以图形化什么的,还是命令行好用(滑稽)

​ 那个程序的源码如下:(够简陋,勿吐槽)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;

int main()
{
FILE *fp; // 头文件#include <stdio.h>
int a;
if((fp=fopen(".flag","r"))==NULL)
{
printf("需要在当前目录下创建文件:.flag\n");
cin >> a;
}
else{
printf("恭喜获得flag:flag{3o_ea3y_233333} \n");
cin >> a;
}
return 0;
}