本文转载自: github.io
如若转载,请注明出处: https://jianghuxia.github.io/2018/09/03/Codefest2018-CTF/
实在是太无聊了,找了找比赛打,Codefest2018
这个感觉跟以往的ctf比赛不同,感觉更偏向代码能力的考查,以下是这次自己做出来的题目writeup,比赛题目一共15
道,菜鸡一枚,只做出10
道。
Freebies
problem
This one’s simple. Join the Slack channel to get the flag.
这题算是签到题,但也是寻找了好一番,就不放答案了
Fortune Cookie
problem
H4k3r has heard that there is a secret hidden behind this website, but he is confused as to how to get access to it. Can you help him
这题,呃,很简单,该下cookies(说着简单,最后试了半天才发现是admin,不是Admin)
Who are you?=admin
即可
Typing Master
problem
If you think you have it in you, connect now to 34.216.132.109 9093 and prove your mettle.
You will be presented with a simple typing task which is meant to check your typing speed.
For example, Can you type ‘Z’ 10 times followed by ‘u’ 6 times, followed by the sum of their ASCII values?
ZZZZZZZZZZuuuuuu207
Input Format
Regarding input to the server – The question was designed keeping netcat in mind. Some users who are using other tools/language (eg, Python, PuTTY, TELNET) to connect to the server please note that they do not terminate the strings like netcat does. If you choose not to use netcat, the message you send to our server should terminate with a trailing newline (‘n’) and nothing else.
nc下,先看看大概是啥样子的
发现每次访问,要求的都不一样,甚至返回的字符串也不一样,想了想,觉得还是一个脚本的事,需要正则一下即可
脚本如下:
#-*-coding:utf-8
from pwn import *
import re
conn=remote('34.216.132.109',9093)
text=conn.recv()
print text
result = re.findall(r"'(w)' (d*)", text)
#print result
#print result[0][0]
#print result[0][1]
str1=(result[0][0] * int(result[0][1]))
str2=(result[1][0] * int(result[1][1]))
str3=(str(ord(result[0][0]) + ord(result[1][0])))
S = ''.join(str1+str2+str3)
print S
conn.sendline(S)
print conn.recv()
运行结果
最终答案:CodefestCTF{1_s33_y0u_4r3_a_m4n_0f_sp33d}
Web BooK
problem
It is expected to complete reading a book/novel to pass the course, but the students being clever avoid reading the whole book by going through the summary only. Santosh(their course teacher) comes up with a new idea, he creates a magic book (you can only go to next page, that is: you can’t go to next page without reading the previous one and so on, and you can only start from the beginning). It is know that the flag is hidden somewhere in the book, so the only way to pass the course is to read the whole book, find the flag. The book has 1000 pages so better be fast. And if you are lucky, you may even find the key on the very first page itself. link to Web_BooK
打开网站,发现如下页面,点击next发现,都是没有规则的url
没办法,只能简单爬虫脚本写下,源码如下
#-*-coding:utf-8
import requests
import re
url = 'http://34.216.132.109:8083'
page = '/fp/'
s = requests.Session()
counter = 0
while (True):
counter += 1
r = s.get(url + page)
page_text = r.text
print page_text
page = re.findall('action="(.*?)"', page_text)[0]
print page, counter
运行下
Access Denied?
problem
A school IT staff manages access to secure files by the method of access code. You are required to give your name and the access code, and the program will give out secret information.
It checks whether you already have an access code, generates new random one along with a new user ID alloted to the user, if that user is not found locally on the system. The access codes are known to have random expiration time (don’t know what goes on in their minds!), so don’t be surprised if you generated an access code just seconds ago and next time the same access code doesn’t work.
Johnny decided to go into the IT room and copy the program into his pendrive. You can find it here.
Can you get the secret information out from the program? The service runs on 34.216.132.109 on port 9094.
Constraints
User ID / UID will be a positive integer
这题给了个school.py
#-*-coding:utf-8
import random
import user_functions
user = raw_input("Enter your name: ")
if not user_functions.exists(user):
# generate a code
count_ = user_functions.generateID(user)%1000 #User ID/ UID in the table is always positive
generator = "xorshift"
random.seed(generator)
count = 0;
for ch in user:
ra = random.randint(1, ord(ch))
rb = (ord(ch) * random.randint(1, len(user))) ^ random.randint(1, ord(ch))
count += (ra + rb)/2
code = 1
for i in range(1,count+count_):
code = (code + random.randint(1, i) ) % 1000000
final = random.randint(1,9) * 1000000 + code
#store it in the database
user_functions.store(user, final)
else:
#if user already exists, fetch access code
final = user_functions.get_code(user)
code = raw_input("Enter your access code: ").strip()
while True:
if code.isdigit():
if (int(code) == final):
print "The flag is " + user_functions.get_flag(user)
exit()
else:
print "Incorrect access code"
else:
print "The code must be an integer"
code = (raw_input("nPlease enter the code: "))
print "n###############################################"
乍一看好像挺复杂的,其实不然,只需要爆破即可,简单分析下
起始变量count
是由我们输入的user
确定的。如果我们每次测试时都提供相同的user
,那么最终count
变量也都是不变的;而count_
变量嘛,虽然不知道到底是什么嘛,但是模1000
得到的结果只可能是[0,999]
;而code
呢?由于code
种子xorshift
生成的,我们可以根据count_
遍历code
。只需要稍微改改给的school.py我们就可以暴力跑出答案。
核心代码其实也就是下面这个:
for i in range(0,1000):
count_ = i
# the seed is always the same
generator = "xorshift"
random.seed(generator)
count = 0;
for ch in user:
ra = random.randint(1, ord(ch))
rb = (ord(ch) * random.randint(1, len(user))) ^ random.randint(1, ord(ch))
count += (ra + rb)/2
code = 1
for i in range(1,count+count_):
code = (code + random.randint(1, i) ) % 1000000
final = random.randint(1,9) * 1000000 + code
完整代码如下:
#-*-coding:utf-8
from pwn import *
import sys
list_code = []
user = 'jianghu'
for i in range(0,1000):
count_ = i
generator = "xorshift"
random.seed(generator)
count = 0;
for ch in user:
ra = random.randint(1, ord(ch))
rb = (ord(ch) * random.randint(1, len(user))) ^ random.randint(1, ord(ch))
count += (ra + rb)/2
code = 1
for i in range(1,count+count_):
code = (code + random.randint(1, i) ) % 1000000
final = random.randint(1,9) * 1000000 + code
list_code.append(final)
print list_code
con = remote('34.216.132.109',9094)
con.recvuntil('Enter your name: ')
con.sendline(user)
for i in list_code:
text = con.recv()
if 'flag' not in text:
con.sendline(str(i))
else:
print text,i
sys.exit()
运行结果如下
最终答案:CodefestCTF{1_s33_y0u_4r3_a_m4n_0f_r4nd0mn3ss}
It’s Magic
problem
Repair given corrupted file to get the flag. download file here
下载完毕后,拖到winhex里,拖到尾部发现FFD9
,尝试改文件头,发现无效
遂尝试网上搜索在线修复受损图片,找到一个工具网站
修复完成后,打开即有flag
最终答案:CodefestCTF{mAgic_byTes}
Hidden Agenda
problem
Just before getting caught in Russia, MI-6 agent John Stegwal sent a mail to MI-6 containing two visually similar images. It is possible that the images contain information on how to access his findings. Can you find the message he sent?
给了两个jpg
文件:image1.jpg
与image2.jpg
。
先用StegSolve
将image1.jpg
与image2.jpg
来次xor
,发现有个二维码的痕迹,保存为solved.bmp
将solved.bmp
与image1.jpg
再来一次MUL,得到一个可扫的清晰二维码
扫出来是个网址https://drive.google.com/file/d/13chbULOlKaOM_jI8_RaxECZ0xzJUg7Y4/view
,打开后,有张图片,下载下来,打开后可以看到清晰的flag{
字样,然后,没然后了,这张图片只有flag{
(那时候看到flag,开心极了,贼坑)
没事,我吃柠檬。谷歌了下,找了找有关jpg
图片隐写,找到了个jsteg
,哟,试试
先试试image1.jpg
,试出东西来了
得到了个flg.exe
,winhex
看下,没看懂是啥
file
下,发现是个MP3
改后缀名,听了听,这是鸟叫声?exm
?拖到Adobe Audition CC2017
试试,查看了下频谱图
得到最终答案:CodefestCTF{0b5cur17y > 53cur17y}
Thunder
此题给了个流量包thunder.pcap
,包不大,分析发现好几个flag.jpg
,但是都是不完整的。
尝试根据jpg
文件的文件格式来拼图。先导出http
对象,删除重复的。此题有个坑点,不可以按照分组序号的大小来拼,必须按照TCP
流所显示的时间依小到大排序,然后拼好即可。
人懒,写了个bat
脚本1.bat
type flag*.jpg>>all.jpg
以下是all.jpg
得到最终答案:CodefestCTF{AP_is_amazing}
Polyglot
problem
Chetu writes code with weird whitespace, and nobody knows why. He uses his own C interpreter, which is probably the only thing that can handle his absurd code. He insists its more secure this way. Since no one ever believes him, he demonstrated his technique on this vulnerable code. Can you get the flag?
这题贼有意思,贼好玩。题目给了两个文件,但是做这题,我只用了c
代码的文件,另外一个elf
都没看。
首先我们看看c
代码:
会发现,这些数字排序,怎么都是空那么多格子的呢?奇怪,但是突然想起了写python
脚本时,会因为空格和tab
混淆而报错,下意识看看这些空白字符是由什么构成的。Notepad++
有个功能
果然,这些空白字符是由不同的空格字符和制表符组成。尝试先用脚本读读
果然,猜想是正确的,那么现在需要提取下这些空白的字符。想到了正则表达式,其中s
表示只要出现空白就匹配。但是匹配完后有什么用了?随即想到有没可能是0
,1
替换,到时候来个二进制转换ASCII
可见字符。尝试一波,先匹配试试,然后‘t’
替换成1
,‘ ’
替换成0
,得到了想要的答案
最终答案:CodefestCTF{sP4c3S AnDtAb5}
Intercept
problem
Garry encrypted a message with his public key and mailed it to Monika. Sure Garry is an idiot. The intercepted mail is given below as seen from Monika’s side. Decrypt the message to get the key. interceptedMail.eml
下载文件后,发现eml
中存在zip
,base64
解码下
有两个文件,flag.enc
是密文,但是私钥哪去了呢?其实在下面那个文件里。
其中Public_Key_Encryption_.docx
实际上是是个压缩包,winhex
下看到了PK
的头
改后缀名,解压。寻找一番没找到私钥。最后才发现,在解压文件中wordmedia
,存在三张图片
其中的image1.png
的尾部存在私钥
那么,提取出来,保存为private.pem
额,openssl
解密下,执行命令openssl rsautl -decrypt -in flag.enc -inkey private.pem -out flag.txt
最终答案:CodefestCTF{kristeinStewart_is_5EXY}