text:
---
layout: post
comments: true
title: PTES -读书笔记
category: 网络安全
keywords: 安全,读书笔记,2019
---

PTES (penetration testing execution standard) 读书笔记

## 0x01 High Level Organization of the Standard
The penetration testing execution standard consists of seven (7) main sections.
+ from the initial communication and reasoning behind a pentest,
+ through the intelligence gathering and threat modeling phases where testers are working behind the scenes in order to get a better understanding of the tested organization,
+ through vulnerability research, exploitation and post exploitation, where the technical security expertise of the testers come to play and combine with the business understanding of the engagement,
+ and finally to the reporting, which captures the entire process, in a manner that makes sense to the customer and provides the most value to it.

## 0x02 Pre-engagement Interactions
### 2.1 Overview
Remember, a penetration test should not be confrontational. It should not be an activity to see if the tester can “hack” you. It should be about identifying the business risk associated with and attack.

### 2.2 Introduction to Scope
Neglecting to properly complete pre-engagement activities has the potential to open the penetration tester (or his firm) to a number of headaches including scope creep, unsatisfied customers, and even legal troubles.

The scope of a project specifically defines what is to be tested. How each aspect of the test will be conducted will be covered in the Rules of Engagement section.

One key component of scoping an engagement is outlining how the testers should spend their time.

It is important in the Pre-Engagement phase that the tester is able to serve as a guide through what may be uncharted territory for a customer.

The tester must understand the difference between a test which focuses on a single application with severe intensity and a test where the client provides a wide range of IP addresses to test and the goal is to simply find a way in.

### 2.3 Metrics for Time Estimation
Once the time to test is determined, it is a prudent practice to add 20% to the time.

Another component of the metrics of time and testing is that every project needs to have a definitive drop dead date.

All good projects have a well-defined beginning and end.

### 2.4 Scoping Meeting
The goal of the scoping meeting is to discuss what will be tested. Rules of engagement and costs will not be covered in this meeting.

First, it needs to be established explicitly what IP ranges are in scope for the engagement. It is not uncommon for a client to be resistant and assume that it is the prerogative of the tester to identify their network and attack it, to make the test as realistic as possible. This would indeed be an ideal circumstance, however, possible legal ramifications must be considered above all else.

### 2.5 Additional Support Based on Hourly Rate
Any requests outside of the original scope should be documented in the form of a statement of work that clearly identifies the work to be done. We also recommend that it be clearly stated in the contract that additional work will be done for a flat fee per hour and explicitly state that additional work can not be completed until a signed and counter-signed SOW is in place.

### 2.7 General Questions
2.7.1 Network Penetration Test

2.7.2 Web Application Penetration Test

2.7.3 Wireless Network Penetration Test

2.7.4 Physical Penetration Test

2.7.5 Social Engineering

2.7.6 Questions for Business Unit Managers

2.7.7 Questions for Systems Administrators

### 2.8 Scope Creep
do not hesitate to ask for additional funding to compensate for the extra time spent. If a customer refuses to pay for the extra work, it is almost never worth staying on to do that work.

The second point is even more critical. When dealing with existing customers, take care to keep the prices lower. Taking advantage of a good situation by price gouging is a sure way to drive away repeat business.

### 2.9 Specify Start and End Dates
To mitigate this risk, add a simple statement to the contract which mentions that all retesting must be done within a certain timeframe after the final report delivery.

### 2.10 Specify IP Ranges and Domains
Before starting a penetration test, all targets must be identified. These targets should be obtained from the customer during the initial questionnaire phase. Targets can be given in the form of specific IP addresses, network ranges, or domain names by the customer.

### 2.11 Dealing with Third Parties
The most important thing to remember is that while permission may have been granted by the client, they do not speak for their third party providers. Thus, permission must be obtained from them as well in order to test the hosted systems. Failing to obtain the proper permissions brings with it, as always, the possibility of violating the law, which can cause endless headaches.

2.11.1 Cloud Services

2.11.2 ISP

2.11.3 MSSPs

    Managed Security Service Providers also may need to be notified of testing.

2.11.4 Countries Where Servers are Hosted

### 2.12 Define Acceptable Social Engineering Pretexts
Be sure that any pretexts chosen for the test are approved in writing before testing is to begin.

### 2.13 DoS Testing
Stress testing or Denial of Service testing should be discussed before the engagement begins.

if the organization is also worried about the availability of their services, then the stress testing should be conducted in a non-production environment which is identical to the production environment.

### 2.14 Payment Terms
2.14.1 Net 30

The total amount is due within 30 days of the delivery of the final report. This is usually associated with a per month percentage penalty for non-payment. This can be any number of days you wish to grant your customers (i.e. 45, or 60).

2.14.2 Half Upfront

It is not uncommon to require half of the total bill upfront before testing begins. This is very common for longer-term engagements.

2.14.3 Recurring

A recurring payment schedule is more commonly used for long-term engagements. For example, some engagements may span as far as a year or two. It is not at all uncommon to have the customer pay in regular installments throughout the year.

### 2.15 Goals
Every penetration test should be goal-oriented. This is to say that the purpose of the test is to identify specific vulnerabilities that lead to a compromise of the business or mission objectives of the customer. It is not about finding un-patched systems. It is about identifying risk that will adversely impact the organization.

2.15.1 Primary

The primary goal of a test should not be driven by compliance.

2.15.2 Secondary

The secondary goals are directly related to compliance.

2.15.3 Business Analysis

Before performing a penetration test it is beneficial to determine the maturity level of the client’s security posture For customers with a very immature security program, it is often a good idea to perform a vulnerability analysis first.

Some testers believe there is a stigma surrounding Vulnerability Analysis (VA) work. Those testers have forgotten that the goal is to identify risks in the target organization, not about pursuing the so-called “rockstar” lifestyle. If a company is not ready for a full penetration test, they will get far more value out of a good VA than a penetration test.

Establish with the customer in advance what information about the systems they will be providing. It may also be helpful to ask for information about vulnerabilities which are already documented. This will save the testers time and save the client money by not overlapping testing discoveries with known issues. Likewise, a full or partial white-box test may bring the customer more value than a black-box test, if it isn’t absolutely required by compliance.

### 2.16 Establish Lines of Communication
One of the most important aspects of any penetration test is communication with the customer. How often you interact with the customer, and the manner in which you approach them, can make a huge difference in their feeling of satisfaction.

### 2.17 Emergency Contact Information
Obviously, being able to get in touch with the customer or target organization in an emergency is vital. Emergencies may arise, and a point of contact must have been established in order to handle them.

2.17.1 Incident Reporting Process

2.17.2 Incident Definition

2.17.3 Status Report Frequency

2.17.4 PGP and Other Alternatives

### 2.18 Rules of Engagement
2.18.1 Timeline

A clear timeline should be established for the engagement. While scope defines the start and the end of an engagement, the rules of engagement define everything in between.

GANTT Charts and Work Breakdown Structures are often used to define the work and the amount of time that each specific piece of the work will take. Seeing the schedule broken down in this manner aids those involved in identifying where resources need to be applied and it helps the customer identify possible roadblocks which many be encountered during testing

2.18.2 Locations

Another parameter of any given engagement which is important to establish with the customer ahead of time is any destinations to which the testers will need to travel during the test. This could be as simple as identifying local hotels, or complex as identifying the applicable laws of a specific target country.

However, if the data cannot be physically or virtually obtained, how can it be proved that the testers indeed obtained access to the information? This problem has been solved in a number of ways. There are ways to prove that the vault door was opened without taking any of the money. For instance, a screenshot of database schema and file permissions can be taken, or the files themselves can be displayed without opening them to displaying the content, as long as no PII is visible in the filenames themselves.

2.18.3 Evidence Handling

When handling evidence of a test and the differing stages of the report it is incredibly important to take extreme care with the data. Always use encryption and sanitize your test machine between tests. Never hand out USB sticks with test reports out at security conferences. And whatever you do, don’t re-use a report from another customer engagement as a template! It’s very unprofessional to leave references to another organization in your document.

2.18.4 Regular Status Meetings

Throughout the testing process it is critical to have regular meetings with the customer informing them of the overall progress of the test. These meetings should be held daily and should be as short as possible. Meetings should be kept to three concepts: plans, progress and problems. Plans are generally discussed so that testing is not conducted during a major unscheduled change or an outage. Progress is simply an update to the customer on what has been completed so far. Problems should also be discussed in this meeting, but in the interest of brevity, conversations concerning solutions should almost always be taken offline

2.18.5 Time of the Day to Test

Certain customers require all testing to be done outside of business hours. This can mean late nights for most testers. The time of day requirements should be well established with the customer before testing begins.

2.18.6 Dealing with Shunning

2.18.7 Permission to Test

One of the most important documents which need to be obtained for a penetration test is the Permission to Test document. This document states the scope and contains a signature which acknowledges awareness of the activities of the testers.

2.18.8 Legal Considerations

Some activities common in penetration tests may violate local laws. For this reason, it is advised to check the legality of common pentest tasks in the location where the work is to be performed. For example,any VOIP calls captured in the course of the penetration test may be considered wiretapping in some areas.

### 2.19 Capabilities and Technology in Place
Good penetration tests do not simply check for un-patched systems. They also test the capabilities of the target organization. To that end, below is a list of things that you can benchmark while testing.

1. Ability to detect and respond to information gathering

2. Ability to detect and respond to foot printing

3. Ability to detect and respond to scanning and vuln analysis

4. Ability to detect and respond to infiltration (attacks)

5. Ability to detect and respond to data aggregation

6. Ability to detect and respond to data ex-filtration

When tracking this information be sure to collect time information. For example, if a scan is detected you should be notified and note what level of scan you were preforming at the time.

## 0x03 Intelligence Gathering
### 3.1 General
Levels are an important concept for this document and for PTES as a whole. It’s a maturity model of sorts for pentesting. Defining levels allows us to clarify the expected output and activities within certain real-world constraints such as time, effort, access to information, etc.

Level 1 Information Gathering

(think: Compliance Driven) Mainly a click-button information gathering process. This level of information can be obtained almost entirely by automated tools. Bare minimum to say you did IG for a PT.

Level 2 Information Gathering

(think: Best Practice) This level can be created using automated tools from level 1 and some manual analysis. A good understanding of the business, including information such as physical location, business relationships, org chart, etc.

Level 3 Information Gathering

(think: State Sponsored) More advanced pentest, Redteam, full-scope. All the info from level 1 and level 2 along with a lot of manual analysis. An Army Red Team is tasked to analyze and attack a segment of the Army’s network in a foreign country to find weaknesses that could be exploited by a foreign national. A level 3 information gathering effort would be appropriate in this case.

### 3.2 Intelligence Gathering
3.2.1 What it is

