Git folder exploit
当部署线上项目的时候可能会把git代码仓库一起部署上去,造成的结果就是.git
文件夹泄漏,由此可以根据.git/index
来知道对应的压缩文件名字,下载之后解压缩即可得到源代码。这个程序是根据lijiejie的githack更改过来的。
因为githack
使用的是socket直接read()之后解压缩,如果文件太大会造成卡死。不管是githack
还是rip-git
,在下载文件的时候,如果文件不存在,而且服务器设置了302跳转的话,就会下载跳转那个页面,最后会导致下载好多重复文件。
所以我在源代码的基础上更改了下,先下载git压缩文件,然后再解压缩到对应的名称,如果文件不存在,服务器跳转,就pass。中间碰到几个问题如下:
使用requests碰到的问题
timeout()
简单来说,Timeouts
可以是一个元组,第一个数值代表的是connect
的timeout
,第二个数值表示read
的timeout
,在这里read
的timeout
表示的是is the number of seconds the client will wait for the server to send a response,(Specifically, it’s the number of seconds that the client will wait between bytes sent from the server. In practice, this is the time before the server sends the first byte)
下载大文件
使用requests,所以下载的时候不需要担心steam=True的情况,直接使用。
r = requests.get(url, stream=True)
with open(local_filename, 'wb') as f:
for chunk in r.iter_conteCnt(chunk_size=1024):
if chunk: # filter out keep-alive new chunks
f.write(chunk)
#f.flush() commented by recommendation from J.F.Sebastian
return local_filename
zlib解压缩
在原有代码的基础上,使用zlib.decompress(requests.reponse.raw.read())
来解压缩文件,本身设想把socket当作file来操作,但是未搞定。
最后采用先下载压缩文件到本地,然后解压缩到对应文件。
Socket流程
由于gitback
在两个地方碰到了socket的问题:
- 请求服务器发生
readtimeout
异常 zlib.decopress
解压缩是否可以解压缩socket,将socket作为文件来读
首先来看以下socket的流程:首先服务端调用socket()
创建一个socket,再将这个socket绑定bind()
,绑定一个端口,调用listen来限制等待连接的队列容量,最后在循环中不停调用accept()
来接收请求。
客户端通过socket()
创建socket,再调用connect()
连接到服务端bind的端口,这个时候如果等待连接的客户端超过listen()
的设置,就会被拒绝,否则服务器接收这个accept()
请求,并建立连接。accet()
会返回新的socket,服务端和客户端都可以通过这个socket,调用send()/recv()
或write()/read()
进行通信。
阻塞与非阻塞
阻塞(blocking),简单来说就是**sleep(休眠)**的技术术语,由于CPU的速度比较快,寄存器、CPU缓存和内存还能跟上这个速度,但是换成硬盘、网络等访问时间在毫秒以上,造成CPU长时间空闲等待,于是造成阻塞。
如果在这些耗费时间较长的I/O访问时,CPU处理完之后立即返回处理其他事情,让设备自行连接、传输。并在结束后让CPU完成善后,这样就是非阻塞(non-blocking),在C语言中可以通过fcntl()
和ioctl()
将socket设为非阻塞。
在非阻塞状态下,服务器可以异步处理I/O,最简单的就是死循环中遍历所有socket,此时如果试着读取non-blocking的socket,如果socket没有内容的时候,返回-1,并将errno设置为EWOULDBLOCK
select()
授予你同时监视多个socket的权利,它会告诉你哪里资料可以读取,那些可以写入,哪些触发了例外。
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select (int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
readfds
,writefds
, excepfds
分别表示要监视的那一组file descriptor set。
至于epoll
,异步IO这些以后再慢慢学,先留个概念。