pwn0-4 Test_your_nc
pwn0

1 | ssh ctfshow@pwn.challenge.ctf.show -p28110 |
等待程序跑完
1 | cat /ctfshow_flag |
获得flag
pwn1
010打开附件 是ELF文件
在虚拟机运行checksec pwn1
1 | ctfshow@ubuntu:~/Desktop/pwn1wjj$ checksec pwn1 |
checksec查看二进制启用了哪些安全机制。判断该走什么利用方式。
可以看到是64位仅关闭Canary保护
- NX: 不能直接执行栈上的 shellcode,通常走 ROP/ret2libc。
- Canary: 有金丝雀,溢出必须先泄露或绕过。
- PIE: 程序地址随机化,需要先泄露地址。
- RELRO: 影响 GOT 能否被写,用于判断能不能改 GOT
打开附件后反编译可直接看到关键命令:
cat /ctfshow_flag- 以及提示语:
You only need to connect to the remote address with NC to get the flag!
表明连接后不用操作,程序会直接执行cat读取flag

checksec仅用于了解保护情况,但本题不需要利用链,发现 system("cat /ctfshow_flag") 后直接连接即可
直接在虚拟机nc连接即可获得flag

pwn2
反编译附件后看到

system("/bin/sh")直接启动一个后门。连上远程以后直接进入shell环境。然后自己执行cat /ctfshow_flag就可以读flag

pwn3
1 | You can call the following function: |
4 5 7都是打印路径字符串
只有6是读取文件内容

pwn4
打开附件 反编译
字符串比较口令校验
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
C语言的反编译版本。IDA把机器代码“猜回”C,所以名字看上去奇怪。本质上还是C语言
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
main是程序固定入口
int:main最后会返回一个整数(0表示正常结束)
argc/argv/envp是命令行参数(这里可以不用管
_fastcall是编译器用的调用方式,对题目逻辑没影响
1 | char s1[11]; |
char s1[11];
开一块能放11个字符的空间char s2[12];
开一块能放12个字符的空间unsigned __int64 v6;
一个 64 位无符号整数。
这个是栈保护值,暂时理解为安全锁
1 | v6 = __readfsqword(0x28u); |
读取栈保护值。是编译器加的,防止栈溢出攻击。和题目逻辑无关
1 | setvbuf(_bss_start, 0LL, 2, 0LL); |
让输入输出立刻显示,不等缓冲,这样交互更流畅
1 | strcpy(s1, "CTFshowPWN"); |
strcpy是把右边字符串复制到左边的数组里
所以s1现在是CTFshowPWN
1 | logo(); |
logo()是打印题目banner
puts()是打印一句话
1 | __isoc99_scanf("%s", s2); |
"%s"是“读入一个字符串”
你的输入会被存进s2
1 | if ( !strcmp(s1, s2) ) |
strcmp(s1, s2)比较两个字符串。- 如果相同,返回0
- 如果不同,返回非0
!strcmp(...)的意思是“如果它们相同”- 如果相同,执行
execve_func()
1 | return 0; |
程序结束正常退出
因此这里要输入s1数值,你输入的内容就存入s2,与真实的s1比较,相同则执行execve_func()
反编译execve_func(),发现就是进入一个shell
1 | CTFshowPWN |

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 luxlu!