Intelligence Gathering is performing reconnaissance against a target to gather as much information as possible to be
utilized when penetrating the target during the vulnerability assessment and exploitation phases. The more information
you are able to gather during this phase, the more vectors of attack you may be able to use in the future.
Open source intelligence (OSINT) is a form of intelligence collection management that involves finding, selecting,
and acquiring information from publicly available sources and analyzing it to produce actionable intelligence.

3.2.2 Why do it

We perform Open Source Intelligence gathering to determine various entry points into an organization. These entry
points can be physical, electronic, and/or human. Many companies fail to take into account what information about
themselves they place in public and how this information can be used by a determined attacker. On top of that many
employees fail to take into account what information they place about themselves in public and how that information
can be used to to attack them or their employer.

3.2.3 What is it not

OSINT may not be accurate or timely. The information sources may be deliberately/accidentally manipulated to reflect
erroneous data, information may become obsolete as time passes, or simply be incomplete.
It does not encompass dumpster-diving or any methods of retrieving company information off of physical items found
on-premises.

### 3.3 Target Selection
3.3.1 Identification and Naming of Target

It is also not all that uncommon for a company to have a number of sub-companies underneath them. For example General Electric and Proctor and Gamble own a great deal of smaller companies.

3.3.2 Consider any Rules of Engagement limitations

3.3.3 Consider time length for test

3.3.4 Consider end goal of the test

Every test has an end goal in mind - a particular asset or process that the organization considers critical. Having the
end result in mind, the intelligence gathering phase should make sure to include all secondary and tertiary elements
surrounding the end goal. Be it supporting technologies, 3rd parties, relevant personnel, etc... Making sure the focus
is kept on the critical assets assures that lesser relevant intelligence elements are de-prioritized and categorized as such
in order to not intervene with the analysis process.

### 3.4 OSINT
Open Source Intelligence (OSINT) takes three forms; Passive, Semi-passive, and Active.

### 3.5 Covert Gathering

### 3.6 Footprinting

### 3.7 Identify Protection Mechanisms

## 0x04 Threat Modeling

### 4.1 General

The standard focuses on two key elements of traditional threat modeling - assets and attacker (threat community/agent). Each one is respectively broken down into business assets and business processes and the threat communities and their capabilities.

As a minimum, all four elements should be clearly identified and documented in every penetration test.

The model should be clearly documented, and be delivered as part of the final report as the findings in the report will reference the threat model in order to create a more accurate relevance and risk score that is specific to the organization (rather than a generic technical one).

4.1.1 High level threat modeling process
+ 1. Gather relevant documentation
+ 2. Identify and categorize primary and secondary assets
+ 3. Identify and categorize threats and threat communities
+ 4. Map threat communities against primary and secondary assets

There are a variety of tools available to identify targets and map attack vectors. These normally focus on the business assets (what systems to target) and business processes (how to attack them.)

### 4.2 Business Asset Analysis
4.2.1 Organizational Data

Policies, Plans, and Procedures

Product Information (e.g. trade secrets, R&D data)

Marketing Information (plans, roadmaps, etc.)

Financial Information (e.g. bank, credit, equity accounts)

Technical Information
    + Infrastructure Design Information
    + System Configuration Information
    + User Account Credentials
    + Privileged User Account Credentials

Employee Data

Customer Data

4.2.2 Human Assets
    + Executive Management
    + Executive Assistants
    + Middle Management
    + Administrative Assistants
    + Technical/Team Leads
    + Engineers
    + Technicians
    + Human Resources

### 4.3 Business Process Analysis

By mapping these processes, identifying the critical vs. non-critical processes and eventually finding flaws in them we are able to understand how the business works, what makes them money and eventually how specific threat communities can make them lose money.

4.3.1 Technical infrastructure supporting process

As business processes are usually supported by IT infrastructure (such as computer networks, processing power, PCs for entering information and managing the business process, etc...), all those elements must be identified and mapped. Such mapping should be clear enough to be used later on in the process when translating the threat model to the vulnerability mapping and exploitation.

4.3.2 Information assets supporting process

4.3.3 Human assets supporting process

4.3.4 3rd party integration and/or usage of/by process

### 4.4 Threat Agents/Community Analysis

### 4.5 Threat Capability Analysis

### 4.6 Motivation Modeling

## 0x05 Vulnerability Analysis

### 5.1 Testing

Vulnerability testing is the process of discovering flaws in systems and applications which can be leveraged by an attacker. These flaws can range anywhere from host and service misconfiguration, or insecure application design.Although the process used to look for flaws varies and is highly dependent on the particular component being tested, some key principals apply to the process.

When conducting vulnerability analysis of any type the tester should properly scope the testing for applicable depth
and breadth to meet the goals and/or requirements of the desired outcome. Depth values can include such things as
the location of an assessment tool, authentication requirements, etc. For example; in some cases it maybe the goal of
the test to validate mitigation is in place and working and the vulnerability is not accessible; while in other instances
the goal maybe to test every applicable variable with authenticated access in an effort to discover all applicable vulnerabilities. Whatever your scope, the testing should be tailored to meet the depth requirements to reach your goals.
Depth of testing should always be validated to ensure the results of the assessment meet the expectation (i.e. did all
the machines authenticate, etc.). In addition to depth, breadth must also be taken into consideration when conducting
vulnerability testing. Breadth values can include things such as target networks, segments, hosts, application, inventories, etc. At its simplest element, your testing may be to find all the vulnerabilities on a host system; while in other
instances you may need to find all the vulnerabilities on hosts with in a given inventory or boundary. Additionally
breadth of testing should always be validated to ensure you have met your testing scope (i.e. was every machine in the
inventory alive at the time of scanning? If not, why).

### 5.2 Active
There are two distinct ways to interact with the target component: automated, and manual.

Automated

Automated testing utilizes software to interact with a target, examine responses, and determine whether a vulnerability exists based on those responses.

Network/General Vulnerability Scanners

Port Based

When the scanner determines that a port is open, a presumption is made by the scanner as to whether a vulnerability
is present or not. For example, if a port based scanner connects to TCP port 23, and that port is listening, the scanner
is likely to report that the telnet service is available on the remote host, and flag it as having a clear text authentication
protocol enabled.

Service Based

Banner Grabbing

Web Application Scanners

General application flaw scanners

Most web application scans start with the address of a website, web application, or web service. The scanner then crawls the site by following links and directory structures. After compiling a list of webpages, resources, services and/or other media offered, the scanner will perform tests, or audits against the results of the crawl. For example, if a webpage discovered in the crawl has form fields, the scanner might attempt SQL injection or cross-site scripting. If the crawled page contained errors, the scanner might look for sensitive information displayed in the error detail, and so on.

Directory Listing/Brute Forcing

Web Server Version/Vulnerability Identification

Methods

OPTIONS

PUT/DELETE

TRACE/TRACK

Network Vulnerability Scanners/Specific Protocols

VPN

Voice Network Scanners

War Dialing

VoIP

Manual Direct Connections

As with any automated process or technology, the margin for error always exists. Instabilities in systems, network
devices and network connectivity may introduce inaccurate results during testing. It is always recommended to execute
manual direct connections to each protocol or service available on a target system to validate the results of automated
testing as well as identifying all potential attack vectors and previously unidentified weaknesses.

Obfuscated

Multiple Exit Nodes

Security monitoring and defense systems operate under the pretense of identifying malicious activity from a specific
IP address. In situations where Intrusion Detection systems are deployed and monitoring activity, sourcing assessment
and attack activities from multiple IP addresses provide more accurate results and lessen the opportunity for a monitoring device on a target network to identify and respond.

IDS Evasion

When conducting assessment activities against a target environment where IDS technologies are deployed, it may
be necessary to perform evasion. Using methods such as string manipulation, polymorphism, session splicing, and
fragmentation can provide more accurate results while bypassing signature matching patterns implemented in IDS devices.

### 5.3 Passive

Metadata Analysis

Though metadata is quite common on documents located on a company’s internal network, companies should take care to purge metadata before making documents available to the public, or on the public Internet. For this reason, any metadata an attacker could gain access to passively (without directly attacking the target) should be considered a security issue.

Traffic Monitoring

### 5.4 Validation

Correlation between Tools

When working with multiple tools the need for correlation of findings can become complicated. Correlation can be
broken down into two distinct styles, specific and categorical correlation of items, both are useful based on the type of
information, metrics and statistics you are trying to gather on a given target.

Manual Testing/Protocol Specific

Attack Avenues

Creation of attack trees

During a security assessment, it is crucial to the accuracy of the final report to develop an attack tree as testing
progresses throughout the engagement. As new systems, services and potential vulnerabilities are identified; an attack
tree should be developed and regularly updated. This is especially important during the exploitation phases of the
engagement as one point of entry that materializes could be repeated across other vectors mapped out during the
development of the attack tree.

Isolated Lab Testing

The accuracy of vulnerability analysis and exploitation is substantially greater when replicated environments are setup
in an isolated lab. Often times, systems may be hardened with specific control sets or additional protection mechanisms. By designing a lab that mimics that of the target organization, the consultant can ensure that the vulnerabilities
identified and exploits attempted against the desired targets are reliable and lessen the opportunity for inaccurate results
or system inoperability.

Visual Confirmation

Manual Connection with Review

### 5.5 Research

Public Research

Vulnerability Databases

Vendor Advisories

Exploit Databases and Framework Modules

Common/default Passwords

Hardening Guides/Common Misconfigurations

Private Research

Setting up a replica environment

Testing Configurations

Fuzzing

Fuzzing, or fault injection, is a brute-force technique for finding application flaws by programmatically submitting
valid, random or unexpected input to the application. The basic process involves attaching a debugger to the target
application, and then running the fuzzing routine against specific areas of input and then analyzing the program state
following any crashes. Many fuzzing applications are available, although some testers write their own fuzzers for
specific targets.

Identifying potential avenues/vectors

Log in or connect to a target network application to identify commands and other areas of input. If the target is a
desktop application that reads files and/or web pages, analyze the accepted file formats for avenues of data input.
Some simple tests involve submitting invalid characters, or very long strings of characters to cause a crash. Attach a
debugger to analyze the program state in the event of a successful crash.

Disassembly and code analysis

Some programming languages allow for decompilation, and some specific applications are compiled with symbols for
debugging. A tester can take advantage of these features to analyze program flow and identify potential vulnerabilities.
Source code for open source applications should be analyzed for flaws. Web applications written in PHP share many
of the same vulnerabilities, and their source code should be examined as part of any test.

## 0x06 Exploitation

### 6.1 Purpose

The exploitation phase of a penetration test focuses solely on establishing access to a system or resource by bypassing security restrictions. If the prior phase, vulnerability analysis was performed properly, this phase should be well planned and a precision strike.. The main focus is to identify the main entry point into the organization and to identify high value target assets. If the vulnerability analysis phase was properly completed, a high value target list should have been complied. Ultimately the attack vector should take into consideration the success probability and highest impact on the organization.

