模拟网页行为之实践篇三

现在来谈下验证码图片的获取方式,带有验证码的地方都会附带有个刷新按钮,而刷新按钮的地方就是获取验证码网址代码。如果看过前面写的《模拟网页行为之工具篇》就会很容易定位到代码位置。定位到代码位置后看下图:


基本可以看到的是获取验证码的网址是:https://ipin.siren24.com/stickyCaptcha。但这还不够,因为前篇我们还讲过关于cookie的概念,需要带有cookie去刷新验证码才是有效的验证码,但如何获取cookie,看下图:


可见cookie类型是hostonly的,hostonly就是说只能在当前网页获取cookie。有了上述抓包分析,那么对验证码的流程有了基本的了解。

那么接下来的步骤分为

1.获取https://ipin.siren24.com/stickyCaptcha的cookie,。

2. 带cookie刷新验证码获取图片数据。


获取hostonly的cookie,c++代码实现如下:

std::string CWebLoginDlg::GetCookie( std::string url )
{LPSTR lpszData = NULL;DWORD dwSize=0; lpszData= new char[1];memset(lpszData,0, 1);retry:	if (!InternetGetCookieA(url.c_str(), "", lpszData, &dwSize)){DWORD er = GetLastError();if (er == ERROR_INSUFFICIENT_BUFFER){delete []lpszData;lpszData = new char[dwSize+1];memset(lpszData,0,dwSize+1);goto retry;}else{ATLTRACE("cookie is null");}}std::string strCookieContent = std::string(lpszData, dwSize);delete [] lpszData;return strCookieContent;
}
参数即为:https://ipin.siren24.com/stickyCaptcha


若cookie为httponly类型,获取的方式也不一样,C++代码如下:

std::wstring CWebLoginDlg::GetCookieEx( std::wstring url )
{LPWSTR lpszData = NULL;DWORD dwSize=0; lpszData= new wchar_t[1];memset(lpszData,0, sizeof(wchar_t));retry:	if (!InternetGetCookieEx(url.c_str(), L"JSESSIONID", lpszData, &dwSize, 0x00002000, NULL)){DWORD er = GetLastError();if (er == ERROR_INSUFFICIENT_BUFFER){delete []lpszData;lpszData = new wchar_t[dwSize+1];memset(lpszData,0,dwSize+1);goto retry;}else{ATLTRACE("cookie is null");}}std::wstring strCookieContent = std::wstring(lpszData, dwSize);delete [] lpszData;return strCookieContent;
}

刷新验证码图片数据,我采用的方式是用curl库,实际上所有网页走网络协议方式都可以借助curl来实现,但这里只单纯刷验证码图片数据。上面步骤把cookie获取到后,将其编辑成以下格式,然后将其作为参数cookie,传入到获取网页返回数据函数,c++代码表示如下:

std::string cookie = GetCookie("https://ipin.siren24.com/stickyCaptcha");
char nline[1024];
sprintf_s(nline, sizeof(nline),"%s; domain=ipin.siren24.com; path=/; hostOnly", cookie.c_str());
m_pCurlClient->GetURLResource("https://ipin.siren24.com/stickyCaptcha", nline, ret);

GetURLResource实现如下:

struct MemoryStruct {char *memory;size_t size;
};size_t CurlClient::WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{size_t realsize = size * nmemb;if (userp == NULL){return realsize;}struct MemoryStruct *mem = (struct MemoryStruct *)userp;//ATLTRACE("222 chunk addr %x %d %d threaid %d", (DWORD)mem, mem->size, realsize, GetCurrentThreadId());mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);if(mem->memory == NULL) {/* out of memory! */ printf("not enough memory (realloc returned NULL)\n");return 0;}memcpy(&(mem->memory[mem->size]), contents, realsize);mem->size += realsize;mem->memory[mem->size] = 0;return realsize;
}bool CurlClient::GetURLResource( std::string url, std::string cookie, std::string &rev)
{bool ssl = (url.find("https") != std::string::npos);struct MemoryStruct chunk;chunk.memory = (char*)malloc(1); chunk.size = 0;   CURL *curl;CURLcode res;curl = curl_easy_init();if (curl){if (!cookie.empty()){char nline[1024];sprintf_s(nline, sizeof(nline),"Set-Cookie: ""%s", cookie.c_str());res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);}curl_easy_setopt(curl, CURLOPT_URL, url.c_str());int agentIndex = m_Multi ? GetCurrentThreadId() % m_UserAgentList.size() : 0;curl_easy_setopt(curl, CURLOPT_USERAGENT, m_UserAgentList[agentIndex].c_str());if (ssl){curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);}curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &CurlClient::WriteMemoryCallback);curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&chunk);curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1); //多线程完成任务马上断开连接curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);res = curl_easy_perform(curl);if (res != CURLE_OK){char curlerror[1024 * 5] = {0};sprintf_s(curlerror, _countof(curlerror), "返回的信息 %s",curl_easy_strerror(res));m_Error = curlerror;}rev = std::string(chunk.memory, chunk.size);free(chunk.memory);curl_easy_cleanup(curl);}return res == CURLE_OK;
}

以上,验证码的图片数据即可获取。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/499622.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SHA-256算法实现

SHA-256 算法输入报文的最大长度不超过2^64 bit,输入按512-bit 分组进行处理,产生 的输出是一个256-bit 的报文摘要。该算法处理包括以下几步: STEP1:附加填充比特。对报文进行填充使报文长度与448 模512 同余(长度…

ecc算法入门介绍

一、从平行线谈起。 平行线,永不相交。没有人怀疑把:)不过到了近代这个结论遭到了质疑。平行线会不会在很远很远的地方相交了?事实上没有人见到过。所以“平行线,永不相交”只是假设(大家想想初中学习的平行…

Intel Hex概述

什么是Intel Hex文件 Intel HEX文件时遵循Intel HEX文件格式的ASCII文本文件。在Intel HEX文件的每一行都包含了 一个HEX记录。这些记录是由一些代表机器语言代码和常量的16进制数据组成的。Intel HEX文件常用来传输要存储在ROM 或者 EPROM中的程序和数据。大部分的EPROM编程器…

AndroidStudio+ideasmali动态调试smali汇编

0x00 前言 之前对于app反编译的smali汇编语言都是静态分析为主,加上一点ida6.6的动态调试,但是ida的调试smali真的像鸡肋一样,各种不爽,遇到混淆过的java代码就欲哭无泪了。后来知道IDEA用一款插件也可以实现smali的动态调试&a…

使用IDA Pro动态调试SO文件

(1)在IDA的安装路径中找到android_server文件。 (2)将android_server拷贝到手机的/data/local/tmp目录下面。 (3) 将手机插上电脑,打开命令提示符, 先输入”adb shell”,然后输入”…

机器学习或深度学习的数据读取工作(大数据处理)

机器学习或深度学习的数据读取工作(大数据处理)主要是.split和re.findall和glob.glob运用。 读取文件的路径(为了获得文件内容)和提取文件路径中感兴趣的东西(标签) 1,“glob.glob”用于读取文件路径 2,“.…

Android系统架构图

一、Aplications(应用层) 应用是用Java语言编写的云新在虚拟机上的程序。 二、Application Framework(应用框架层) 这一层是编写Google发布的核心应用时所使用的API框架,开发人员可以使用这些框架来开发自己的应用。 V…

AES算法重点详解和实现

可以看到,在原始数据长度为16的整数倍时,假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n,其它情况下加密数据长度等于16*(n1)。在不足16的整数倍的情况下,假如原始数据长度等于16*nm[其中m小于16]…

勒索病毒傀儡进程脱壳

样本是:wallet勒索病毒 环境:虚拟机VMWARE win7 32位 工具:OD,winhex 初次拿到样本,先用火绒剑工具监控下病毒样本的流程,可以看到有一个自创建进程的行为。 我们等找到OEP后,在CreateProcessA下…

arm32和arm64常用指令B BL BLX机器码计算

现在大部分手机cpu架构是ARM v7-A和ARMV8-A,,在ARM-v7A中常使用32位ARM指令集并且支持thumb指令集与arm的切换,而在ARMV8中使用的是64位ARM指令集且不再有thumb指令集状态的切换了。在调用函数时,会有常用的调用方式:BL和B&#x…

openssl c++实现bouncycastle中AES加解密

0x01 为什么要用bouncycastle 先说说JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。 它提供对对称、不对称、块和流密码的加密…

win10用Eclipse+OpenJTag对S3C2440开发板进行动态调试

0 背景在S3C2400开发板裸板调试程序中,常用调试手段有三种:点灯法,串口打印,OpenOCD。OpenOCD又分命令行和图形界面(Eclipse)。点灯发和串口打印调试效率都很低,若能掌握第三种调试方法,会让开发过程变得高…

无源码情况下动态调试混淆的java程序

逆向工程JAVA通常是非常简单的,因为优秀的JAVA二进制反编译器已经存在多年。类似于jd-gui工具和恢复java二进制文件源代码功能也做的非常出色的。在这种情况下我们需要动态调试java反编译java程序的情况下,可以从反编译导出然后导入java IDE如Eclipse作为…

OpenJTAG调试S3C2440裸板程序

0x00 懵逼当你写好的初始化代码head.S和链接脚本uart.lds共同编译出来的*.bin,烧录到NandFlash中的时候,发现串口输出一片空白,这时你的想法是什么,砸电脑还是干点其他有用的事?还是老实的搭建调试环境吧,上…

APK逆向之静态分析篇

0x00 APK包结构0x01 APK反编译-apktool啰嗦一句,反编译之前配置好java环境,具体JDK安装过程,请参照之前的文章。下载最新版本的apktool.jar,并在当前目录下编辑脚本apktool.bat,内容如下: echo off set PAT…

S3C2440 lds链接脚本解析

1. SECTIONS到底意味着什么在一个裸版程序里面含有*.lds文件,而lds文件意味着如果你的程序烧录在nandflash,那在nandflash的内存将根据lds文件指定偏移来分布,下面从不同场景来解释SECTIONS的内容。2. 小于4K程序若程序小于4K,那…

安装qt5.9.5 windows环境

下载:用国外链接下载慢,还是乖乖用国内链接地址吧,我这里5.9.5http://mirrors.ustc.edu.cn/qtproject/archive/qt/5.9/5.9.5/qt-opensource-windows-x86-5.9.5.exe。安装: 在安装的时候需要创建qt账号,然后根据你的vis…

qt在visual studio 2015下的使用

创建工程: 打开visual studio,按上一篇文章的方式创建新工程QtGuiApplication1,默认我们可以看到里面会出现QtGuiApplication1这个类是继承于QMainWindow这个类的。在创建过程中注意下图选项:有三个对象分别是QMainwindow&#xf…

qt 收缩窗体

效果图:功能拆分图:代码: QtStubOption.cpp QtSubOption::QtSubOption(QWidget *parent): QLabel(parent) {ui.setupUi(this);m_GuiShow SHOWGUI;setMouseTracking(true);m_PicStatus[SHOWGUI] ":/QtGuiApplication3/tile";m_Pic…

Android的ELF文件重定位详解,包括64位

0x01 引言 ELF文件格式,主要基于两种,一种是基于链接视图,链接视图即是基于节(Section)来进行解析,一种是基于执行视图,执行视图即是基于段(Segment)来进行解析。前一种是用于静态分析的时候,譬如IDA载入。…