PWNABLE write up[Toddler’s Bottle]
fd 最基础的c语言题目
![]() | ![]() |
---|
Fd.c
1 | #include <stdio.h> |
由fd.c知程序中变量fd为读入的第一个参数减0x1234,同时fd也作为read函数的第一个参数。
linux的文件描述符
Integervalue Name <unistd.h> symbolicconstant <stdio.h> filestream
0 Standardinput STDIN_FILENO stdin
1 Standardoutput STDOUT_FILENO stdout
2 Standarderror STDERR_FILENO stderr
当fd为0时,read函数为标准输入流,(0x1234)16 =(4660)10 即第一个参数为4660时read函数生效,再输入buf的内容:LETMEWIN,获取flag。

collision
![]() | ![]() |
---|
1 | #include <string.h> |

bof
![]() | ![]() |
---|
最简单的buffer overflow

栈的简单结构如下
overflowme
ebp
eip
函数参数key
只要溢出把key的值变成0xcafebabe就可以了


flag
![]() | ![]() |
---|
题目提示是逆向,拖到winhex里发现upx加壳

Upx -d 脱下壳,再用ida打开

发现main函数里有句提示,双击跟进下具体位置,发现flag

passcode
![]() | ![]() |
---|
做这题时先要看到程序里的关键点
scanf(“%d”, passcode1); 这里没有&,表示是直接向地址为passcode1里写入整型数据
刚上手,发现输入name处存在溢出,但是有canary,canary就是图中v2,即passcode2,因此不能直接覆盖返回地址。

通过ida观察栈中情况
name变量所在位置

passcode1所在位置

两者相差0x60
最终思路如下:
1.通过输入name控制passcode1
2.将passcode1构造成程序中接下来会调用函数的地址
3.下一步程序会执行scanf函数,通过scanf直接将函数地址(got表)覆写成我们想要的
即下图

这里覆写的是printf的got表

random
![]() | ![]() |
---|

发现随机数没设置种子,每次出来的都是同一个值


leg
ARM汇编基础知识,虽然学过8086汇编,但看到ARM汇编还是懵逼的,好多寄存器没见过…上网查了资料才知道
![]() | ![]() |
---|
r0-r3 用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。
被调用函数在返回之前不必恢复 r0-r3。如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。
r4-r11 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。
r12 是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。
在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复 r12。
r13 是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。
r14 是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复
r15 是程序计数器 PC。它不能用于任何其它用途。
https://blog.csdn.net/u014379540/article/details/51996209

题目需要使输入的key=key1+key2+key3

Mov r3,pc 将PC中的内容放至r3寄存器中,此时PC中的内容为当前地址+8,即0x08ce4,函数返回值为r0寄存器中的内容,即key1=0x08ce4

Add r6,pc #1
在ARM里表示r6=pc+1 即r6=0x08d01
Bx r6 表示r6是跳转的目的地址,并且根据地址的最低位确定是否状态切换。如果末尾是1则切换到thumb状态,否则保留在asm状态;当前状态下是应该切换到thumb状态。
这里是thumb模式,所以操作都是16位的,也就是16进制的4位
当前pc为0x08d08
r3=pc+4=0x08d0c

LR为链接寄存器,保存子程序的返回地址

子程序结束后顺序返回到0x08d80,即r0和LR的值为0x08d80
最终把三个数相加得到key

mistake
![]() | ![]() |
---|
题目提示是运算符优先级问题
问题出在这里

=优先级小于<,因此fd为0,即程序会先从标准输入流中获取pw_buf2值
整个逻辑都可控了

shellshock
![]() | ![]() |
---|
Shellshock是2014年的一个bash shell 的CVE
https://www.freebuf.com/news/48331.html
Poc: env x=’() { :;}; echo hh’ bash -c “echo test”
设置环境变量时,如果发现有(){ 会解析成函数,且之后的命令仍然执行

coin1
![]() | ![]() |
---|
题目就不放上来了,一个简单的二分查找


注意要放到他的服务器上跑,不然延迟很高,肯定来不及
blackjack
![]() | ![]() |
---|
一个21点的小游戏,题目就不放了
做法也很简单,因为一开始没看源码,测试了下发现赌注可以输入负数,接着一直输就好了……
后来看了源码发现还有别的解法
https://blog.csdn.net/qq_20307987/article/details/51435143

lotto
![]() | ![]() |
---|
看似是一个看脸的彩票游戏,但是代码里有很大问题

计算match值这部分,虽然lotto是随机的,但是如果你输入6个相同数字,lotto中有一个和你输入数字相同就能验证通过,爆破一下
脚本里:( 部分可以无视,因为pwnable的flag标志太明显了…

cmd1
![]() | ![]() |
---|
考察点:linux基础等,通配符*的利用
1 | #include <stdio.h> |
要求输入的参数中不能包含flag sh tmp
方法一、
利用通配符

方法二、
利用绝对路径绕过关键字的限制
在有权限创建文件的位置创建文件a
a的内容如下


cmd2
![]() | ![]() |
---|
相比于cmd1,限制更加严格,连/ 和`都不能用了
1 | #include <stdio.h> |
本题的重点就是绕过/的限制
易知

这样一来就很轻松构造Payload

但是并没有执行,又试了下payload写入文件执行,也无法执行。
后来查了下linux中单双引号的区别才发现问题所在:

https://blog.csdn.net/beginning1126/article/details/8633900
果然还是Linux基础太差了,以后要好好补补
用单引号就ok了

uaf
![]() | ![]() |
---|
学到了uaf(use after free)漏洞
题目解析这篇博客已经讲得很清楚了
https://blog.csdn.net/qq_20307987/article/details/51511230
利用过程自己再捋一遍
1.先执行3,虽然分配的空间被回收,但是m指针仍然指向被回收的内存区域(迷途指针)
2.查看之前分配的空间大小,以便利用,分配了0x18

3.将虚表调整

memcpy
![]() | ![]() |
---|
movntps m128,XMM
m128 <== XMM 直接把XMM中的值送入m128,不经过cache,必须对齐16字节.
movdqa 把2个对准的四字节整数传送到xmm寄存器或者内存
堆块分配时除了堆块本身还有堆块大小和标志位共计4字节。而malloc分配的堆块大小是以8字节对其的。
因为movntps需要16字节对齐,这就说明每次分配的堆块数必须是偶数,所以只要每次输入的大小满足使分配的堆块数为偶即可
k为输入数据,即满足(k+4)/8=2n
这题一开始不是很理解,但是看了几遍writeup后发现其实原理很简单,主要要了解堆分配的规则,一开始想复杂了

asm
![]() | ![]() |
---|
题目大致的意思是把你的shellcode加上一段预设的shellcode在沙箱里运行
先看沙箱函数,沙箱里只允许使用open read write exit exit_group这些函数

再看添加的shellcode,只是把寄存器清零了

用pwntools自带的shellcraft模块就很方便


blukat
![]() | ![]() |
---|
这题……纯考你细心不细心

第一部分的题目相对简单,分值也低,还有Input unlink horcruxes 没写,有空继续做