### 6.2 Countermeasures

Countermeasures are defined as preventative technology or controls that hinder the ability to successfully complete an
exploit avenue. This technology could be a Host Based Intrusion Prevention System, Security Guard, Web Application
Firewall, or other preventative methods. When performing an exploit, several factors should be taken into consideration.

6.2.1 Anti-Virus

Encoding / Packing / Encrypting  / Whitelist Bypass  / Process Injection  / Purely Memory Resident

6.2.2 Human

6.2.3 Data Execution Prevention (DEP)

6.2.4 Address Space Layout Randomization

6.2.5 Web Application Firewall (WAF)

### 6.3 Evasion

Evasion is the technique used in order to escape detection during a penetration test. This could be circumventing a
camera system as to not be seen by a guard, obfuscating your payloads to evade Intrusion Detection Systems (IDS) or
Intrusion Prevention Systems (IPS) or encoding requests/responses to circumvent web application firewalls. Overall,
the need to identify a low risk scenario for evading a technology or person should be formulated prior to the exploit.

### 6.4 Precision Strike

The main focus of a penetration test is to simulate an attacker in order to represent a simulated attack against the
organization. The value brought through a penetration test is generally not through smash and grab techniques where
the attacks are noisy in nature and in an attempt to try every exploit. This approach may be particularly useful at the
end of a penetration test to gauge the level of incident response from the organization, but in most cases the exploitation
phase is a accumulation of specific research on the target.

### 6.5 Customized Exploitation Avenue

Every attack will typically not be the same in how the exploitation avenue occurs. In order to be successful in this
phase, the attack should be tailored and customized based on the scenario. For example, if a wireless penetration test
is occurred, and a specific technology is in use, these need to be identified and attacked based on what technologies are
in place. Having a clear understanding of each scenario and the applicability of an exploit is one of the most important
aspects of this phase of the penetration test.

### 6.6 Tailored Exploits

The penetration tester should have the knowledge in place to be able to customize an exploit and the ability to change on the fly in order to successfully complete the attack.

6.6.1 Exploit Customization

A common theme for exploits is to target specific versions of operating systems or applications.

### 6.7 Zero-Day Angle

This type of attack often represents a highly advanced organization that can handle a focused attack against the organization through normal attack methods. In certain scenarios research may be conducted in order to reverse engineer, fuzz, or perform advanced discovery of vulnerabilities that have not been discovered.

6.7.1 Fuzzing

6.7.2 Source Code Analysis

6.7.3 Types of Exploits

Buffer Overflows / SEH Overwrites (structured exception handler ) / Return Oriented Programming

6.7.4 Traffic Analysis

6.7.5 Physical Access

Human Angle  / PC Access

6.7.6 Proximity Access (WiFi)

WiFi Attacks / Attacking the User

There are several common techniques in use of this, but most commonly the attacker would setup a wireless access point with the same name or an enticing name in order for the victim to connect.

### 6.8 Example Avenues of Attack

Web Application Attacks

Social-Engineering

Physical Attack Avenues

Memory Based Exploits (i.e. buffer/heap overflows, memory corruptions, use-after-free).

Man in the Middle

VLAN Hopping

USB/Flash Drive deployment

Reverse Engineering

Zero-Day Angle

Attacking the user

Encryption Cracking

Graphics Processing Unit (GPU) Cracking

Traffic Analysis

Firewire Routing protocols

Phishing with Pretexting

Employee Impersonation

### 6.9 Overall Objective

In the pre-engagement interaction phase with the customer, a clear definition of the overall objectives of the penetration
test should have been communicated. In the case of the exploitation phase, the biggest challenge is identifying the
least path of resistance into the organization without detection and having the most impact on the organizations ability
to generate revenue.

By performing the prior phases properly, a clear understanding of how the organization functions and makes money
should be relatively understood. From the exploitation phase and into the post-exploitation phase, the attack vectors
should rely solely on the mission of circumventing security controls in order to represent how the organization can
suffer substantial losses through a targeted attack against the organization.

## 0x07 Post Exploitation

### 7.1 Purpose

The purpose of the Post-Exploitation phase is to determine the value of the machine compromised and to maintain
control of the machine for later use. The value of the machine is determined by the sensitivity of the data stored on
it and the machines usefulness in further compromising the network. The methods described in this phase are meant
to help the tester identify and document sensitive data, identify configuration settings, communication channels, and
relationships with other network devices that can be used to gain further access to the network, and setup one or more
methods of accessing the machine at a later time. In cases where these methods differ from the agreed upon Rules of
Engagement, the Rules of Engagement must be followed.

### 7.2 Rules of Engagement

7.2.1 Protect the Client

Unless previously agreed upon, there will be no modification of services which the client deems “critical” to their infrastructure.
All modifications, including configuration changes, executed against a system must be documented.

。。。

7.2.2 Protecting Yourself

Ensure that the contract and/or statement of work signed by both the client and provider that the actions taken on the systems being tested are on behalf and in representation of the client.

。。。

### 7.3 Infrastructure Analysis

7.3.1 Network Configuration

7.3.2 Network Services

### 7.4 Pillaging

Pillaging refers to obtaining information (i.e. files containing personal information, credit card information, passwords,
etc.) from targeted hosts relevant to the goals defined in the pre-assessment phase. This information could be obtained
for the purpose of satisfying goals or as part of the pivoting process to gain further access to the network. The location
of this data will vary depending on the type of data, role of the host and other circumstances. Knowledge and basic
familiarity with commonly used applications, server software and middleware is very important, as most applications
store their data in many different formats and locations. Special tools may be necessary to obtain, extract or read the
targeted data from some systems.

7.4.1 Installed Programs
+ List of the applications and their associated versions installed on the system.
+ List of operating system updates applied to the system.

7.4.2 Installed Services

Services on a particular host may serve the host itself, or other hosts in the target network. It is necessary to create a
profile of each targeted host, noting the configuration of these services, their purpose, and how they may potentially
be used to achieve assessment goals or further penetrate the network.

（Security Services；File/Printer Shares ；Database Servers ；Directory Servers ；Name Servers ；Deployment Services ；Certificate Authority ；Source Code Management Server ；Dynamic Host Configuration Server ；Dynamic Host Configuration Server （DHCP）；Virtualization ；Messaging ；Monitoring and Management ；Backup Systems ；Networking Services (RADIUS,TACACS..etc) ）

7.4.3 Sensitive Data

（Key-logging ；Screen capture ；Network traffic capture ；Previous Audit reports ）

7.4.4 User Information

In this section the main focus is on the information present on the target system related to user accounts either present
on the system or that have connected remotely and have left some trace that the personnel performing the assessment
can gather and analyze for further penetration or provide the desired goal of the assessment.

On System

General information that can be gather on a compromised system are:
+ History files ；
+ Encryption Keys (SSH, PGP/GPG) ；
+ Interesting Documents (.doc/x, .xls/x , password.*) ；
+ User specific application configuration parameters
+ Individual Application History (MRU Windows only, history files..etc)
+ Enumerate removable media
+ Enumerate network shares / domain permission (gpresult)

Web Browsers

IM Clients
+ Enumerate Account Configuration (User, Password, Server, Proxy)
+ Chat Logs

7.4.5 System Configuration

Password Policy

Security Policies

Configured Wireless Networks and Keys

### 7.5 High Value/Profile Targets

### 7.6 Data Exfiltration

7.6.1 Mapping of all possible exfiltration paths

7.6.2 Testing exfiltration paths

7.6.3 Measuring control strengths

### 7.7 Persistence

+ Installation of backdoor that requires authentication.
+ Installation and/or modification of services to connect back to system. User and complex password should be used as a minimum; use of certificates or cryptographic keys is preferred where possible. (SSH, ncat, RDP). Reverse connections limited to a single IP may be used.
+ Creation of alternate accounts with complex passwords.
+ When possible backdoor must survive reboots.

### 7.8 Further Penetration Into Infrastructure

7.8.1 From Compromised System

Actions that can be taken from a compromised system:
+ Upload tools
+ Use local system tools
+ ARP Scan
+ Ping Sweep
+ DNS Enumeration of internal network
+ Directory Services Enumeration
+ Brute force attacks
+ Enumeration and Management thru Management Protocols and compromised credentials (WinRM, WMI, SMB, SNMP..etc)
+ Abuse of compromised credentials and keys (Webpages, Databases..etc)
+ Execute Remote Exploits

7.8.2 Thru Compromised System

Actions that can be taken thru a compromised system:
+ Port Forwarding
+ Proxy to internal network (SSH)
+ VPN to internal network
+ Execute Remote Exploit
+ Abuse of compromised credentials and keys (Webpages, Databases..etc)

### 7.9 Cleanup

The cleanup process covers the requirements for cleaning up systems once the penetration test has been completed.

This will include all user accounts and binaries used during the test.
+ Remove all executable, scripts and temporary file from a compromised system. If possible use secure delete
method for removing the files and folders.
+ Return to original values system settings and application configuration parameters if they where modified during
the assessment.
+ Remove all backdoors and/or rootkits installed.
+ Remove any user accounts created for connecting back to compromise systems.

## 0x08 Reporting

### 8.2 Report Structure

The report is broken down into two (2) major sections in order to communicate the objectives, methods, and results of the testing conducted to various audiences.

### 8.3 The Executive Summary

Background:

Overall Posture:

Risk Ranking/Profile:

General Findings:

Recommendation Summary:

Strategic Roadmap:

### 8.4 Technical Report

Introduction:

The introduction section of the technical report is intended to be an initial inventory of:
+ Personnel involved in the testing from both the Client and Penetration Testing Team
+ Contact information
+ Assets involved in testing
+ Objectives of Test
+ Scope of Test
+ Strength of Test
+ Approach
+ Threat/Grading Structure

Information Gathering:

Vulnerability Assessment:

Exploitation/ Vulnerability Confirmation:

Post Exploitation:

Post Exploitation:
+ Privilege Escalation path
+ Technique used
+ Acquisition of Critical Information Defined by client
+ Value of information
+ Access to core business systems
+ Access to compliance protected data sets
+ Additional Information/Systems Accessed
+ Ability of persistence
+ Ability for exfiltration
+ Countermeasure Effectiveness

Risk/Exposure:

Conclusion:

