week1--RE--刷题记录

news/2025/11/11 21:32:27/文章来源:https://www.cnblogs.com/x0rrrrr/p/19209596

week1 刷题

目录
  • week1 刷题
      • 1. [GXYCTF2019]simple CPP
      • 2. [网鼎杯 2020 青龙组]singal
      • 3. [buuctf]firmware
      • 4. [2019红帽杯]xx

1. [GXYCTF2019]simple CPP

​ IDA载入直接分析,这个程序的主要加密逻辑有几块:

img

第一块是一个异或,和key进行异或

img

第二部分是将8个字符拼成一个QWORD,然后存放到v20当中

img

​ 最后就是将v20的值拿出来计算然后进行比较判断。在最后这个加密当中,运用了一大堆的运算,那么z3是最好的方式,直接z3求解即可。

​ 这里有一个注意的地方是,我们并不知道输入有多长,只知道最后比较的长度是32字节,所以这里的z3需要从分组之后开始求解。求解出来后再回推input。这里试了一下从开头写z3到结尾会导致解出来的值不太一样。

  • exp:
from z3 import*
f1, f2, f3, f4 = BitVecs('f1 f2 f3 f4', 64)
s = Solver()s.add(f3 & (~f1) == 0x11204161012)
s.add((f3 & (~f2)) & f1 | f3 & ((f2 & f1) | f2 & (~f1) | (~(f2 | f1))) == 0x8020717153E3013)
s.add((f3 & ~f1) | (f2 & f1) | (f3 & (~f2)) | (f1 & ~f2) == 0x3E3A4717373E7F1F)
s.add((((f3 & (~f1)) | (f2 & f1) | (f3 & (~f2)) | (f1 & ~f2)) ^ f4) == 0x3E3A4717050F791F)
s.add((((f3 & (~f1)) | (f2 & f1) | f2 & f3)) == (~f1 & f3 | 0xC00020130082C0C))
print(s.check())d2 = []
d = s.model()
flag1 = hex(d[f1].as_long())[2:].rjust(16, "0")
flag2 = hex(d[f2].as_long())[2:].rjust(16, "0")
flag3 = hex(d[f3].as_long())[2:].rjust(16, "0")
flag4 = hex(d[f4].as_long())[2:-2]def decode(flag, d):                        le = len(flag)for i in range(0, le, 2):if flag[i:i+2] != "":              d.append(int(flag[i:i+2], 16))  decode(flag1, d2)
decode(flag2, d2)
decode(flag3, d2)
decode(flag4, d2)
key = 'i_will_check_is_debug_or_not'        
fake_flag = ""
for i in range(len(d2)):fake_flag += chr(ord(key[i]) ^ d2[i])
print(fake_flag)
# We1l_D0ndeajoa_Slgebra_am_iright_flag = ''
right_flag += fake_flag[:8]
right_flag += 'e!P0or_a'			# 多解,比赛的时候hint需要将这个替换上去		
right_flag += fake_flag[16:]
print(right_flag)# flag{We1l_D0ne!P0or_algebra_am_i}

2. [网鼎杯 2020 青龙组]singal

​ 非常基础的一道vm题,直接ida分析:

img

使用idapython将code字节码抓出来:

start = 0x403040
print("[")
for i in range(455):print(ida_bytes.get_byte(start+i), end=", ")
print("\n]")

img

然后直接将vm逻辑用python抄出来,z3配合直接求解出来:

from z3 import *s = Solver()
x = [BitVec(f"x{i}",8) for i in range(15)]opcode = [
10, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 81, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 65, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 65, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 63, 0, 0, 0, 7, 0, 0, 0, 52, 0, 0, 0, 7, 0, 0, 0, 50, 0, 0, 0, 7, 0, 0, 0, 114, 0, 0, 0, 7, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 167, 255, 255, 255, 7, 0, 0, 0, 49, 0, 0, 0, 7, 0, 0, 0, 241, 255, 255, 255, 7, 0, 0, 0, 40, 0, 0, 0, 7, 0, 0, 0, 132, 255, 255, 255, 7, 0, 0, 0, 193, 255, 255, 255, 7, 0, 0, 0, 30, 0, 0, 0, 7, 0, 0, 0, 122, 0, 0, 0, 0
]v9 = 0
Str = [0] * 1000
end = 114
v8 = 0
v7 = 0
v6 = 0
v5 = 0
v4 = 0
while v9 < end:op = opcode[v9 * 4]if op == 1:Str[v6+100]=v4v9 += 1v6 += 1v8 += 1elif op == 2:v4 = Str[v8] + opcode[(v9 + 1)*4]v9 += 2elif op == 3:v4 = Str[v8] - opcode[(v9 + 1)*4]v9 += 2elif op == 4:v4 = opcode[(v9 + 1)*4] ^ Str[v8]v9 += 2elif op == 5:v4 = opcode[(v9 + 1)*4] * Str[v8]v9 += 2elif op == 6:v9 += 1elif op == 7:print(Str[v7 + 100])s.add(Str[v7 + 100] == opcode[(v9 + 1)*4])v9 += 2v7 += 1elif op == 8:Str[v5] = v4v9 += 1v5 += 1elif op == 10:print("Read input")for i, v in enumerate(x):Str[i] = vv9 += 1elif op == 11:v4 = Str[v8] - 1v9 += 1elif op == 12:v4 = Str[v8] + 1v9 += 1else:print(f"unknown insn {op}")print(s.check())
if s.check():m = s.model()for i in x:val = m.eval(i, model_completion=True)print(chr(val.as_long()), end="")from z3 import *s = Solver()
x = [BitVec(f"x{i}",8) for i in range(15)]opcode = [
10, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 33, 0, 0, 0, 1, 0, 0, 0, 11, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 81, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 36, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 0, 0, 11, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 54, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 65, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 32, 0, 0, 0, 8, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 37, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 0, 0, 0, 8, 0, 0, 0, 3, 0, 0, 0, 32, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 65, 0, 0, 0, 8, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 34, 0, 0, 0, 7, 0, 0, 0, 63, 0, 0, 0, 7, 0, 0, 0, 52, 0, 0, 0, 7, 0, 0, 0, 50, 0, 0, 0, 7, 0, 0, 0, 114, 0, 0, 0, 7, 0, 0, 0, 51, 0, 0, 0, 7, 0, 0, 0, 24, 0, 0, 0, 7, 0, 0, 0, 167, 255, 255, 255, 7, 0, 0, 0, 49, 0, 0, 0, 7, 0, 0, 0, 241, 255, 255, 255, 7, 0, 0, 0, 40, 0, 0, 0, 7, 0, 0, 0, 132, 255, 255, 255, 7, 0, 0, 0, 193, 255, 255, 255, 7, 0, 0, 0, 30, 0, 0, 0, 7, 0, 0, 0, 122, 0, 0, 0, 0
]v9 = 0
Str = [0] * 1000
end = 114
v8 = 0
v7 = 0
v6 = 0
v5 = 0
v4 = 0
while v9 < end:op = opcode[v9 * 4]if op == 1:Str[v6+100]=v4v9 += 1v6 += 1v8 += 1elif op == 2:v4 = Str[v8] + opcode[(v9 + 1)*4]v9 += 2elif op == 3:v4 = Str[v8] - opcode[(v9 + 1)*4]v9 += 2elif op == 4:v4 = opcode[(v9 + 1)*4] ^ Str[v8]v9 += 2elif op == 5:v4 = opcode[(v9 + 1)*4] * Str[v8]v9 += 2elif op == 6:v9 += 1elif op == 7:print(Str[v7 + 100])s.add(Str[v7 + 100] == opcode[(v9 + 1)*4])v9 += 2v7 += 1elif op == 8:Str[v5] = v4v9 += 1v5 += 1elif op == 10:print("Read input")for i, v in enumerate(x):Str[i] = vv9 += 1elif op == 11:v4 = Str[v8] - 1v9 += 1elif op == 12:v4 = Str[v8] + 1v9 += 1else:print(f"unknown insn {op}")print(s.check())
if s.check():m = s.model()for i in x:val = m.eval(i, model_completion=True)print(chr(val.as_long()), end="")# Read input
# (16 ^ x0) - 5
# 3*(32 ^ x1)
# x2 - 2 - 1
# 4 ^ x3 + 1
# 3*x4 - 33
# x5 - 1 - 1
# (9 ^ x6) - 32
# 36 ^ x7 + 81
# x8 + 1 - 1
# 2*x9 + 37
# 65 ^ x10 + 54
# 1*(x11 + 32)
# 3*x12 + 37
# (9 ^ x13) - 32
# x14 + 65 + 1
# sat
# 757515121f3d478 <-- flag

3. [buuctf]firmware

​ 这个是个路由器的固件题,有点misc的味道。下载题目之后是一个.bin文件,丢虚拟机用binwalk看看是个什么玩意。看起来有不少东西
img

​ 使用binwalk直接将文件拆开:

binwalk -e 51475f91-7b90-41dd-81a3-8b82df4f29d0.bin 

img

整出来之后发现文件夹当中有一个.squashfs的文件,这个文件是一种只读的压缩文件系统。可以使用firmware-mod-kit工具来获取解压缩,这里可以直接去github中将源码下载下来,然后丢到虚拟机,在src文件夹make一下,就可以使用了:

unsquashfs_all.sh 120200.squashfs

然后就能够发现多了一个root-1的文件夹,最后在这个文件夹当中/tmp找到了一个backdoor的文件,复制出来丢die看看有没有壳,发现有一个upx,直接工具脱一下壳,然后丢ida里面,字符串查找就能够发现有一个邮箱的字符串了:
img

接着直接交叉引用到调用的位置,可以发现这个v3其实就是端口号,如果传入的字串有自己的端口就使用自己的端口,没有的话就使用36667端口

img

最后直接将echo.bytehost51.com:36667进行md5提交即可。

4. [2019红帽杯]xx

​ 直接丢IDA看看反汇编,main函数看起来非常的乱。开头就是一个输入长度的判断,输入如果不等于19直接退出:

image-20251111112427360

然后直接动调看看关键位置:

img

第一个关键位置就是这里,这里的v30其实是输入的前4字节,然后传入了这个sub_140001AB0函数当中,进去看了一下发现是一个xxtea加密,然后key就是输入的前四个字节了:

img

​ 继续往下分析:
img

这里很明显就是一个乱序了,接着继续往下:

img

最后这里很明显能看出来是一个异或的加密,而且加密过程是这样的,如果索引值 / 3大于0的话就和从0开始的字符进行逐个异或加密,这里解密的时候需要倒过来。

​ 最后这一块就是比较了:

img

这里的几块变量的内存都是连续的所以这个就是密文。那么大致的逻辑就是:输入 --> xxtea --> 乱序 ---> 异或 --> 比较可以直接写exp了:

#pragma once
#include <iostream>
#include <stdio.h>
#include <vector>void decrypt_xor(unsigned char* enc)
{for (int i = 23; i > 0; i--){int j = 0;if (i / 3 > 0){do {enc[i] ^= enc[j++];} while (j < i / 3);}}
}void sort(unsigned char* enc)
{std::vector<unsigned char> v;for (int i = 0; i < 24; i++){v.push_back(enc[i]);}char index[] = { 2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21 };for (int i = 0; i < 24; i++){enc[index[i]] = v[i];}}uint8_t* tea_decrypt(const uint8_t* cipher, uint64_t cipherlen, const uint8_t* key) {if (!cipherlen || cipherlen < 4) return NULL;// 去掉可能的结尾 0uint64_t usable = cipherlen;if (cipher[cipherlen - 1] == 0 && (cipherlen % 4) == 1) {usable = cipherlen - 1;}if (usable % 4 != 0) return NULL;size_t n = (size_t)(usable / 4);// 组装 vuint32_t* v = (uint32_t*)calloc(n, sizeof(uint32_t));if (!v) return NULL;for (uint64_t i = 0; i < usable; i++) {size_t idx = (size_t)(i >> 2);size_t shift = (size_t)((i & 3) * 8);v[idx] |= ((uint32_t)cipher[i]) << shift;}// 组装 keyuint32_t k[4];for (int j = 0; j < 4; j++) {int base = j * 4;k[j] = (uint32_t)key[base]| ((uint32_t)key[base + 1] << 8)| ((uint32_t)key[base + 2] << 16)| ((uint32_t)key[base + 3] << 24);}// XXTEA 解密核心if (n > 1) {uint32_t delta = 0x9E3779B9;size_t rounds = 6 + 52 / n;uint32_t sum = (uint32_t)(rounds * delta);uint32_t z, y;while (sum) {uint32_t e = (sum >> 2) & 3;y = v[0];for (size_t p = n - 1; p > 0; p--) {z = v[p - 1];v[p] -= (((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4)))^ ((sum ^ y) + (k[(p & 3) ^ e] ^ z));y = v[p];}z = v[n - 1];v[0] -= (((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4)))^ ((sum ^ y) + (k[(0 & 3) ^ e] ^ z));sum -= delta;}}// 恢复原始长度uint32_t orig_len = v[n - 1];uint64_t max_plain = (uint64_t)((n - 1) * 4);if ((uint64_t)orig_len > max_plain) {free(v);return NULL;}// 导出明文uint8_t* out = (uint8_t*)malloc((uint64_t)orig_len);if (!out) {free(v);return NULL;}for (uint64_t i = 0; i < (uint64_t)orig_len; i++) {out[i] = (uint8_t)(v[i >> 2] >> (8 * (i & 3)));}free(v);return out;
}void decrypt()
{unsigned char enc[] ={0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B,0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8,0xE7, 0x56, 0x56, 0xFA};// 解密xordecrypt_xor(enc);printf("[*] : xor finish \r\n");// 乱序sort(enc);printf("[*] : sort success\r\n");// xxteachar key[16] = { 'f','l','a','g'};size_t size = 0;uint8_t* decrpyt = tea_decrypt((const uint8_t*)enc,24,(uint8_t*)key);printf("[*] : xxtea success\r\n");for (int i = 0; i < 19; i++)printf("%c", decrpyt[i]);
}// flag{CXX_and_++tea}

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

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

相关文章

Appium Inspector教程

{ "platformName": "Android", "appium:deviceName": "Android Device", "appium:noReset": true, "appium:automationName": "UiAutomator2"…

Pycharm常用设置

Pycharm常用设置1. 总提示变量名应该全小写 2. 提示参数可以使用外部的变量

pythontip 映射字符串中的字母

编写一个程序,创建一个字典,其中给定单词的每个唯一字母表示一个键,值为字母出现的索引的列表。 定义函数letter_indices(),参数为word(字符串)。 在函数中,创建一个字典,其中键是单词中的唯一字母,值是包含该字…

Python : argument name should be lowercase 警告处理解决方法

Python : argument name should be lowercase 警告处理解决方法From: https://www.cnblogs.com/sunxun001/p/13199786.html 用pyCharm时,常会出现警告信息: function name should be lowercase --函数名应该是小写…

*题解:P5278 算术天才⑨与等差数列

原题链接 解析 要想放到线段树上做,就要考虑如何在不排序的情况下通过一系列可合并的信息判别等差数列。对于一个数列,我们知道它的长度 \(len\),配合上最大值 \(mx\) 最小值 \(mn\) 就可以判断询问给出的 \(k\) 能…

instanceof(类型)

instanceof(类型)instanceof(检测左侧的对象是否为右侧类或接口的实例) public class Main {public static void main(String[] args){//方法的调用只和左边定义的数据类型有关Object object=new teacher();System…

高级程序语言设计第5次

这个作业属于:https://edu.cnblogs.com/campus/fzu/gjyycx 这个作业的要求:https://edu.cnblogs.com/campus/fzu/gjyycx/homework/14581 学号:102500416 姓名:王浩宇 第一部分 1.2. 尽力了,老师3.4.第二部分书本作…

25.11.11 spfa算法

SPFA算法 1.SPFA 是 Bellman-Ford 算法 的一种优化算法,用来求解 带权有向图 中 单源最短路径(可以有负权边,但不能有负权回路)。 2.算法流程: 以源点 s 为起点: (1)初始化 dist[i] = INF,dist[s] = 0; (2)建立…

什么是glTF,与glb的区别,规格和优点,通俗易懂地解释下载获取

​ 近年来,在网站和应用程序上查看 3D 内容的机会迅速增加。 无论是在三维空间中传达产品吸引力的电子商务网站,还是在虚拟空间中交互的元宇宙,还是将信息叠加在现实世界中的增强现实 (AR),3D 技术都在发展我们的…

CF2164E Journey 题解

Hint1 考虑存在欧拉回路的充要条件。Hint2 当我们想在 $(u, v)$ 点间进行传送时,如何计算最小的代价呢?Hint3 相信你已经通过 Hint2 想到建重构树了,那么不妨试试通过贪心算出答案。转化之后题目要求的就是原图的一…

算法训练之BFS解决最短路径难题

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

ASP.NET Core Authorization: 跳过JWT校验

本文记录了如何在asp.net core 9.0上为WebApi配置跳过JWT校验的方法。 项目准备 执行以下命令dotnet new webapi --use-minimal-apis --name MockJwtTestApi --output MockJwtTestApi --auth None dotnet add package …

学习昇腾硬件软件产品名称

应用使能(层级位于MindSpore等框架之上)摘录官网介绍:MindSpeed是一款专为昇腾平台打造的高性能加速库,涵盖了MindSpeed Core亲和加速模块、MindSpeed LLM套件、MindSpeed MM套件以及MindSpeed RL套件这四个重要组…

实用指南:[linux仓库]信号保存[进程信号肆]

实用指南:[linux仓库]信号保存[进程信号肆]2025-11-11 21:08 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: bl…

v4l2_subdev和video_device区分

相关规则video_device是用户空间可见的设备节点,如摄像头、编解码器; v4l2_subdev是不可见于用户空间的中间硬件模块,比如sensor、ISP一个实体硬件(entity),也可以是 video_device或者v4l2_subdev;两者的结构体…

第七天 设计用例方法

设计用例方法共十种 其中七种为黑盒测试方法:等价类、边界值、判定表、状态迁移法、场景法、因果图和正交表 经验测试法三种:错误推测法、异常分析法、随机测试法 作用: (1)单个功能适合:等价类、边界值主要针对…

AT_agc034_c [AGC034C] Tests

不知道为什么今天的题目都不是很想写代码。 首先感受一下,你会发现 \(c_i\) 在高桥优势大的时候肯定取 \(r_i\),否则取 \(l_i\)。 然后你发现仍然不是很好做,考虑二分一下操作数。 到了这个时候开始初现端倪了,你发…

论安慰人

时常受伤,更多自己默默舔舐伤口,难以和别人建立深层连接。我们生活在这样的背景的社会中,安慰别人是个需求旺盛、实施困难的高精端技术活。以“安慰人”为引子,总结一下个人和别人建立亲密关系的原则和技巧。 说简…

电商运营每天在忙啥?拆解4个核心工作,新手也能照做 - 智慧园区

电商运营每天在忙啥?拆解4个核心工作,新手也能照做

102302112王光诚作业2

作业①: 要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。 运行结果:点击查看代码 import sqlite3 import requests from bs4 import BeautifulSoup from datetime import …