Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize reverse Engineering of Docker Image

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

This article mainly explains "how to realize the reverse engineering of Docker image". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to realize the reverse engineering of Docker image".

First, let the Docker daemon daemon pull the image, and then extract the image into a file:

Docker pull tmknom/prettier:2.0.5docker save tmknom/prettier:2.0.5 > prettier.tar

Yes, this file is just a typical tarball format archive:

$tar xvf prettier.tar6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/VERSION6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/json6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.jsona9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/VERSIONa9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/jsona9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tard4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/VERSIONd4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/jsond4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tarmanifest.jsonrepositories

As you can see, Docker often uses hash hashes when naming. Let's look at manifest.json. It is written in a hard-to-read compressed JSON, but the JSON Swiss Army knife jq prints JSON well:

$jq. Manifest.json [{"Config": "88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json", "RepoTags": ["tmknom/prettier:2.0.5"], "Layers": ["a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar", "d4f612de5397f1fc91272cfbad245b89eac8fa4ad9f0fc10a40ffbb54a356cb4/layer.tar", "6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tar"]}]

Notice that these three layers of Layer correspond to three directories named with a hash. We'll see later. Now, let's look at the JSON file that the Config key points to. It's a little long, so I'll just dump the first part here:

$jq. | 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json | head-n 20 {"architecture": "amd64", "config": {"Hostname": "," Domainname ":", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false "Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"], "Cmd": ["--help"], "ArgsEscaped": true, "Image": "sha256:93e72874b338c1e0734025e1d8ebe259d4f16265dc2840f88c4c754e1c01ba0a"

The most important thing is the history list, which lists each layer in the mirror. The Docker image is made up of these layers. Almost every command in Dockerfile becomes a layer, describing the changes the command has made to the mirror. If you execute the RUN script.sh command to create the really_big_file, and then delete the file with the RUN rm really_big_file command, the Docker image actually generates two layers: one contains the really_big_file, and the other contains the .wh.really _ big_file record to delete it. The size of the entire image file remains the same. This is why you often see Dockerfile commands like RUN script.sh & & rm really_big_file linked together-it ensures that all changes are merged into one layer.

Here are all the layers recorded in the Docker image. Note that most layers do not change the file system image, and the empty_layer is marked as true. Only three of the following layers are non-empty, consistent with what we described earlier.

$jq .history 88f38be28f05f38dba94ce0c1328ebe2b963b65848ab96594f8172a9c3b0f25b.json [{"created": "2020-04-24T01:05:03.608058404Z", "created_by": "/ bin/sh-c # (nop) ADD file:b91adb67b670d3a6ff9463e48b7def903ed516be66fc4282d22c53e41512be49 in/"}, {"created": "2020-04-24T01:05:03.92860976Z", "created_by": "/ bin/sh-c # (nop) CMD [\" / bin/sh\ "]," empty_layer ": true} {"created": "2020-04-29T06:34:06.617130538Z", "created_by": "/ bin/sh-c # (nop) ARG BUILD_DATE", "empty_layer": true}, {"created": "2020-04-29T06:34:07.020521808Z", "created_by": "/ bin/sh-c # (nop) ARG VCS_REF", "empty_layer": true} {"created": "2020-04-29T06:34:07.36915054Z", "created_by": "/ bin/sh-c # (nop) ARG VERSION", "empty_layer": true}, {"created": "2020-04-29T06:34:07.708820086Z", "created_by": "/ bin/sh-c # (nop) ARG REPO_NAME", "empty_layer": true} {"created": "2020-04-29T06:34:08.06429638Z", "created_by": "/ bin/sh-c # (nop) LABEL org.label-schema.vendor=tmknom org.label-schema.name=tmknom/prettier org.label-schema.description=Prettier is an opinionated code formatter. Org.label-schema.build-date=2020-04-29T06:34:01Z org.label-schema.version=2.0.5 org.label-schema.vcs-ref=35d2587 org.label-schema.vcs-url= https://github.com/tmknom/prettier org.label-schema.usage= https://github.com/tmknom/prettier/blob/master/README.md#usage org.label-schema.docker.cmd=docker run-- rm-v $PWD:/work tmknom/prettier-- parser=markdown-- write'* * / * .md 'org.label-schema.schema-version=1.0 " "empty_layer": true}, {"created": "2020-04-29T06:34:08.511269907Z", "created_by": "bin/sh-c # (nop) ARG NODEJS_VERSION=12.15.0-r1", "empty_layer": true}, {"created": "2020-04-29T06:34:08.775876657Z", "created_by": "/ bin/sh-c # (nop) ARG PRETTIER_VERSION" "empty_layer": true}, {"created": "2020-04-29T06:34:26.399622951Z" "created_by": "| 6 BUILD_DATE=2020-04-29T06:34:01Z NODEJS_VERSION=12.15.0-r1 PRETTIER_VERSION=2.0.5 REPO_NAME=tmknom/prettier VCS_REF=35d2587 VERSION=2.0.5 / bin/sh-c set-x & & apk add-- no-cache nodejs=$ {NODEJS_VERSION} nodejs-npm=$ {NODEJS_VERSION} & & npm install-g prettier@$ {PRETTIER_VERSION} & & npm cache clean-- force & & apk del nodejs-npm"} {"created": "2020-04-29T06:34:26.764034848Z", "created_by": "/ bin/sh-c # (nop) WORKDIR / work"}, {"created": "2020-04-29T06:34:27.092671047Z", "created_by": "/ bin/sh-c # (nop) ENTRYPOINT [\" / usr/bin/prettier\ "]," empty_layer ": true} {"created": "2020-04-29T06:34:27.406606712Z", "created_by": "/ bin/sh-c # (nop) CMD [\"-- help\ "]", "empty_layer": true}]

great! All the commands are in the created_by field, and we can almost use these commands to rebuild the Dockerfile. But not entirely. The top ADD command doesn't actually give us the files we need to add. The COPY command also does not have all the information. We also lost the FROM statements because they extended to all the layers inherited from the underlying Docker image.

We can group layers by Dockerfile by looking at the timestamp timestamp. The timestamps of most layers differ by less than a minute, representing the time it takes for each layer to build. But the first two floors are 2020-04-24, and the rest are 2020-04-29. This is because the first two layers come from a base Docker image. Ideally, we can find a FROM command to get this image, so we have a maintainable Dockerfile.

Manifest.json shows that the first non-empty layer is a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97/layer.tar. Let's look at it:

$cd a9cc4ace48cd792ef888ade20810f82f6c24aaf2436f30337a2a712cd054dc97 tar tf layer.tf | headbin/bin/archbin/ashbin/base64bin/bbconfigbin/busyboxbin/catbin/chgrpbin/chmodbin/chown

It looks like it might be a basic image of the operating system operating system, which is what you would expect from a typical Dockerfile. There are 488 entries in Tarball, and if you look at them, you will find some interesting entries:

... dev/etc/etc/alpine-releaseetc/apk/etc/apk/archetc/apk/keys/etc/apk/keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pubetc/apk/keys/alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pubetc/apk/keys/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pubetc/apk/protected_paths.d/etc/apk/repositoriesetc/apk/worldetc/conf.d/...

Sure enough, this is an Alpine image, and if you notice that other layers use the apk command to install packages, you may have guessed it. Let's unpack the tarball and take a look:

$mkdir files$ cd files$ tar xf.. / layer.tar$ lsbin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var$ cat etc/alpine-release3.11.6

If you pull and extract the alpine:3.11.6, you will find that there is a non-empty layer inside, and the layer.tar is the same as the layer.tar in the Prettier image base layer.

Out of interest, what are the other two non-empty layers? The second layer is the main layer that contains the Prettier installation package. It has 528 entries, including Prettier, a bunch of dependencies, and certificate updates:

... usr/lib/libuv.so.1usr/lib/libuv.so.1.0.0usr/lib/node_modules/usr/lib/node_modules/prettier/usr/lib/node_modules/prettier/LICENSEusr/lib/node_modules/prettier/README.mdusr/lib/node_modules/prettier/bin-prettier.jsusr/lib/node_modules/prettier/doc.jsusr/lib/node_modules/prettier/index.jsusr/lib/node_modules/prettier/package.jsonusr/lib/node_modules / prettier/parser-angular.jsusr/lib/node_modules/prettier/parser-babel.jsusr/lib/node_modules/prettier/parser-flow.jsusr/lib/node_modules/prettier/parser-glimmer.jsusr/lib/node_modules/prettier/parser-graphql.jsusr/lib/node_modules/prettier/parser-html.jsusr/lib/node_modules/prettier/parser-markdown.jsusr/lib/node_modules/prettier/parser-postcss.jsusr/lib/node_modules/prettier/parser-typescript.jsusr / lib/node_modules/prettier/parser-yaml.jsusr/lib/node_modules/prettier/standalone.jsusr/lib/node_modules/prettier/third-party.jsusr/local/usr/local/share/usr/local/share/ca-certificates/usr/sbin/usr/sbin/update-ca-certificatesusr/share/usr/share/ca-certificates/usr/share/ca-certificates/mozilla/usr/share/ca-certificates/mozilla/ACCVRAIZ1.crtusr/share/ca-certificates/mozilla/AC_RAIZ_FNMT -RCM.crtusr/share/ca-certificates/mozilla/Actalis_Authentication_Root_CA.crt...

The third layer is created by the WORKDIR / work command, which contains only one entry:

$tar tf 6c37da2ee7de579a0bf5495df32ba3e7807b0a42e2a02779206d165f55f1ba70/layer.tarwork/

The original Dockerfile is in Prettier's git repository.

Thank you for reading, the above is the content of "how to realize the reverse engineering of Docker image". After the study of this article, I believe you have a deeper understanding of how to realize the reverse engineering of Docker image, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report