## 参考文献
[1] [The penetration testing execution standard](http://www.pentest-standard.org/index.php/Main_Page)


text:
# Gucci

A simple CLI templating tool written in golang. I created this because I wanted something that was more powerful than `envsubt` to use when templating files on the command line. I also used golang because I wanted a single binary.

[![GitHub version](https://badge.fury.io/gh/noqcks%2Fgucci.svg)](https://badge.fury.io/gh/noqcks%2Fgucci)
[![License](https://img.shields.io/github/license/noqcks/gucci.svg)](https://github.com/noqcks/gucci/blob/master/LICENSE)
[![Build Status](https://travis-ci.org/noqcks/gucci.svg?branch=master)](https://travis-ci.org/noqcks/gucci)

# Get

If you have go installed

```
go get github.com/noqcks/gucci
```

Or you can just download the binary and move it into your path

```
VERSION=0.0.4
wget -q https://github.com/noqcks/gucci/releases/download/v${VERSION}/gucci-v${VERSION}-darwin-amd64
chmod +x gucci-v${VERSION}-darwin-amd64
mv gucci-v${VERSION}-darwin-amd64 /usr/local/bin/gucci
```

# Use

gucci can take input in multiple ways

### file

```
$ gucci template.tpl > template.conf
```

### stdin

```
$ gucci
Start typing stuff {{ print "here" }}
^d
Start typing stuff here
```

via piping

```
$ echo '{{ html "<escape-me/>" }}' | gucci
```

# Templating

### GoLang Functions

All of the existing [golang templating functions](https://golang.org/pkg/text/template/#hdr-Functions) are available for use.

### Built In Functions

This is a list of custom functions this tool adds that you can use:

- `split`: Used to split strings

  ```
  {{ range split .BACKENDS "," }}
    server {{ . }}
  {{ end }}
  ```

- `shell`: For arbitrary shell commands

   ```
   {{ shell "cat VERSION.txt" }}
   ```

## Example

**NOTE**: gucci reads and makes available all environment variables.

For example a var $LOCALHOST = <IP_ADDRESS>

gucci template.tpl > template.conf

```
# template.tpl
{{ .LOCALHOST }}
```

`gucci template.tpl > template.conf` -->

```
# template.conf
<IP_ADDRESS>
```

simple enough!

For an iteration example, you have $BACKENDS=server1.com,server2.com

```
# template.tpl
{{ range split .BACKENDS "," }}
server {{ . }}
{{ end }}
```

`gucci template.tpl > template.conf` -->

```
# template.conf
server server1.com
server server2.com
```

### TODO

- add input sources (json & yaml files)

license: MIT

repository: hardware/gucci

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: hardware/gucci


text:
#Github-API-Open-Issue-Count
Input : User can input a link to any public GitHub repository

Output :
UI will display the following information -

- Total number of open issues
- Number of open issues that were opened in the last 24 hours
- Number of open issues that were opened more than 24 hours ago but less than 7 days ago
- Number of open issues that were opened more than 7 days ago

#DEMO
http://shippable.crazyslate.com

repository: rajibmitra/Github-API-Open-Issue-Count

repo_name: rajibmitra/Github-API-Open-Issue-Count


text:
# TacoLite: A simple SQLite and Modern C++ Integration library

This project is a handler for C++ SQLite3 API. It is intended to create a simple way to interact with database.

## Compile the project
Linux based compilation:

To compile the project install [Conan C++ Package manager](http://conan.io) and install sqlite3 using conan in your system, you can find it in conan center,
then just run:
```console
foo@bar :~$ mkdir build && cd build
foo@bar :~$ conan install ..
foo@bar :~$ cmake .. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
foo@bar :~$ cmake --build .
```

## How to use
sqlite-amalgamation folder is standalone, and it is not used in the project(because we installed it using Conan).\
Handle.h and SQLite.h are the celebrities here.\
Once sqlite is installed in your project by using conan, you can interact with sqlite in a easy way.

### Include in your project

```C++
#include "SQLite.h"
```

Now, be careful and try to using try and catch when using TacoLite.
### In a nutshell:

```C++
Connection connection = Connection::Memory();

// Creating connection and statement handler and doing the query at the same time
// preparing the query inside the Statement constructor by calling no member function
// Execute in sqlite.h
Execute(connection, "create table Users (Name)");
Execute(connection, "insert into Users values (?)", "Eduardo");
Execute(connection, "insert into Users values (?)", "Ana Belen");
Execute(connection, "insert into Users values (?)", "Juanisimo");

// to take all users getting by the iteration over the query
auto Users = std::vector<std::string>();

// getting the elements returned by the query
for(Row row : Statement(connection, "select Name from Users"))
{
    // GetString has a default parameter 0, but you can write it instead
    Users.push_back(row.GetString());
}

// showing all the users inside the vector
for(auto & user : Users)
{
    std::cout << "User: " << user << "\n";
}
```

### Creating a connection

```C++
try {
    // creating a database entirely in memory
    Connection connection = Connection::Memory();
    //or if you're using it to store wide characters
    Connection connection = Connection::WideMemory();
}
```

### Creating databases and inserting data

```C++
/// instead of in memory
// creating 2 physical databases, empties
Connection utf8("/home/cheetos/Developer/CProgramming/Cpp-AdvancedTopics/SQLiteInteraction/utf8database.db");
Connection utf16("/home/cheetos/Developer/CProgramming/Cpp-AdvancedTopics/SQLiteInteraction/utf16database.db");
```

### Executing a query and binding data
```C++
// statement handler
Statement statement;

// in case not a utf8 encoding, statements first convert any encoding type
// into utf8
// preparing the query
statement.Prepare(connection, "select ?1 union all select "
                              "?2 union all select ?3 union all select ?4 union all select ?5"
                              "union all select ?6");

// BINDING regular encodings
std::vector<std::string> data{"Hello", " ", "SQLite3 and C++"};

// if bindingAll is called and Bind too then BindAll should be called first
// automatic binding
statement.BindAll("hello", std::string("Your"), std::string("Name"));

// common bindings
statement.Bind(4, data[0]);
// binding a r-value is possible
statement.Bind(5, std::string("everybody over"));
statement.Bind(6, data[2]);
```

### Inline automatic binding

```C++
Connection connection = Connection::Memory();

Statement statement;

statement.Prepare(connection, "select ?1 union all select "
                                      "?2 union all select ?3 union all select ?4 union all select ?5"
                                      "union all select ?6", "Eduardo", 24, 16190278, "single", 70, "programmer");

//or:

// Creating statement handler and doing the query at the same time
// preparing the query inside the Statement constructor
Statement statement(connection, "select ?1 union all select "
                              "?2 union all select ?3 union all select ?4 union all select ?5"
                              "union all select ?6", "Eduardo", 24, 16190278, "single", 70, "programmer");
```

### Read the rows in your statement

```C++
// calling the Row iterator classes
for(Row const & row : statement)
{
    // simple loop for reading rows
    // using the reader
    std::cout << row.GetString(0) << "\n";
}
```

repository: eduardorasgado/Cpp-AdvancedTopics

repo_name: eduardorasgado/Cpp-AdvancedTopics


text:
# June 15, 2016

- Michelle Noorali gave an introduction
- Ben Hall, founder of katacoda, did a demo of [katacoda](https://www.katacoda.com/)
  - Katacoda is an interactive learning platform for software engineers.
  - Ben showed off the current lessons on Kubernetes which are available now.
  - Ben also talked about how companies/people can make their own interactive lessons and embed them.
  - Contact Ben on [Twitter](https://twitter.com/Ben_Hall): @Ben_Hall
- Eric Chiang demoed new Role Based Access Control features and capability in Kubernetes 1.3.
  - This demo was extensive and very helpful! Check out the [recording](https://www.youtube.com/watch?v=97VMYjfjWyg&list=PLI1CvzwXi1cUVsxm2QBIyJgeCkf62ylun&index=2) for the full scoop.
  - You can find the demo script/setup/example from the meeting in Eric's github repo [here](https://github.com/ericchiang/coreos-kubernetes/tree/sig-apps-demo/single-node).
- Michelle Noorali shared the sig-apps survey which can be found [here](http://goo.gl/forms/n7vcisBv3l9IuTQr1).

Watch the [recording](https://www.youtube.com/watch?v=97VMYjfjWyg&list=PLI1CvzwXi1cUVsxm2QBIyJgeCkf62ylun&index=2).

repository: kubernetes/community

gha_language: Jupyter Notebook

repo_name: kubernetes/community


text:
# Improve the "fresh-clone" story

Status: Pending

Version: Alpha

## Abstract

This document proposes to extend the dependency, registry, and environment
management code to provide a cleaner "fresh-clone" story.

Essentially, a user should only need to run `git clone` and `ks pkg install` to
get started developing, and it should not be necessary to check bulky metadata
files into a version control system to have a good clone-to-development story.
In this sense `ks pkg install` would take on a role similar to `npm install`,
which is used to obtain all dependencies of a node.js project.

## Motivation

The `ks` CLI tool is largely awkward to use with source control systems like
`git`. There are several reasons for this, but likely the biggest is that
ksonnet keeps around a lot of metadata that can (and should) be generated
automatically. Because it's not, users are forced to keep this in version
control, which is non-ideal.

Two good examples of this problem are:

1. source code for packages the application depends on, and
1. metadata associated with ksonnet _environments_ (_e.g._, information about
   the cluster, the `k8s.libsonnet` file that is generated based on the OpenAPI
   specification associated with that cluster, and so on).

(2) in particular is costly; each `k8s.libsonnet` is about ~1.7MB.

Since it is possible generate (or acquire) all of these things based on the
information in the `app.yaml` file, this commit proposes to introduce a `ks
install` command. This command follows the example set by NPM, a project with a
similar problem; NPM has a `package.json` file, and `npm install` is used to
(_e.g._) pull down dependencies from the NPM registry.

The related issue is captured in [#217][217].

## Goal

1. Make it trivial to clone and get started developing a ksonnet application (it
   should be two commands: `git clone` followed by `ks pkg install`).
1. Reduce the memory footprint of checking a ksonnet application into a source
   control system like `git` by autogenerating bulky metadata files.
1. Auto-generate a `.gitignore` as a result of `ks init`. (See issue [#55][55])
1. Don't block development because the user doesn't have access to an
   environment. For example, `prod` environments are usually locked down; a user
   should not be prevented from developing a ksonnet application simply because
   they don't have access to this environment. (They will obviously not be able
   to push to that environment, however.)
1. When `ks pkg install` runs, it should present a clear, easy-to-consume
   picture of what it's going to do (or has done). For example, it should say
   "installed these dependencies", _etc_.

## Proposal

This proposal consists mainly of two main bodies of work:

1. changes to the semantics and implementation of `ks pkg install` (which will
   attempt to get all dependencies if they are not already present)
1. changes to the way environments are initialized (_i.e._, we can't expect
   users to have access to all environments, so the `ks` CLI needs to be able to
   tolerate this).

### `ks pkg install`

We propose the form of the command should change from `ks pkg install
<pkg-name>` to `ks pkg install [pkg-name]` (_i.e._, we propose `pkg-name` should
be optional).

When run with no `pkg-name`, `ks pkg install` should cause all dependencies to
be installed if not present. Specifically:

1. We traverse the list of registries in `app.yaml` and attempt to retrieve and
   cache each of them locally.
1. We traverse the list of dependencies in `app.yaml` and attempt to install
   them one by one.

Other changes related to partially-initialized ksonnet applications are not
necessary. For example, if a user runs `git clone` and forgets to run `ks pkg
install`, we should allow the Jsonnet compiler to not find the dependency, and
error out. If this becomes an expressed problem from users, we can re-evaluate.

This notably does _not_ solve the problem of generating the environment
metadata. This is handled in the next section.

### Lazily-instantiated environments

A number of commands depend on a fully-initialized environment. Since we cannot
expect users to have access to all environments (_e.g._, most `prod`
environments are locked down), the `ks` CLI tool needs to tolerate this case
when the locked-down environments aren't needed, and it needs to present useful
errors in the case they are.

To resolve this problem, we propose that environments should be _instantiated
lazily_ (by which we mean _when needed_ rather than ahead of time).
Specifically, we propose that commands that interact with the environment
(_e.g._, `ks diff`, `ks apply`, and so on) have the following workflow:

1. Check whether the environment is initialized.
1. If it is, try to run the command.
1. If it's not, attempt to initialize the environment from the existing
   metadata.

## User Experience

### Backwards compatibility

This change will be backwards-compatible.

## Alternatives considered

The only alternative is to do what we are doing now, which is to force users to
check the metadata files into source control.

[55]: https://github.com/ksonnet/ksonnet/issues/55
[217]: https://github.com/ksonnet/ksonnet/issues/217

repository: comet-ml/kubeflow

gha_language: Python

repo_name: comet-ml/kubeflow


text:
---
title: 'Bangalore Calling'
date: '2008-12-14T22:07:13+05:30'
status: publish
permalink: /2008/12/14/bangalore-calling
author: vishy
description: ''
type: post
id: 26
featured_image: ../../../../uploads/2008/12/cubbon_park_BANGALORE1_12929f_thehindu_com.jpeg
categories:
    - R2I
tags:
    - 'bangalore calling'
    - bengaluru
    - 'move to bangalore'
    - 'move to india'
    - 'moving to bangalore'
    - 'moving to india'
    - nri
    - 'R2I (Decisions)'
    - 'return to india'
    - 'returning nri'
post_format: []
image:
    - ''
seo_follow:
    - 'false'
seo_noindex:
    - 'false'
---

[![](../../../../uploads/2008/12/cubbon_park_BANGALORE1_12929f_thehindu_com.jpeg "cubbon_park_BANGALORE1_12929f_thehindu_com")](http://www.ulaar.com/wp-content/uploads/2008/12/cubbon_park_BANGALORE1_12929f_thehindu_com.jpeg)
Cubbon Park, Bangalore (circa 2009) – Pic courtesy thehindu.com

(Someday this post shall be completed. Until then, here’s a relevant comment thread between me and a New Jersey Indian American woman contemplating the move.)

Other posts related to the “Where in India” decision:

- [Where in India are we moving to?](http://www.ulaar.com/2008/05/30/where-in-india-are-we-moving-to/)
- [The Bombay Seduction](http://www.ulaar.com/2008/06/12/the-bombay-seduction/)
- [Gurgaon Growling](http://www.ulaar.com/2009/06/18/gurgaon-growling/)
- [100 days in Bangalore (Part 1)](http://www.ulaar.com/2008/12/14/100-days-in-bangalore-part1/)

*—-*

*Hi Vishy,
Great and interesting blog!! I am a 26 yr old married woman staying in NJ from last 2 years. My hubby works with an investment bank. We two are also seriously thinking of moving back to India and we definitely belong to “should-we” group..:)I read all your posts, sequentially, right from the first one and really felt surprised how simila we ppl think in terms of living in US and when talked about going back to India. We also are in the process of deciding upon the city to which we want to move. And we hav also selected Delhi/NCR, Bangalore, Mumbai as our options. Both of us belong to UP.
I have seen New York city and absolutely love its diverse and cosmopolitan crowd, the freedom in the air. And thats why I am more inclined to settle in Mumbai. When I was reading your post “The Bombay Seduction”, I felt its something special about Mumbai city that everybody who goes there falls in love with that..:)but later in your post found out that you are settled in Bangalore. Would you please tell me why you and Poonam made this decision? I understand its all the individual’s choice and the preferences but in the end of the post you showed your intent of living in Mumbai. Actually I am collecting all possible informations from my friends and different sources which can help us in making a right decision about the city, job etc while moving back to India. Your valuable experience might help us.
Once again would like to say I really liked your blog. You have put your thoughts and experiences in a very interesting manner. Would love to hear from you,
With Best Wishes,
PS*

——

—–

*Hi PS,
So glad you are finding the blog interesting & useful. There are 3 posts that I never completed:
Gurgaon Growling
Bangalore Calling
Why we chose Bangalore*

*I have a fond hope that during the Christmas holidays I’ll complete them (your comment is inspiration enough). Meanwhile here’s the short version of our decision:
1\. Since we have 2 young kids, having sufficient “playing spaces” was a top criterion. This translated to “gated apartment communities” which were present in greater profusion (& affordability) in Bangalore than Mumbai.
2\. Had we been contemplating this move 10 (or even 6) yrs ago – an era sans kids, Bombay might have trumped Bangalore.
3\. New York is to Mumbai as Silcon Valley is to Bangalore. During our years in US, both Poonam & I longed to live in New York for a few years. The window of opportunity (we felt) was again in the pre-kids era so it passed.
4\. I’m not saying a family with kids cannot live in Mumbai – it’s just that for a family with kids returning from US, Bangalore is a softer landing than Mumbai. In your case (assuming you don’t have kids yet), Mumbai sounds like a great fit, especially if you consider the fact that your hubby is an investment banker (for financial folks, Mumbai trumps Bangalore big time).
5\. Finally, after spending 10 excellent yrs in Silicon Valley, the fact that Bangalore ethos was the closest to it clinched it for us. Will elaborate on this in the ‘Bangalore Calling’ post ![:)](https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif)*

*Wish you the best in your moving plans. Hey – maybe you should start your blog? And keep the questions/comments coming..*

*Vishy*

—–

*Hi Vishy,*

*Thanks for your reply!! Many of the NRI people whom I have interacted with have chosen Bangalore to settle down while moving back to India. I wish to know the positive aspects about B’lore city- is it
1\. plenty of job options
2\. similar-to-US lifestyle
3\. Pleasant Weather*

*However, I have heard from my age-group people that Bangalore has extremely high cost of living(high rents and real estate prices). And the road traffic is sickening and horrible over there.*

*If possible, pls share your views and experience (till date) about Bangalore and Mumbai city. I will be looking for a job in an IT co., so would like to explore whether Mumbai would have enough IT job opportunities. Also as you have moved very recently there, is the IT job market bad in India too? Is hiring taking place?*

*Looking forward to your next posts..:)
Happy Christmas and a great new year 2009!!
PS*

——

*PS,
Yes to all three – plenty (read PLENTY) of job options – especially for techies, closest to SF Bay Area (& by corollary US) and best weather among all the leading metros. One cannot over-emphasize that aspect. There’s a reason Californians are happier than East-coasters (ok – I only have anecdotes as proof). I believe every Indian metro has one redeeming quality – in the case of Bangalore, #1 is the weather.  Then again, with the exception of Delhi/NCR, other metros are no great shakes either. Mumbai traffic is quite lousy, Hyderabad’s traffic might get better faster than Bangalore’s.*

*Regarding IT jobs in Mumbai – sure there are a fair number of them but it doesn’t come close to Bangalore. If you are looking for a career in technology product development, Bangalore is a clear #1 (followed by Hyderabad, Chennai, and Gurgaon/Delhi – order depends on who you’d ask). If it’s IT in finance, Mumbai would be a really good bet.*

*The IT job market in India is not yet bad. However the operative word may be ‘yet’. Technology product & service companies are still hiring in 2009 but everyone’s really cautious. In this global meltdown state, it’s hard not to get affected.*

*Vishy*

—–

repository: ulaari/ulaar

gha_language: JavaScript

gha_license_id: MIT

repo_name: ulaari/ulaar


text:
---
title: 'Building V8 with GN'
description: 'This document explains how to use GN to build V8.'
---
V8 is built with the help of [GN](https://gn.googlesource.com/gn/+/master/docs/). GN is a meta build system of sorts, as it generates build files for a number of other build systems. How you build therefore depends on what “back-end” build system and compiler you’re using.
The instructions below assume that you already have a [checkout of V8](/docs/source-code) and that you have [installed the build dependencies](/docs/build).

More information on GN can be found in [Chromium’s documentation](https://www.chromium.org/developers/gn-build-configuration) or [GN’s own docs](https://gn.googlesource.com/gn/+/master/docs/).

Building V8 from source involves three steps:

1. generating build files
1. compiling
1. running tests

There are two workflows for building V8:

- the convenience workflow using a helper script called `gm` that nicely combines all three steps
- the raw workflow, where you run separate commands on a lower level for each step manually

## Building V8 using `gm` (the convenience workflow) { #gm }

`gm` is a convenience all-in-one script that generates build files, triggers the build and optionally also runs the tests. It can be found at `tools/dev/gm.py` in your V8 checkout. We recommend adding an alias to your shell configuration:

```bash
alias gm=/path/to/v8/tools/dev/gm.py
```

You can then use `gm` to build V8 for known configurations, such as `x64.release`:

```bash
gm x64.release
```

To run the tests right after the build, run:

```bash
gm x64.release.check
```

`gm` outputs all the commands it’s executing, making it easy to track and re-execute them if necessary.

`gm` enables building the required binaries and running specific tests with a single command:

```bash
gm x64.debug mjsunit/foo cctest/test-bar/*
```

## Building V8: the raw, manual workflow { #manual }

### Step 1: generate build files { #generate-build-files }

There are several ways of generating the build files:

1. The raw, manual workflow involves using `gn` directly.
1. A helper script named `v8gen` streamlines the process for common configurations.

#### Generating build files using `gn`  { #gn }

Generate build files for the directory `out/foo` using `gn`:

```bash
gn args out/foo
```

This opens an editor window for specifying the [`gn` arguments](https://gn.googlesource.com/gn/+/master/docs/reference.md). Alternatively, you can pass the arguments on the command line:

```bash
gn gen out/foo --args='is_debug=false target_cpu="x64" v8_target_cpu="arm64" use_goma=true'
```

This generates build files for compiling V8 with the arm64 simulator in release mode using `goma` for compilation.

For an overview of all available `gn` arguments, run:

```bash
gn args out/foo --list
```

#### Generate build files using `v8gen` { #v8gen }

The V8 repository includes a `v8gen` convenience script to more easily generate build files for common configurations. We recommend adding an alias to your shell configuration:

```bash
alias v8gen=/path/to/v8/tools/dev/v8gen.py
```

Call `v8gen --help` for more information.

List available configurations (or bots from a master):

```bash
v8gen list
```

```bash
v8gen list -m client.v8
```

Build like a particular bot from the `client.v8` waterfall in folder `foo`:

```bash
v8gen -b 'V8 Linux64 - debug builder' -m client.v8 foo
```

### Step 2: compile V8 { #compile }

To build all of V8 (assuming `gn` generated to the `x64.release` folder), run:

```bash
ninja -C out/x64.release
```

To build specific targets like `d8`, append them to the command:

```bash
ninja -C out/x64.release d8
```

### Step 3: run tests { #tests }

You can pass the output directory to the test driver. Other relevant flags are inferred from the build:

```bash
tools/run-tests.py --outdir out/foo
```

You can also test your most recently compiled build (in `out.gn`):

```bash
tools/run-tests.py --gn
```

**Build issues? File a bug at [v8.dev/bug](/bug) or ask for help on<EMAIL_ADDRESS>

branch_name: refs/heads/main


text:
# quick-cordova-android-tv

NOTE: This is a plugin forked from lycwed (see lycwed-cordova-plugin-android-tv), and is essentially the same thing, with a few tweaks made to allow for it to use the same Android activity as any cordova app which uses MainActivity.

Cordova plugin to manage app for Android TV.

## Install

`cordova plugin add https://github.com/faqro/quick-cordova-android-tv.git`

## Requirements

Include banners in config.xml at varying sizes as splash images. These will be automatically added to various 'drawable' folders.

Then add in your config.xml in platform android :

```xml
        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
            <application android:banner="@drawable/screen" />
            <application android:isGame="true" />
        </edit-config>
```

repository: faqro/quick-cordova-android-tv

repo_name: faqro/quick-cordova-android-tv


text:
Lab Report Template for CIS411_Lab0
Course: Messiah College CIS 411, Fall 2018
Instructors: Joel Worrall & Trevor Bunch
Name: Drew Feldman
GitHub: DrewRFeldman
Step 1: Fork this repository
https://github.com/DrewRFeldman/cis411_lab0
The accompanying diagram of what my fork precisely and conceptually represents
https://docs.google.com/drawings/d/1XnyDNvx4CySERyUQh_7TGzCZSk5WRbbRNFNBDxwDnPc/edit?usp=sharing
Step 2: Clone your forked repository from the command line
My GraphQL response from adding myself as an account on the test project
``` JSON
{
  "data": {
    "mutateAccount": {
      "id": "faad80fc-52b9-4cb3-beb5-fabb2a291a82",
      "name": "Drew Feldman",
      "email"<EMAIL_ADDRESS>    }
  }
}
```
Step 3: Creating a feature branch
The output of my git commit log
d2ddea5 (HEAD -> master, origin/master, origin/HEAD) Version 0.0.1 of the lab instructions
ab312fc more progress
62fb0a5 more progress
fe1937b more in the lab instructions
3e807fb first section
9ae6b83 remove LAB.md
e429c1a lab instructions
968099e remove test db
7362cd1 working
44ce6ae Initial commit
The accompanying diagram of what my feature branch precisely and conceptually represents
https://docs.google.com/drawings/d/1amICOGRvqSiRTOhNTL_8t3MmSojMFRfK8WRidiYwxiA/edit?usp=sharing
Step 4: Setup a Continuous Integration configuration
What is the .circleci/config.yml doing?
It is error checking the commit to see if the commit is going to cause errors for the project. I think.
It does this by pulling the code from the repository and creating a virtual instance to test and make sure everything is working.
What do the various sections on the config file do?
Version shows which version of CircleCI you're using. The Jobs section contains all the tasks that need to be executed. The build is the build of the current job being worked on, and the docker designates which docker to use. Image dictates which version of node to use, steps explains the build process, yarn install downloads anything circleci needs for the test, yarn test tests the code. I think. This is all super confusing to me, I tried to get it explained by friends.
When a CI build is successful, what does that philosophically and practically/precisely indicate about the build?
It shows that the changes to the existing file blend well and that no errors were produced. This means the code is sound.
If you were to take the next step and ready this project for Continuous Delivery, what additional changes might you make in this configuration (conceptual, not code)?

Step 5: Merging the feature branch

The output of my git commit log

d7b74f2 (HEAD -> master, origin/master, origin/HEAD) Finished Lab Report
0428c7b Changes to lab reports file.
5dd212d (labreport) Commiting changes to feature branch.
a3abcde (origin/labreport) Just a random commit
3249302 Commit 1 @tangollama
dabceca (lapreport) Merge pull request #24 from tangollama/circleci
a4096db Create README.md
2f01bf4 Update LAB_INSTRUCTIONS.md
347bd50 Update LAB_INSTRUCTIONS.md
7aaa9f3 Update LAB_INSTRUCTIONS.md
37393ae Bug fixed
1949d2a Update LAB_INSTRUCTIONS.md
d36ad90 Update LAB.md
59ef18a Update LAB_INSTRUCTIONS.md
37be3c8 Update LAB_INSTRUCTIONS.md
97da547 Update LAB.md
0bd6244 (origin/purelab) updated Step 0 title
4562cd8 added npm and node install repreq
255051e adding template
13a09b7 Adding the LAB.md and correcting some instructions.
d2ddea5 Version 0.0.1 of the lab isntructions
ab312fc more progress
62fb0a5 more progress

A screenshot of the Jobs list in CircleCI
Step 6: Submitting a Pull Request
Remember to reference at least one other student in the PR content via their GitHub handle.
Step 7: [EXTRA CREDIT] Augment the core project
PR reference in the report to one of the following:
Add one or more unit tests to the core assignment project.
Configure the CircleCI config.yml to automatically build a Docker image of the project.
Configure an automatic deployment of the successful CircleCI build to an Amazon EC2 instance.


text:
# Lambdakiq

TODO ...

```ruby
# TODO ...
```

## Contributing

After checking out the repo, run:

```shell
$ ./bin/bootstrap
$ ./bin/setup
$ ./bin/test
```

Bug reports and pull requests are welcome on GitHub at https://github.com/customink/lambdakiq. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.

## Code of Conduct

Everyone interacting in the Lambdakiq project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/customink/lambdakiq/blob/master/CODE_OF_CONDUCT.md).

repository: jdaviderb/lambdakiq

repo_name: jdaviderb/lambdakiq


text:
linters
=======

This repository is a child of [Sublime Lint](http://github.com/lunixbochs/sublimelint "Sublime Lint") and will be automatically installed.

NOTE: You may need to install the mentioned binaries and place them within your `PATH` for some linters to work.

Languages:

* AppleScript - NSAppleScript via PyObjC
* C - validation via `clang`
* C++ - validation via `clang++`
* CSS - linting via `csslint`
* CoffeeScript - validation via `coffee --compile`
* Go - validation via `go build` in a temporary folder
* HAML - checking via `haml -c`
* HTML - linting via `tidy`
* Java - linting via Eclipse command-line `eclim`
* JavaScript - linting via JSLint command-line `jsl`
* Lua - syntax checking via `luac -p`
* NASM - validation via `nasm` and a temporary file
* PHP - syntax checking via `php -l`
* Perl - syntax+deprecation checking via `perl -c`
* Python - linting via `pyflakes`
* Puppet - parsing via `puppet parser validate`
* Ruby - syntax checking via `ruby -wc`
* XML - linting via `xmllint`

repository: lunixbochs/linters

extension: markdown

repo_name: lunixbochs/linters


text:
# SpriteSheetPacker

Sprite Sheet Packer is a fully featured tool for combining multiple individual images into a single, efficiently laid out image.

![](https://github.com/nickgravelyn/spritesheetpacker/blob/master/images/ToolUI.png)

Sprite Sheet Packer supports reading PNG, JPG, BMP, and GIF images and produces a single PNG image with all the images embedded inside of it. The resulting image is transparent anywhere an image is not drawn. The tool also produces an accompanying file that maps the image file names with their rectangles, for use in your program to find the regions of the image you are interested in.

The tool has a full UI including options for setting the maximum resulting image size, padding (added to the size of the individual images), as well as options for requiring a power-of-two sized output and a square output. The tool has buttons for managing the desired images and also accepts drag-and-drop of image files into the list for true ease of use.

The build process is completely multithreaded to ensure smooth operation of the application even when processing large numbers of images.

The tool now supports plugins so you can create your own image or map file types without having to edit the application. Once you've compiled a DLL with your types in it, simply place it next to the exe and run the application. When you are choosing your image or map file location, use the drop down to choose the file type. For an example, see the XNA XML exporter in the source tree which exports an XML file in XNA Content format instead of the standard text file. The XNA XML exporter is also included, in compiled form, with the regular download.

Here are some sample output files created from 720 individual images found here: http://blogoscoped.com/archive/2006-08-08-n51.html using various combinations of the "Require Power of Two Output" and "Require Square Output" options:

Non-power of two and non-square:

![](https://github.com/nickgravelyn/spritesheetpacker/blob/master/images/Sheet1.png)

Power of two and non-square:

![](https://github.com/nickgravelyn/spritesheetpacker/blob/master/images/Sheet2.png)

Non-power of two and square:

![](https://github.com/nickgravelyn/spritesheetpacker/blob/master/images/Sheet3.png)

Power of two and square:

![](https://github.com/nickgravelyn/spritesheetpacker/blob/master/images/Sheet4.png)

For an example of parsing the text output with XNA Game Studio, see Using Sprite Sheet Packer with XNA GS.

All code was written by Nick Gravelyn except the code for computing the efficient placement of the rectangles which was taken from the [Nuclex Framework](http://nuclexframework.codeplex.com/).

repository: walteryoung/SpriteSheetPacker

repo_name: walteryoung/SpriteSheetPacker


text:
# `@actions/exec`

## Usage

#### Basic

You can use this package to execute your tools on the command line in a cross platform way:

```js
const exec = require('@actions/exec');

await exec.exec('node index.js');
```

#### Args

You can also pass in arg arrays:

```js
const exec = require('@actions/exec');

await exec.exec('node', ['index.js', 'foo=bar']);
```

#### Output/options

Capture output or specify [other options](https://github.com/actions/toolkit/blob/d9347d4ab99fd507c0b9104b2cf79fb44fcc827d/packages/exec/src/interfaces.ts#L5):

```js
const exec = require('@actions/exec');

let myOutput = '';
let myError = '';

const options = {};
options.listeners = {
  stdout: (data: Buffer) => {
    myOutput += data.toString();
  },
  stderr: (data: Buffer) => {
    myError += data.toString();
  }
};
options.cwd = './lib';

await exec.exec('node', ['index.js', 'foo=bar'], options);
```

#### Exec tools not in the PATH

You can use it in conjunction with the `which` function from `@actions/io` to execute tools that are not in the PATH:

```js
const exec = require('@actions/exec');
const io = require('@actions/io');

const pythonPath: string = await io.which('python', true)

await exec.exec(`"${pythonPath}"`, ['main.py']);
```

repository: r-lib/actions

repo_name: r-lib/actions


text:
## The Problem

<!--- Why is this change required? What problem does it solve? Bug fix or new feature? -->
<!--- If it fixes an open issue, please link to the issue here. -->

## The Solution

<!--- Describe the changes you made at a high level -->
<!--- Leave comments on the source diff to draw attention to important low-level specifics -->

## Checklist

- [ ] Test manually on `test-ui` using remote chains.
- [ ] Run load tests.
- [ ] Update documentation if needed.
- [ ] Update CHANGELOG.md.

repository: gelatodigital/nxtp

repo_name: gelatodigital/nxtp


text:
---
layout: post
title: "Streamlining Contingency Tables"
---

Medical Statistics: Scripted

# Contingency Table
A contingency table is a matrix formatted view of the frequency distribution of given variables.

## 2x2 Contingency Table
```Python3
"""
Example Contingency Table:
---------------------------------
Outcome      Treatment Groups
_________________________________
            Test        Control
Positive     a             c
Negative     b             d
Total       a+b           c+d
---------------------------------
Key:
a = t_pos
b = t_neg
c = c_pos
d = c_neg
"""
```

## Libraries
```Python3
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
```

## Proportion of positive outcomes under test condition
### Used for treatment comparison to control
```Python3
def p_test_subs(t_pos, t_neg):
    """
    Calculate proportion of positive outcomes under test condition
    :param t_pos: Positive results in Test group
    :param t_neg: Negative results in Test group
    :return p_test: Proportion of subjects w/ positive outcome under treatment/test condition
    """
    total = t_pos+t_neg
    p_test = t_pos/total
    return p_test
```
## Proportion of positive outcomes under control condition
### Used for treatment comparison to control
```Python3
def p_control_subs(c_pos, c_neg):
    """
    Calculate proportion of positive outcomes under control condition
    :param c_pos: Positive results in Control group
    :param c_neg: Negative results in Control group
    :return p_control: Proportion of subjects w/ positive outcome under control condition
    """
    total = c_pos+c_neg
    p_control = c_pos/total
    return p_control
```
## Basic difference of proportions of positive results in test, control groups
```Python3
def diff_proportions(p_test, p_control):
    """
    Calculate difference of proportions of positive results in test, control groups
    :param p_test: Proportion of positive outcome under test
    :param p_control: Proportion of positive outcome under control
    :return dop: Difference of proportions of p_test and p_control
    """
    dop = p_control - p_test
    return dop
```
## Absolute risk difference of positive results in test, control groups
### Used for clinical trials
```Python3
def diff_proportions(p_test, p_control):
    """
    Calculate Absolute risk difference (ARD) of positive results in test, control groups
    :param p_test: Proportion of positive outcome under test
    :param p_control: Proportion of positive outcome under control
    :return ard: Absolute risk difference
    """
    ard = np.abs(p_control - p_test)
    return ard
```
## Relative Risk
### Used for prospective studies
```Python3
def relative_risk(p_test, p_control):
    """
    Calculates relative risk
    :param p_test: Proportion of positive outcome under test
    :param p_control: Proportion of positive outcome under control
    :return rr: Relative Risk(RR)
    """
    rr = p_test/p_control
    return rr
```
## Number needed to treat/harm (NNT)
### Inverse of RR
```Python3
def NNT(p_test, p_control):
    """
    Calculate Number needed to treat (NNT) of positive results in test, control groups
    :param p_test: Proportion of positive outcome under test
    :param p_control: Proportion of positive outcome under control
    :return nnt: number needed to treat
    """
    nnt = 1 / np.abs(p_test - p_control)
    return nnt
```

## Odds Ratio (OR)
### Ratio of occurences/non-occurence between test/control groups
```Python3
def OddsRatio(p_test, p_control):
    """
    Calculates odds ratio
    :param p_test: Proportion of positive outcome under test
    :param p_control: Proportion of positive outcome under control
    :return odds_ratio: Ratio of odds of occurence/non-occurence for test and control groups
    """
    test_group = p_test/(1-p_test)
    control_group = p_control/(1-p_control)
    odds_ratio = test_group/control_group
    return odds_ratio
```


text:
## 🥳 What?

Last Friday (14-10-2022) I was trying to renew my github profile and I thought
that it would be nice to share something outside "coding stuff", so that whoever
visits it might get to know a little bit more about me.

Three months ago I decided to fight some anxiety episodes by running away from
them (literally). After becoming a runner and having run for a while I thought
that would be cool to share my strava stats.

## 🤌 Objective

**Share a summary of the strava stats in my github profile**

## 🤯 Iterations

1. Iframe not rendered in github
2. Iframe not working properly anyway
3. Floki, req and the DOM first load

### Iframe not rendered in github

If you go to your profile in strava, you will find a share button in the bottom
right corner that says "Share Activities". If you press this button, a pop-up
will appear with some html code (an iframe) that you can embed into your code.
Theoretically markdown lets you use inline html, [see this
post](https://daringfireball.net/projects/markdown/syntax#html).

_The result:_

As I suspected, even though markdown allows inline html, github does not render
it. It makes sense for security reasons. At this point I thought maybe it does
not work in my github profile but there is not reason why it should not work in
github pages.

### Iframe not working properly anyway

Before trying anything in github pages, I wanted to create a simple html with
the iframe snippet embedded.

```html
<html>
  <body>
    <iframe
      height="160"
      width="300"
      frameborder="0"
      allowtransparency="true"
      scrolling="no"
      src="https://www.strava.com/athletes/16733304/activity-summary/7193d786bd475377789a5eb93321d996755cde76"
    >
    </iframe>
  </body>
</html>
```

Surprisingly the iframe is not rendering the right stats. In fact, it looks like
it is not rendering any stats at all.

Yet these are the real stats in my public profile:

At this point I opened a ticket in strava support and totally parked the iframe
idea.

### Floki, req and the DOM first load

As the public profile is loading the right stats, my mind tells me that the
next natural approach is to parse the DOM in that public page and gather the
stats.

Thanks to elixir scripting introduced in [elixir
1.12](https://github.com/elixir-lang/elixir/releases/tag/v1.12.0) we can easily
achieve this by using req and floki with
[`Mix.install/2`](https://hexdocs.pm/mix/1.12/Mix.html#install/2):

```elixir
Mix.install([
  {:req, "~> 0.2"},
  {:floki, "~> 0.33.1"}
])

"https://www.strava.com/athletes/1673330"
|> Req.get!()
|> Map.fetch!(:body)
|> Floki.parse_document()
```

Unfortunately this does not work as the stats shown in the public profile are
loaded after the DOM has been rendered by some 💩 jQuery or who knows 🤷. This
outcome drove me to my latest iteration and final solution.

**Note: you actually need to be authenticated to see those stats :sweat_smile:**

## 🤠 Final solution

1. Strava API
   1. Refreshing the OAuth token
   2. Getting the activities
   3. EEX and rewriting the readme
2. Automating the summary with GHA

### Strava API

**You need to create an strava application, see
[the docs](https://developers.strava.com/docs/authentication/).**

To be able to perform requests the Strava API without user interaction, we need
to get a OAuth refresh token. We can build a simple router with plug and
[strava](https://github.com/slashdotdash/strava) to print the refresh token
like this:

```elixir
defmodule StravaSync.Router do
  use Plug.Router

  plug Plug.Logger
  plug :match
  plug :dispatch

  get "/activities" do
    url =
      "http://www.strava.com/oauth/authorize?client_id=#{Strava.client_id()}&response_type=code" <>
        "&redirect_uri=#{URI.encode_www_form(Strava.redirect_uri())}&approval_prompt=force" <>
        "&scope=read_all,profile:read_all,activity:read_all,activity:write"

    body = "<html><body>You are being <a href=\"#{url}\">redirected</a>.</body></html>"

    conn
    |> put_resp_header("location", url)
    |> send_resp(conn.status || 302, "text/html", body)
  end

  get "/authenticate" do
    conn =
      %{
        query_params: %{
          "code" => code
        }
      } = conn |> fetch_query_params()

    %OAuth2.Client{
      token: %OAuth2.AccessToken{
        refresh_token: refresh_token
      }
    } = Strava.Auth.get_token!(code: code, grant_type: "authorization_code")

    IO.inspect(refresh_token, label: RefreshToken)
    send_resp(conn, 200, "application/json", Jason.encode!(%{refresh_token: refresh_token}))
  end

  match _ do
    send_resp(conn, 404, "text/html", "oops")
  end

  defp send_resp(conn, status, content_type, body) do
    conn
    |> put_resp_content_type(content_type)
    |> send_resp(conn.status || status, body)
  end
end
```

Once you visit `localhost:4000/activities` and you follow the OAuth
authorization flow, you need to save the `refresh_token` somewhere. If you the
router code snippet there is a `IO.puts` that will print it for us.

#### Refreshing oauth token

After getting the refresh token you can ask for new access tokens if you hit
the refresh token url with your `client_id` and `client_secret` as query
params.

```elixir
Mix.install([
  {:req, "~> 0.2"},
  {:timex, "~> 3.7.9"}
])

strava_client_id = System.get_env("STRAVA_CLIENT_ID")
strava_refresh_token = System.get_env("STRAVA_REFRESH_TOKEN")
strava_client_secret = System.get_env("STRAVA_CLIENT_SECRET")

refresh_token_url =
  "https://www.strava.com/oauth/token?" <>
    "grant_type=refresh_token&refresh_token=#{strava_refresh_token}&" <>
    "client_id=#{strava_client_id}&client_secret=#{strava_client_secret}"

%{
  body: %{
    "access_token" => access_token,
    "refresh_token" => refresh_token
  }
} = Req.post!(refresh_token_url)
...
```

#### Getting the activities

By hitting the refresh token url beforehand and always, we ensure that anytime
we hit the activities url, our `access_token` will be valid; making our stats
gathering script idempotent. Now we can get the activities like so:

```elixir
...
after_unix = Date.utc_today() |> Timex.shift(months: -1) |> Timex.to_unix()

{:ok, %{body: activities}} =
  Req.get("https://www.strava.com/api/v3/athlete/activities?after=#{after_unix}&per_page=200",
    headers: [{"Authorization", "Bearer #{access_token}"}]
  )
...
```

**I wanted the stats of the last month, that is why after_unix is in place.**

#### EEX and rewriting the readme

All of this is looking quite sexy so far, but, how do I show this in the
readme? If I want the stats to be shown in my profile, I need to use some kind
of templating system that allows me to build the stats and produce a new
updated readme.

This is when EEX comes to play:

```elixir
...
new_readme =
  "README.md.eex"
  |> File.read!()
  |> EEx.eval_string(
    number_of_runs: number_of_runs,
    total_elevation_gain: :erlang.float_to_binary(summary.total_elevation_gain, decimals: 2),
    total_time: Format.to_hh_mm_ss(summary.total_time),
    total_distance:
      summary.total_distance |> Kernel./(1000) |> :erlang.float_to_binary(decimals: 2),
    from_date: after_unix |> DateTime.from_unix!() |> DateTime.to_date(),
    to_date: DateTime.utc_now() |> DateTime.to_date()
  )

File.write!("README.md", new_readme)
```

and the `README.md.eex` contains:

```eex
  * Runs: <%= number_of_runs %>
  * Elevation Gain: <%= total_elevation_gain %> m
  * Total time: <%= total_time %>
  * Total distance: <%= total_distance %> km
```

### 🤖 Automating the summary with GHA.

If you know me, you will already be aware that if something can be automated, I
will do so.

In this case I wanted to:

- RUN the sexy script on a weekly basis.
- Commit the new readme.

I did this via [github_actions](https://github.com/features/actions):

```yaml
---
- name: Strava sync
  env:
    STRAVA_CLIENT_ID: ${{ secrets.STRAVA_CLIENT_ID }}
    STRAVA_REFRESH_TOKEN: ${{ secrets.STRAVA_REFRESH_TOKEN }}
    STRAVA_CLIENT_SECRET: ${{ secrets.STRAVA_CLIENT_SECRET }}
  run: elixir strava_sync.ex

- name: Get current date
  id: date
  run: echo "::set-output name=date::$(date +'%Y-%m-%d')"

- name: Commit changes
  uses: EndBug/add-and-commit@v9
  with:
    author_name: Josep Lluis Giralt D'Lacoste
    author_email<EMAIL_ADDRESS>    message: "Strava sync ${{ steps.date.outputs.date }}"
    add: "*.md"
```

- find the full elixir script in [here](https://github.com/gilacost/gilacost/blob/master/strava_sync.ex).
- find the GHA action in [here](https://github.com/gilacost/gilacost/blob/master/.github/workflows/strava_sync_ex.yml).
- latest strava sync workflow badge ![Strava sync EX](https://github.com/gilacost/gilacost/workflows/Strava%20sync%20EX/badge.svg)

love ❤ and peace 🐦 to all

repository: gilacost/gilacost

gha_language: Erlang

repo_name: gilacost/gilacost


text:
---
layout: default
---

# 1995-12-19 - Java and timing info - second attempt

## Header Data

From<EMAIL_ADDRESS>(Jim Miller)

To<EMAIL_ADDRESS>Message Hash: 5c159f56d3d7dbc63cda41a3bc2b0936f94da80f51d3af1951d7f125b5a36aba

Message ID<EMAIL_ADDRESS>Reply To: _N/A_

UTC Datetime: 1995-12-19 04:02:48 UTC

Raw Date: Mon, 18 Dec 95 20:02:48 PST

## Raw message

```
{% raw  %}From<EMAIL_ADDRESS>(Jim Miller)
Date: Mon, 18 Dec 95 20:02:48 PST
To<EMAIL_ADDRESS>Subject: Java and timing info - second attempt
Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

I asked about using Java scripts to capture remote timing info before and
got no response.
Therefore, I'll ask it again.

The thing that makes Java a big deal is that you execute other people's
code on your machine.

Combine this with some a standard crypto API for doing Web-based digital
signatures or authentication or encryption and you may begin to see some
possibilities.

Would it be possible to create a Java applet that causes the client
machine to sign or encrypt something with their private key, and then send
back timing info?

For the answer to be YES a few things need to be true.  There needs to be
some sort of standard crypto API in use that can be accessed by a Java
script, and Java scripts need to be able to capture and send back timing
info.  Does anyone on this list know enough about Java to know if it can
do any of these things?

<EMAIL_ADDRESS>

{% endraw %}
```

## Thread

+ Return to [December 1995](/archive/1995/12)

+ Return to<EMAIL_ADDRESS>(Futplex)](/authors/futplex_at_pseudonym_com_futplex_)"
+ Return to "[Jeff Weinstein <jsw@netscape.com>](/authors/jeff_weinstein_jsw_at_netscape_com_)"
+ Return to<EMAIL_ADDRESS>(Jim Miller)](/authors/jim_at_bilbo_suite_com_jim_miller_)"

+ 1995-12-19 (Mon, 18 Dec 95 20:02:48 PST) - Java and timing info - second attempt -<EMAIL_ADDRESS>(Jim Miller)_
  + 1995-12-19 (Tue, 19 Dec 1995 15:39:38 +0800) - [Re: Java and timing info - second attempt](/archive/1995/12/c9d191e3cdadbd179f009c2a6f21fddcd5f660bb0aef136e80910330b5fa3a53) - _Jeff Weinstein<EMAIL_ADDRESS>  + 1995-12-19 (Tue, 19 Dec 1995 16:43:51 +0800) - [Re: Java and timing info - second attempt](/archive/1995/12/668965980d69329a7fb080b4ddb031d0896461daba827f64ed231aa5afc08fe1) -<EMAIL_ADDRESS>(Futplex)_


text:
### Prerequisites

- Homebrew
- Git
- GCC/G++:
- Make
- CMake _(for RandomX)_
- autoconf / automake / libtool _(for Minisketch)_
- Rust
- choosenim
- Nim 1.2.12

To install every prerequisite, run:

```
xcode-select --install
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install git cmake autoconf automake libtool
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
curl https://nim-lang.org/choosenim/init.sh -sSf | sh
choosenim 1.2.12
```

You will have to update your path after installing Homebrew, Rust, and choosenim. Their installers will say how to.

### Meros

#### Build

```
git clone https://github.com/MerosCrypto/Meros.git
cd Meros
nimble build
```

> There's also a headless version which doesn't import any GUI files available via adding `-d:nogui` to the build command.

#### Run

```
./build/Meros
```

repository: MerosCrypto/Meros

gha_language: Nim

gha_license_id: NOASSERTION

repo_name: MerosCrypto/Meros


text:
---
layout: leftnav-page-content
title: Discovering Wuhan
permalink: /china/know/china-municipalities-provinces/wuhan-guide/
breadcrumb: Discovering Wuhan
collection_name: china-know-selected
---

This is a selection of resources on Discovering Wuhan available from the [NLB catalogue](http://catalogue.nlb.gov.sg/){:target="_blank"} or the Internet and is not meant to be an exhaustive list. If you know of or come across more useful resources, please drop us a [note](mailto:ref@nlb.gov.sg){:target="_blank"} so that we can share them with our readers.

### **NLB print and digital resources**

[**Physical and socioeconomic driving forces of land-use and land cover changes: A case study of Wuhan city, China**](http://eresources.nlb.gov.sg/Main/Browse?startsWith=E){:target="_blank"}

The authors investigate the connections between land-use and land-cover changes (LULC) and the driving factors for rational urban management. They also use remotely sensed images to map these LULC from 1990 to 2018 using Wuhan city, China, as a case study.

Retrieved from EBSCOhost. *myLibrary ID* is required to access the database.

[**Wuhan makes waves on international social media with “Meet in Wuhan” campaign**](http://eresources.nlb.gov.sg/Main/Browse?startsWith=E){:target="_blank"}

“Meet in Wuhan”, the online campaign launched by the Wuhan Tourism Development Committee, successfully concluded on 25 December 2018. The campaign offered overseas audiences a glimpse into Wuhan’s diverse tourism attractions and cultural heritage through a series of intriguing stories presented with 3D animation techniques, thereby setting an example in marketing a Chinese tourist city to an overseas audience.

Retrieved from EBSCOhost. *myLibrary ID* is required to access the database.

[**Welcome to Wuhan**](http://eresources.nlb.gov.sg/Main/Browse?startsWith=E){:target="_blank"}

The article offers travel tips and recommendations to Wuhan, China, from hotel accommodation such as the Wanda Reign Wuhan to itinerary suggestions such as visiting the East Lake Scenic Park natural site, the Han Show Theatre and the Wanda Movie Park.

Retrieved from EBSCOhost. *myLibrary ID* is required to access the database.

[**Huge turnout for the first FAI – ASFC World Fly-In Expo in Wuhan, China**](http://eresources.nlb.gov.sg/Main/Browse?startsWith=E){:target="_blank"}

The article highlights the 2017 FAI – ASFC World Fly-in Expo in Wuhan, China from 4 — 7 November 2017. The event featured a Guinness World Record attempt involving 100 hot air balloon weddings and mentions the International Paramotor Championships, as well as the International Skydiving Championship at the event.

Retrieved from EBSCOhost. *myLibrary ID* is required to access the database.

---

### **You may also like**

[**Ease of doing business in Wuhan, China**](http://www.doingbusiness.org/en/data/exploreeconomies/china/sub/wuhan){:target="_blank"}

This website outlines the steps one needs to take to start a business in Wuhan and the procedures and estimated time and costs involved.

[**Wuhan: China’s most central city**](https://www.weekinchina.com/wp-content/uploads/2018/10/Sinopolis-Wuhan.pdf){:target="_blank"}

This guide focuses on the city of Wuhan, the capital city of Hubei Province and home to one of the largest university populations in the world. Apart from giving a brief historical outline of the city, it also provides the main statistics and discusses the city’s industry, property, retail and education sectors.

[**Seriously, how cheap is China? Here’s the cost of living in Wuhan, China**](http://www.breakinglabarrier.com/2017/01/10/cost-of-living-in-wuhan-china/){:target="_blank"}

This article provides a guide on the average cost of living in Wuhan. It discusses the prices of items such as groceries, night life, transportation and utilities, as well as average salaries of its citizens.


text:
# Changelog

## v1.3.0 - 2021-05-02

### Added

- Added [tiny-invariant](https://www.npmjs.com/package/tiny-invariant) dependency.

### Changed

- Changed type checking to use `invariant` function from [tiny-invariant](https://www.npmjs.com/package/tiny-invariant).

### Removed

- Removed [use-latest](https://www.npmjs.com/package/use-latest) dependency.

## v1.2.0 - 2020-11-21

### Added

- Added source maps to build output.

### Changed

- Updated [use-latest](https://www.npmjs.com/package/use-latest) dependency to v1.2.0.

## v1.1.0 - 2020-10-25

### Added

- Added type checking of parameters in `useKeypress` hook.

### Changed

- Updated `handler` parameter to allow [nullish values](https://developer.mozilla.org/en-US/docs/Glossary/Nullish).

## v1.0.1 - 2020-07-09

### Added

- Added [use-latest](https://www.npmjs.com/package/use-latest) dependency.

## v1.0.0 - 2020-05-19

Initial public version! :tada: