好友
阅读权限25
听众
最后登录1970-1-1
|
本帖最后由 a38758720 于 2020-12-14 10:15 编辑
公司项目管理系统用的PowerProject,不懂这玩意用的公司多不多,反正我觉得挺难用的
报工页面让我极其难受,点个报工条目要等半天,所以决定抓个包看一下http请求直接用代码跑
要搞个自动报工,那自然登录啥的也得安排上,不然怎么算自动报告。
所以第一步咱们先做登录。
话不多说反正先F12登录界面
盲猜一下登录url可能是 login?user=xxx&password=xxx
抓个包试试
果然没那么简单,好家伙密码和验证码竟然都做了加密,这长度,反正不是初学做业务系统时喜欢用的md5加密,而且还得传验证码,靠,以前老师不是说验证码就是用来页面上验证的吗,怎么要传到后台了
该不会死在这一步了吧。
偷看了一眼登录的源码
好的这该死的用的是rsa加密,似乎只需要一个公钥,果断打上断点看看公钥是啥
搞到公钥了,而且从源码上看,他用公钥对验证码和密码都做了加密。
加密算法搞到了,登录请求也搞到了,现在登录请求还差一个参数,就是验证码,这狗东西咋整。
继续抓包试试
点了一下验证码,果然,这tm也是像后台请求的。
懂了,这玩意就是跟这次登录会话绑定的
行吧,那我的还得搞的验证码自动识别呗,而且全是数字的验证码看起来简答 #本想自己训练一个出来,直到我在百度找到了一个验证码识别模块,直接用呗
[HTML] 纯文本查看 复制代码 <!-- tess4j用于识别验证码-->
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.4.0</version>
</dependency>
tess4j直接安排上
当然这玩意要附带他训练好的模型
[Java] 纯文本查看 复制代码 public class ValidCode {
private ITesseract instance;
/**
* [url=home.php?mod=space&uid=952169]@Param[/url] languagePath 语言库地址
* @param language 语言,语言库文件的开头
*/
public ValidCode(String languagePath, String language) {
instance = new Tesseract();
//设置训练库的位置
instance.setDatapath(languagePath);
//chi_sim :简体中文, eng 根据需求选择语言库
instance.setLanguage(language);
}
public String ocr(String path) {
File file = new File(path);
String result = null;
try {
result = instance.doOCR(file);
} catch (TesseractException e) {
e.printStackTrace();//捕获异常不干活是会被打的!
}
return result.trim();
}
}
先安排上验证码识别模块。
这块思路就是先通过get下载下来验证码然后掉tess4j直接识别
话说起来,这玩意的请求后面跟着一串诡异的数字,这玩意是干嘛的
尝试一下不带数字访问,似乎没啥影响,估计只是一串随机数,不管了还是看他的代码呗
果然是该死的随机数,那就简单了,直接照猫画虎得了
[Java] 纯文本查看 复制代码 String path;
if (new File("./ocr_data").exists()) {
path = "./ocr_data";
} else {
path = ValidCode.class.getResource("/ocr_data").getPath().substring(1);
}
String jpgPath = new File("./validCode.jpg").getAbsolutePath();
logger.info("验证码识别训练文件路径:[{}],验证码图片路径:[{}]", path, jpgPath);
httpRequest.download("http://0.0.0.0/ajax/Authorization/GetValidateCode/" + (int) Math.floor(Math.random() * (100000 + 1)),
null,
jpgPath);
ValidCode validCodeOcr = new ValidCode(URLDecoder.decode(path), "eng");
String validCode = validCodeOcr.ocr(jpgPath);
validCode = validCode.replaceAll("[^\\d]", "");
logger.info("验证码为:" + validCode);
RSAEncrypt rsaEncrypt = new RSAEncrypt();
String publicKey = "publicKey";
pwd = rsaEncrypt.encrypt(pwd, publicKey);
validCode = rsaEncrypt.encrypt(validCode, publicKey);
Map<String, Object> map = new HashMap<>();
map.put("UserId", name);
map.put("Password", pwd);
map.put("ValidateCode", validCode);
map.put("loginType", "CA");
map.put("CAPassword", "");
CloseableHttpResponse response = httpRequest.post("http://0.0.0.0/MvcPages/Home/LoginPost", map);
HttpEntity post = response.getEntity();
String resultMsg = EntityUtils.toString(post);
if (response.getStatusLine().getStatusCode() <= 200 && !resultMsg.contains("error")) {
logger.info("登录成功");
break;
}
if (response.getStatusLine().getStatusCode() == 500) {
logger.error("服务器异常[" + resultMsg + "]");
System.exit(0);
}
if (resultMsg.contains("密码错误")) {
logger.error("密码错误[" + resultMsg + "]");
System.exit(0);
}
logger.info("登录失败[" + resultMsg + "]");
ok登录成功,保存cookie,接下来就是报工了,老样子先抓包
报工要好几步,选择报工项目,然后选择报工内容,然后每天的工时
一步步抓包呗
参数也很简单很好理解,反正照搬就对了,到目前为止抓包的部分都结束了,然后快乐写代码呗
[Java] 纯文本查看 复制代码 public void selectProject(String projectId, String firstDayOfWeek) throws Exception {
Map<String, Object> map1 = new HashMap<>();
map1.put("category1", "Other");
map1.put("projectId", projectId);
map1.put("firstDayOfWeek", firstDayOfWeek);
map1.put("states", "");
map1.put("category2s", "开发");
map1.put("date", firstDayOfWeek);
CloseableHttpResponse post = httpRequest.post("http://0.0.0.1/Timesheets/Submit/SaveTimesheetObject", map1);
logger.info("设置报工条目[{}]", projectId);
}
public void saveTimesheet(String time, String standardHours, String overtimeHours, String projectId) throws Exception {
if (StringUtils.isBlank(standardHours) && StringUtils.isBlank(overtimeHours) ||
standardHours.equals("0") && overtimeHours.equals("0")
) {
return;
}
Map<String, Object> map1 = new HashMap<>();
map1.put("Category1", "Other");
map1.put("Category2", "开发");
map1.put("ProjectId", projectId);
map1.put("PreSaleProjectId", "");
map1.put("UserId", name);
map1.put("Date", time);
map1.put("StandardHours", standardHours);
map1.put("OvertimeHours", overtimeHours);
map1.put("WorkType", "开发");
map1.put("WorkContent", "1");
CloseableHttpResponse post = httpRequest.post("http://0.0.0.1/Timesheets/Submit/SaveTimesheet", map1);
logger.info(EntityUtils.toString(post.getEntity()));
}
public void getTimesheetFields(String firstDayOfWeek) throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("date", firstDayOfWeek);
CloseableHttpResponse post = httpRequest.post("http://0.0.0.1//Timesheets/Submit/GetTimesheetFields", map);
logger.info(EntityUtils.toString(post.getEntity()));
}
[Java] 纯文本查看 复制代码 public void deal() throws Exception {
File file = new File("./config.properties");
InputStreamReader inputStreamReader;
if (!file.exists()) {
inputStreamReader = new InputStreamReader(
BGMain.class.getResourceAsStream("/config.properties"),
Charset.forName("GBK"));
} else {
InputStream resourceAsStream = new FileInputStream("./config.properties");
inputStreamReader = new InputStreamReader(
resourceAsStream,
Charset.forName("GBK"));
}
Properties properties = new Properties();
properties.load(inputStreamReader);
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String projectId = properties.getProperty("project_id");
String firstDay = properties.getProperty("first_day");
logger.info("加载配置文件");
logger.info(String.format("user:%s,password:%s,projectId:%s,firstDay:%s", user, password, projectId, firstDay));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date parse = sdf.parse(firstDay);
String one = properties.getProperty("one");
String oneJb = properties.getProperty("one_jb");
String two = properties.getProperty("two");
String twoJb = properties.getProperty("two_jb");
String three = properties.getProperty("three");
String threeJb = properties.getProperty("three_jb");
String four = properties.getProperty("four");
String fourJb = properties.getProperty("four_jb");
String five = properties.getProperty("five");
String fiveJb = properties.getProperty("five_jb");
String six = properties.getProperty("six");
String sixJb = properties.getProperty("six_jb");
String seven = properties.getProperty("seven");
String sevenJb = properties.getProperty("seven_jb");
HttpRequest httpRequest = new HttpRequest();
PowerProject powerProject = new PowerProject(httpRequest, user, password);
powerProject.login();
powerProject.selectProject(projectId, one);
powerProject.saveTimesheet(firstDay, one, oneJb, projectId);
powerProject.saveTimesheet(sdf.format(new Date(parse.getTime() + (3600L * 24 * 1000))), two, twoJb, projectId);
powerProject.saveTimesheet(sdf.format(new Date(parse.getTime() + (3600L * 24 * 1000) * 2)), three, threeJb, projectId);
powerProject.saveTimesheet(sdf.format(new Date(parse.getTime() + (3600L * 24 * 1000) * 3)), four, fourJb, projectId);
powerProject.saveTimesheet(sdf.format(new Date(parse.getTime() + (3600L * 24 * 1000) * 4)), five, fiveJb, projectId);
powerProject.saveTimesheet(sdf.format(new Date(parse.getTime() + (3600L * 24 * 1000) * 5)), six, sixJb, projectId);
powerProject.saveTimesheet(sdf.format(new Date(parse.getTime() + (3600L * 24 * 1000) * 6)), seven, sevenJb, projectId);
powerProject.getTimesheetFields(one);
}
搞个配置文件方便配置,然后就完事了。
打个包方便执行,写个bat直接跑就完事了
[Shell] 纯文本查看 复制代码 java -jar test1-1.0-SNAPSHOT-jar-with-dependencies.jar
pause
搞定收工,终于不用再该死的页面上一步步的点报工了。 |
|