2021西湖论剑-wp
Posted 满天星ak
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021西湖论剑-wp相关的知识,希望对你有一定的参考价值。
2021西湖论剑-wp
前言
全靠大佬打,我是划水的。
灏妹的web
页面开发中
Dirsearch扫一下,idea泄露
ezupload
查看页面源代码,发现提示
?source=1
发现使用_FILE进行上传,构造上传表单
访问并随便上传一个文件,放到bp里回显no
查看源码最后一个else,在此情况进行渲染temper/index.latte,同时文件也被写入temper。也就是我们上传index.latte的文件。
waf测试
if “$nl /f*>1
”/if
然后上传,最后访问url/1。
密码人集合
nc连接
可知为数独
https://www.jb51.net/article/110940.htm 借此脚本
#coding=utf-8
import datetime
class solution(object):
def __init__(self,board):
self.b = board
self.t = 0
def check(self,x,y,value):#检查每行每列及每宫是否有相同项
for row_item in self.b[x]:
if row_item == value:
return False
for row_all in self.b:
if row_all[y] == value:
return False
row,col=x/3*3,y/3*3
row3col3=self.b[row][col:col+3]+self.b[row+1][col:col+3]+self.b[row+2][col:col+3]
for row3col3_item in row3col3:
if row3col3_item == value:
return False
return True
def get_next(self,x,y):#得到下一个未填项
for next_soulu in range(y+1,9):
if self.b[x][next_soulu] == 0:
return x,next_soulu
for row_n in range(x+1,9):
for col_n in range(0,9):
if self.b[row_n][col_n] == 0:
return row_n,col_n
return -1,-1 #若无下一个未填项,返回‐1
def try_it(self,x,y):#主循环
if self.b[x][y] == 0:
for i in range(1,10):#从1到9尝试
self.t+=1
if self.check(x,y,i):#符合 行列宫均无条件 的
self.b[x][y]=i #将符合条件的填入0格
next_x,next_y=self.get_next(x,y)#得到下一个0格
if next_x == -1: #如果无下一个0格
return True #返回True
else: #如果有下一个0格,递归判断下一个0格直到填满数独
end=self.try_it(next_x,next_y)
if not end: #在递归过程中存在不符合条件的,即 使try_it函数返回None的项
self.b[x][y] = 0 #回朔到上一层继续
else:
return True
def start(self):
begin = datetime.datetime.now()
if self.b[0][0] == 0:
self.try_it(0,0)
else:
x,y=self.get_next(0,0)
self.try_it(x,y)
for i in self.b:
print i
end = datetime.datetime.now()
print '\\ncost time:', end - begin
print 'times:',self.t
return
s=solution([[3,0,1,0,5,8,0,0,7],
[4,0,0,0,0,0,0,3,0],
[0,0,0,0,2,0,0,0,0],
[9,8,0,3,0,0,0,0,6],
[0,0,6,0,0,0,0,0,0],
[0,0,0,0,0,0,7,8,0],
[5,0,0,0,6,0,9,0,8],
[8,0,0,0,0,0,0,0,1],
[0,0,0,0,0,0,0,0,0]])
s.start()
西湖论剑我要拿第一
1 234 5678 9 依次代替成数字
得出结果,再转回文字
unknown_dsa
先来求一下佩尔方程,得解是ul 和 vl:
ul[i] ^ 2 - wl[i] \\times vl[i]^2 == 1
Python脚本
wl = [3912956711, 4013184893, 3260747771]
ul = []
vl = []
def pell(N, try_num):
cf = continued_fraction(sqrt(N))
for i in range(try_num):
denom = cf.denominator(i)
numer = cf.numerator(i)
if numer2 - N * denom2 == 1:
return numer, denom
return None, None
for N in wl:
ult, vlt = pell(N, 10000)
ul.append(ult)
vl.append(vlt)
print(ul)
print(vl)
2.拿到ul 和 vl,知道c11和c12,得到m1和m2
m1=crt(c11,ui)
m1,_=gmpy2.iroot(m1,7)
Print(long_to_buyes(m1))
m2=crt(c12,v1)
m2,_=gmpy2.iroot(m2,7)
Print(long_to_buyes(m2))
求p和q,已知 p ∗ q p * q p∗q 和 $(p-1)
脚本如下
Import gmpy2
n=852589223779928796266540600421678790889067284911682578924216186052590393595645322161563386615512475256 x=211158499061801396563106646074584256376705200819832482589841660262228987535050089041366888200757204110 Delta=1+4*n*x
delta_sqrt, _ = gmpy2.iroot(delta, 2)
p = (1 + delta_sqrt) // 2
q = n // p
print(p)
print(q)
计算x1和x2就行。
s1 = (hm1 + x1*r1) * invert(k, q) % q
s2 = (hm2 + x1*r1) * invert(k, q) % q
TacticalArmed
打开exe,程序用了二进制文件的数据动态来构建机器码
首先来提取机器码
import pefile, binascii, struct, mmap
from iced_x86 import *
from typing import Dict, Sequence
from types import ModuleType
flag = b"0" * 8
ida_off = 0x401a00
bin_file = open('./TacticalArmed.exe', 'rb')
bin_map = mmap.mmap(bin_file.fileno(), 0, access=mmap.ACCESS_READ)
sizes_raw = bin_map[0x405220 - ida_off:0x405220 - ida_off + 34 * 4]
sizes = [struct.unpack('@I', sizes_raw[i:i+4])[0] for i in range(0, len(sizes_raw), 4)]
template_base = 0x405010 - ida_off
dw_4052A8_base = 0x4052A8 - ida_off
size = 0
v17 = 0
counter = 0
template_offset = template_base
def sub_4011F0(b_arr, counter, offset):
i = 0
while b_arr[i] != 0:
i += 1
dw = struct.unpack('@I', bin_map[dw_4052A8_base + counter * 4:dw_4052A8_base + counter * 4 + 4])[0]
assert dw >= 0
v5 = dw % 0x10
v4 = dw >> 4
if v4 == 1:
b_arr[i:i+4] = struct.pack('@I', 0x405648 + 4 * (v5 + 2 * offset))
elif v4 == 2:
b_arr[i:i+4] = struct.pack('@I', 0x405000 + 4 * v5)
elif v4 == 3:
b_arr[i:i+4] = struct.pack('@I', 0x405748)
formatter = Formatter(FormatterSyntax.INTEL)
def create_enum_dict(module: ModuleType) -> Dict[int, str]:
return module.__dict__[key]:key for key in module.__dict__ if isinstance(module.__dict__[key], int)
CODE_TO_STRING: Dict[Code_, str] = create_enum_dict(Code)
def code_to_string(value: Code_) -> str:
s = CODE_TO_STRING.get(value)
if s is None:
return str(value) + " /*Code enum*/"
return s
REGISTER_TO_STRING: Dict[Register_, str] = create_enum_dict(Register)
def register_to_string(value: Register_) -> str:
s = REGISTER_TO_STRING.get(value)
if s is None:
return str(value) + " /*Register enum*/"
return s
OP_CODE_OPERAND_KIND_TO_STRING: Dict[OpCodeOperandKind_, str] = create_enum_dict(OpCodeOperandKind)
def op_code_operand_kind_to_string(value: OpCodeOperandKind_) -> str:
s = OP_CODE_OPERAND_KIND_TO_STRING.get(value)
if s is None:
return str(value) + " /*OpCodeOperandKind enum*/"
return s
MNEMONIC_TO_STRING: Dict[Mnemonic_, str] = create_enum_dict(Mnemonic)
def mnemonic_to_string(value: Mnemonic_) -> str:
s= MNEMONIC_TO_STRING.get(value) if s is None:
return str(value) + " /*Mnemonic enum*/" return s
def format_mem(offset, is_lhs):
if offset == 0x405748:
return "TMP", False
elif offset >= 0x405648 and offset < 0x405748:
off = offset - 0x405648
if is_lhs:
return "INPUT[%d:%d]" % (off, off + 4), True
else:
return "struct.unpack('@i', INPUT[%d:%d])[0]" % (off, off + 4), False
elif offset >= 0x405000 and offset <= 0x40500C:
#return
#0x405000: "0x7CE45630",
#0x405004: "0x58334908",
#0x405008: "0x66398867",
#0x40500C: "0xC35195B1",
#[offset]
return
0x405000: "0x22836719",
0x405004: "0xA5978C21",
0x405008: "0x79573824",
0x40500C: "0x330B55EF",
[offset], False
else:
raise ValueError("Unknown memory region")
out = open("sdisasm.py", 'w')
out.writelines([
"import struct\\n",
"TMP = 0\\n",
"INPUT = bytearray(b\\"\\\\x00\\" * )\\n".format(len(flag))
])
out_code = open("shellcode.bin", 'wb')
for current_off_1 in range(len(flag) >> 3):
size = 0
for j in range(34):
while size > 0:
op_buf = bytearray(b"\\x00" * 16)
# print(size)
op_buf[:size] = bin_map[template_offset:template_offset + size]
sub_4011F0(op_buf, counter, current_off_1)
out_code.write(op_buf[:size])
op_buf[size] = 0xc3
decoder = Decoder(32, op_buf[:size + 1], ip=0x405010)
for instr in decoder:
info_factory = InstructionInfoFactory()
info = info_factory.info(instr)
op_code = instr.op_code()
disasm = formatter.format(instr)
start_index = instr.ip - 0x405010
bytes_str = op_buf[start_index:start_index + instr.len].hex().upper()
#print(f"bytes_str:20 disasm")
#print(code_to_string(instr.code))
mnemonic = mnemonic_to_string(instr.mnemonic)
lhs = None
lhs_kind = op_code_operand_kind_to_string(op_code.op_kind(0))
lhs_reg = register_to_string(instr.op0_register)
lhs_is_buffer = False
if lhs_kind == "EAX":
lhs = "EAX"
elif lhs_kind == "R32_REG":
lhs = lhs_reg
elif lhs_kind == "R32_OR_MEM":
if lhs_reg != "NONE":
lhs = lhs_reg
else:
assert(len(info.used_memory()) == 1)
lhs,lhs_is_buffer = format_mem(info.used_memory()[0].displacement, True)
elif lhs_kind == "MEM_OFFS":
assert(len(info.used_memory()) == 1)
lhs, lhs_is_buffer = format_mem(info.used_memory()[0].displacement, True)
else:
raise Exception(f"Unknown lhs kind: lhs_kind")
rhs = None
rhs_kind = op_code_operand_kind_to_string(op_code.op_kind(1))
rhs_reg = register_to_string(instr.op1_register)
rhs_is_buffer = False
if rhs_kind == "EAX":
rhs = "EAX"
elif rhs_kind == "R32_REG":
rhs = rhs_reg
elif rhs_kind == "R32_OR_MEM":
if rhs_reg != "NONE":
rhs = rhs_reg
else:
assert(len(info.used_memory()) == 1)
rhs, rhs_is_buffer = format_mem(info.used_memory()[0].displacement, False)
elif rhs_kind == "MEM_OFFS":
assert(len(info.used_memory()) == 1)
rhs, rhs_is_buffer = format_mem(info.used_memory()[0].displacement, False)
elif rhs_kind == "IMM8":
rhs = hex(instr.immediate8)
elif rhs_kind == "IMM32":
rhs = hex(instr.immediate32)
else:
raise Exception(f"Unknown rhs kind: rhs_kind")
if lhs_is_buffer and not rhs_is_buffer:
rhs = "struct.pack('@i', )".format(rhs)
line =
'MOV': 'lhs = rhs',
#'ADD': 'lhs = (lhs + rhs) & 0xFFFFFFFF',
#'SUB': 'lhs = (lhs - rhs) & 0xFFFFFFFF',
#'SHR': 'lhs = (lhs >> rhs) & 0xFFFFFFFF',
#'SHL': 'lhs = (lhs << rhs) & 0xFFFFFFFF',
#'XOR': 'lhs = (lhs ^ rhs) & 0xFFFFFFFF', 'ADD': 'lhs = lhs + rhs',
'SUB': 'lhs = lhs - rhs',
'SHR': 'lhs = lhs >> rhs',
'SHL': 'lhs = lhs << rhs',
'XOR': 'lhs = lhs ^ rhs',
[mnemonic].format(lhs=lhs, rhs=rhs)
out.write(line + "\\n")
break
counter += 1
template_offset += 0x10
size = sizes[v17]
v17 += 1
counter = 0
template_offset = template_base
size = sizes[0]
v17 = 1
out.write("# ==\\n")
print("# ======")
提取成功,然后根据迭代
ECX = TMP
ECX = ECX - 0x7e5a96d2
TMP = ECX
EDX = struct.unpack('@i', INPUT[4:8])[0]
EDX = EDX >> 0x5
EAX = 0xA5978C21
EAX = EAX + EDX
ECX = TMP
ECX = ECX + struct.unpack('@i', INPUT[4:8])[0]
EAX = EAX ^ ECX
EDX = struct.unpack('@i', INPUT[4:8])[0]
EDX = EDX << 0x4
ECX = 0x22836719
ECX = ECX + EDX
EAX = EAX ^ ECX
EDX = struct.unpack('@i', INPUT[0:4])[0]
EDX = EDX + EAX
INPUT[0:4] = struct.pack('@i', EDX)
EAX = struct.unpack('@i', INPUT[0:4])[0]
EAX = EAX >> 0x5
ECX = 0x330B55EF
ECX = ECX + EAX
EDX = TMP
EDX = EDX + struct.unpack('@i', INPUT[0:4])[0]
ECX = ECX ^ EDX
EAX = struct.unpack('@i', INPUT[0:4])[0]
EAX = EAX << 0x4
EDX = 0x79573824
EDX = EDX + EAX
ECX = ECX ^ EDX
EAX = struct.unpack('@i', INPUT[4:8])[0]
EAX = EAX + ECX
INPUT[4:8] = struct.pack('@i', EAX)
最后解密,我们尝试TEA算法进行解密
static uint32_t sum = 0x8F9CCAA6; // 动调获得
void encrypt (uint32_t v[2], const uint32_t k[4])
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x7e5a96d2; /* a key schedule constant */
uint32_t k0=k[0]以上是关于2021西湖论剑-wp的主要内容,如果未能解决你的问题,请参考以下文章