关于Python脚本提交POST表单

昨天帮舍友写一个刷票的脚本,注册、登录、投票,三个过程。分析了一下数据包的内容以后,发现注册的时候POST提交的内容是 Multipartform-data格式的,用urllib2一直没弄好,最后用requests实现了。

urllib2应该可以实现的,回头再研究下。

另外,urllib2好像不支持长连接,requests支持。

总结一下,requests还是挺好用的。

补充:

WX20170321-115316@2x

小记unlink&frontlink

先看看unlink的代码:

FD = P->fd;

BK = P->bk;

FD->bk = BK;

BK->fd = FD;

当一块内存被合并,或者被分配,总之当它从双循环链表里解开的时候调用unlink宏,指针P指向正在操作的这块内存。

由内存块的结构可知,P->fd即P+8,P->bk即P+12。我们如果可以通过某种方式(比如缓冲区溢出)控制被解链的这块内存的内容,就可以做如下操作:

P->bk = shellcode地址

P->fd = 要覆盖的地址-12

这里的要覆盖的地址可以是栈上的返回地址,也可以是.dtors段上的析构函数的地址,或者是GOT表中的函数地址,当该块内存被解链时(比如释放时和前一块空闲内存合并),要覆盖的地址就会被覆盖为shellcode地址。

当一块内存被释放时,会调用frontlink来把这块内存加到双向循环链表里(在合并相邻块后执行),下面是frontlink代码:

BK = bin;

FD = BK->fd;

if (FD != BK) {

while (FD != BK && S < chunksize(FD)) {

FD = FD->fd;

}

BK = FD->bk;

}

P->bk = BK;

P->fd = BK;

FD->bk = BK->fd = P;

其中bin指向双向循环链表里的那个筐,然后里面的空闲内存块按从大到小的顺序排列,P指向要加进去的内存块。

举个例子分析一下:

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

int main(int argc, char *argv[])

{

if (argc != 3) {

printf(“Usage: prog_name arg1 \n”);

exit(-1);

}

char *first, *second, *third;

char *fourth, *fifth, *sixth;

first = malloc(strlen(argv[2]) + 1);

second = malloc(1500);

third = malloc(12);

fourth = malloc(666);

fifth = malloc(1508);

sixth = malloc(12);

strcpy(first, argv[2]);

free(fifth);

strcpy(fourth, argv[1]);

free(second);

return 0;

}

这个程序可以用以下方式利用:

strcpy(first, argv[2]);

在argv[2]中包含一段shellcode,并且最后四个字节是shellcode地址(first也就是first块的最后四个字节);

free(fifth);

fifth块被释放后被放入筐中。

strcpy(fourth, argv[1]);

可以利用这个缓冲区溢出来控制fifth内存块的fd和bk指针,我们可以让fifth->fd指向一个假的内存块,比如我们可以控制的fourth内存块的某位置,这里记为fake(即fifth->fd = fake),并且我们让fake块的bk指针,即fake+12 = 要覆盖的地址-8,这里要覆盖的地址我们取.dtors段的第一个函数地址。

free(second);

当second块被释放时,程序会调用frontlink代码将其放到和fifth块相同的筐中,过程大概是下面这样:

BK = bin;

FD = fifth; //这样假设应该无碍

FD = fifth->fd = fake; //循环执行了一次

BK = FD->bk = fake->bk = fake + 12; //即要覆盖的地址-8

P->bk = BK;

P->fd = FD;

BK->fd = P; //P(即second块)的前四个字节就是first块的最后四个字节,即shellcode地址

所以.dtors段的第一个函数指针就被覆盖为shellcode的地址了,程序在return之后就会执行shellcode。